QOpenGL开发入门系列4:旋转

系列教程索引:Qt开发入门系列教程索引

上一篇:QOpenGL开发入门系列3:多边形上色

在上一篇中,我们绘制了彩色的三角形和四边形。本文将图形旋转起来。

在OpenGLut系列中,旋转是使用glRotatef函数,但是Qt中这个函数无效。

方法一

先用OpenGLut常用的glGenBuffers方法

渲染语言

vertice 顶点

1
2
3
4
5
6
7
8
9
10
#version 330 core

in vec4 aPos;
in vec4 aColor;
out vec4 outColor;
uniform mat4 mvpMatrix;
void main(){
gl_Position = mvpMatrix * aPos;
outColor=aColor;
}

fragment 段

1
2
3
4
5
6
#version 330 core

in vec4 outColor;
void main(){
gl_FragColor = outColor;
}

可以看到段的输入是顶点的输出,也就是说先处理顶点,然后将顶点处理为面。

初始化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
initializeOpenGLFunctions();//初始化OpenGL上下文内容
glClearColor(0.0f,0.0f,0.0f,1.0f);//将缓冲区清空为RGBA指定的颜色
//使用颜色缓冲区、深度缓冲区、RGBA、alpha支持
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_RGBA|GL_ALPHA_BITS);
glEnable(GL_DEPTH_TEST);//使用深度缓冲区测试

program = new QOpenGLShaderProgram;
program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,":/resources/vsrc.glsl");
program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,":/resources/fsrc.glsl");
program->bindAttributeLocation("aPos",0);
program->bindAttributeLocation("aColor",1);
program->link();//激活Program对象
program->bind();

glGenBuffers(4, &m_vboIds[0]);
GLfloat triangleVertices[] = {
0.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 0.0f,
1.0f,-1.0f, 0.0f,
};
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);

GLfloat triangleColors[] = {
1.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,
0.0f,0.0f,1.0f
};
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleColors), triangleColors, GL_STATIC_DRAW);

GLfloat quadVertices[] = {
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f,-1.0f, 0.0f,
-1.0f,-1.0f, 0.0f
};
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);

GLfloat quadColors[] = {
0.5f,0.5f,1.0f,
0.5f,0.5f,1.0f,
0.5f,0.5f,1.0f,
0.5f,0.5f,1.0f
};
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[3]);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadColors), quadColors, GL_STATIC_DRAW);
  • 如果渲染语言太多了,就需要将其移至专用文件中,Qt的这种文件格式为glsl,其实叫什么无所谓,内容对就可以。
  • 顶点语言中有两个输入aPos和aColor,分别绑定到顶点位置0和1。
  • 创建4个缓冲区,用于两个图形的顶点坐标和颜色,如果是图片就需要创建纹理Texture。然后绑定数据
  • GL_STATIC_DRAW表示数据不会修改

绘图函数

先绑定数据

1
2
3
program->bind();
...
program->release();

绘制三角形

1
2
3
4
5
6
7
8
9
10
11
m_modelView.setToIdentity();
m_modelView.translate(-1.5f, 0.0f, -6.0f);
m_modelView.rotate(m_rtri,0.0f,1.0f,0.0f);
program->setUniformValue("mvpMatrix", m_projection * m_modelView);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
program->enableAttributeArray(0);
program->setAttributeBuffer(0, GL_FLOAT, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
program->enableAttributeArray(1);
program->setAttributeBuffer(1, GL_FLOAT, 0, 3);
glDrawArrays(GL_TRIANGLES, 0, 3);

移动和旋转,然后计算新的值,并将新值赋予渲染语言中的变量。

修改旋转角度

1
2
m_rtri+=1.0f;
m_rquad+=1.0f;

效果为:

rotate

可以看到图像边框有很严重的锯齿。

在构造函数中添加

1
2
3
QSurfaceFormat surfaceFmt;
surfaceFmt.setSamples(4);
setFormat(surfaceFmt);

或者在main中添加

1
2
3
QSurfaceFormat surfaceFmt;
surfaceFmt.setSamples(4);
w.setFormat(surfaceFmt);

效果为:

antialiasing

可以看到平滑了许多。

方法二

待补充

完整代码在OpenGL_Beginner中的QOpenGL下的4.rotate。

下一篇:QOpenGL开发入门系列5:立方体