现代OpenGL+Qt学习笔记之四:使用Uniform变量实现对模型的旋转

来源:互联网 发布:urp 数据库 编辑:程序博客网 时间:2024/05/21 17:51

现代OpenGL+Qt学习笔记之四:使用Uniform变量实现对模型的旋转

主要内容

  介绍GLSL中的uniform变量基础,并通过uniorm变量实现对模型的旋转操作。本文将对现代OpenGL+Qt学习笔记之三:显示一个彩色三角形中绘制的三角形进行一定角度的旋转。(PS:本文的项目在上一篇笔记项目的基础上进行更改)

GLSL中的unifrom变量

  前面已经介绍过逐点属性变量(per-vertex attribute),在着色器中,逐点属性变量在每一次运行时都是不同的,需要重新赋值,如对于不同的点,其位置值自然是不同的。但在实际的着色程序中,一些变量并不需要在每一次运行着色器时都需要改变其值。如我们常说的模型视图矩阵(model view matrix)和视图矩阵(projection matrix)等,以及后面会介绍的光照等。

  首先不考虑复杂的模型视图矩阵,而是直接在顶点着色器中定义一个uniform类型的旋转矩阵变量RotationMatrix。所使用的顶点着色器basic_uniform.vert如下:

#version 410in vec3 VertexPosition;in vec3 VertexColor;out vec3 Color;uniform mat4 RotationMatrix;void main(){    Color = VertexColor;    gl_Position = RotationMatrix * vec4(VertexPosition,1.0);}

  在main()函数中,顶点的颜色仍然是直接输出的,但位置却是左乘了一个4X4的旋转矩阵,以实现对空间位置的变换。

  对应的片元着色器basic_uniform.frag的代码和现代OpenGL+Qt学习笔记之三:显示一个彩色三角形中的完全相同。

#version 410in vec3 Color;out vec4 FragColor;void main() {    FragColor = vec4(Color, 1.0);}

  着色器写好后,同样添加到项目的资源文件中,备用。

  打开OpenGL部件类的源文件openglwidget.cpp,添加下列头文件:

#include <QMatrix4x4>

  QMatrix4x4类提供了4X4的矩阵的定义,而且是针对常用的模型视图矩阵的操作来实现的,用它可以很方便的实现变换矩阵的平移、旋转等操作。

  接下来,在绘制语句

glDrawArrays(GL_TRIANGLES, 0, 3 );

前,添加下列代码,以实现旋转矩阵的定义、投影、平移和旋转,并将最终的矩阵赋值到GLSL中的RotationMatrix变量上。

    // transform    int w = width();    int h = height();    QMatrix4x4 matrix;    matrix.perspective(45.0f, (GLfloat)w/(GLfloat)h, 0.001f, 100.0f);    matrix.translate(0.0, 0.0, -3.0);    matrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);    program->setUniformValue("RotationMatrix", matrix);

  这里分别调用了QMatrix4x4类的perspective()函数、translate()函数和rotate()函数。其中perspective()是设置视景体,也就是空间的可视范围,具体的介绍可以找别的资源学习一下(如OpenGL Transformation);translate()是实现平移,这里是将物体向z轴负方向平移了3个单位,也就是把物体拿远了(如果不拿远几个单位,是看不到物体的,因为物体是和你的眼睛处在同一个平面了);rotate()就是实现物体的旋转,第一个参数是旋转角度,这里旋转了90度,旋转轴在接下来的3个参数中指定。这里指定的就是z轴正方向。

  接下来的setUniformValue()函数自然就设置着色程序中相应的uniform变量的值了,这里就用刚刚初始化和处理过的matrix赋值着色程序中的RotationMatrix变量,setUniformValue()函数还会经常用到。

  最后,还别忘了修改着色器的源码路径,因为添加了新的资源(旧的可以删了),文件名不一样,路径也得改一下,我的着色器编译代码如下:

    // vertex shader    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);    vshader->compileSourceFile(":/shader/basic_uniform.vert");    // fragment shader    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);    fshader->compileSourceFile(":/shader/basic_uniform.frag");

  编译和运行程序,出来的结果应该如下:
旋转后的三角形
可以看到一个旋转90度后的彩色三角形。而且三角形较之前的三角形要小一些,原因是我们让这个物体(三角形)拿远了3个单位(如果设置成2左右的数值可能就一样大了,但是两种显示用了不同的投影方法,不具有可比性,所以具体设置多少就能一样大了也不好说)。

小结

  本文简单介绍了一下GLSL中的uniform变量的用法,实现了对一个三角形的旋转。但是整体都比较简单,后面会继续利用uniform变量实现更加复杂的图形视图矩阵和投影矩阵变换以及光照功能等。

源码地址:http://download.csdn.net/download/chaojiwudixiaofeixia/9974877

阅读全文
0 0