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

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

上一篇:QOpenGL开发入门系列2:基本图形

上一篇介绍了最基本的图像绘制,但是是黑底白色,本文介绍如何给图像上色。

普通版

先看一下简单版的上色

在顶点之前设置颜色属性就可以了。

1
2
3
4
5
6
7
8
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0,0);
glVertex3f(-0.5,0,0);
glColor3f(0,1.0f,0);
glVertex3f(0,1,0);
glColor3f(0,0,1.0f);
glVertex3f(0.5,0,0);
glEnd();

效果为:

colored

VBO版

三角形

纯色版

先来渲染语言

1
2
3
4
5
6
7
8
9
10
const char* vsrc="#version 330 core\n"
"in vec3 inPos;\n"
"void main(){\n"
" gl_Position=vec4(inPos,1.0);\n"
"}";

const char* fsrc="#version 330 core\n"
"void main(){\n"
" gl_FragColor=vec4(1.0f,0.0f,1.0f,1.0f);\n"
"}";

需要输入一个位置数据,而颜色就直接固定为#ff00ff

在初始化函数中设置

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
program = new QOpenGLShaderProgram;
program->addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program->addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program->bindAttributeLocation("inPos",0);
program->link();//激活Program对象
program->bind();

//3.初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)
vao.create();
vao.bind();

//2.初始化VBO,将顶点数据存储到buffer中,等待VAO激活后才能释放
float vertices[]={
// 位置
0.5f, -0.5f, 0.0f,// 右下
-0.5f, -0.5f, 0.0f,// 左下
0.0f, 0.5f, 0.0f// 顶部
};
vbo.create();
vbo.bind();//绑定到当前的OpenGL上下文
vbo.allocate(vertices,sizeof(vertices)*sizeof(float));
vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);

program->enableAttributeArray(0);
program->enableAttributeArray(1);
program->setAttributeBuffer(0,GL_FLOAT,0,3,3*sizeof (float));

vao.release();
vbo.release();
program->release();

在绘图函数中使用

1
2
3
4
5
program->bind();
vao.bind();
glDrawArrays(GL_TRIANGLES,0,3);
vao.release();
program->release();

效果为:

colored

彩色版

渲染语言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const char* vsrc="#version 330 core\n"
"in vec3 inPos;\n"
"in vec4 inColor;\n"
"out vec4 outColor;\n"
"void main(){\n"
" gl_Position=vec4(inPos,1.0);\n"
" outColor = inColor;\n"
"}";

const char* fsrc="#version 330 core\n"
"in vec4 outColor;\n"
"void main(){\n"
" gl_FragColor=outColor;\n"
"}";

可以看到,相对于上一篇,多了颜色相关的输入输出。我们需要在代码中指定输入颜色inColor,而输出颜色outColor则输出给下一级gl_FragColor,注意数据流向中的变量名要相同。

然后初始化函数中

1
2
3
4
5
6
7
program = new QOpenGLShaderProgram;
program->addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program->addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program->bindAttributeLocation("inPos",0);
program->bindAttributeLocation("inColor",1);
program->link();//激活Program对象
program->bind();

因为有两个输入,所以需要两个顶点位置,那就绑定两个位置。

然后设置位置的顶点数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float vertices[]={
// 位置 // 颜色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下 颜色对应红色(1.0f, 0.0f, 0.0f)
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下 颜色对应绿色
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部 颜色对应蓝色
};

vbo.create();
vbo.bind();
vbo.allocate(vertices,sizeof(vertices)*sizeof (float));

program->enableAttributeArray(0);
program->enableAttributeArray(1);
program->setAttributeBuffer(0,GL_FLOAT,0,3,6*sizeof (float));
program->setAttributeBuffer(1,GL_FLOAT,3*sizeof(float),3,6*sizeof(float));

位置0数据类型为GL_FLOAT,数据在数组的起始位置为0,数量为3,长度为6个float长度,有效值为3个,获取完成后移至6个后的位置,也就是下一行(一行6个数据)。

位置1数据类型为GL_FLOAT,数据在数组的起始位置为3个float大小,数量为3,长度为6,获取后移至下一行。

这样位置0绑定数组左侧的3列,位置1绑定数组右侧3列。

调用代码一样

1
2
3
4
5
program->bind();
vao.bind();
glDrawArrays(GL_TRIANGLES,0,3);
vao.release();
program->release();

效果为:

colored

四边形

普通版

normal

VBO纯色版

same color

VBO彩色版

colorful

和三角形类似,自己去研究一下代码就可以了解了。

多边形

这个代码用的方法和上面的不一样,与OpenGLut的类似,看看茴香豆的茴字到底有几种写法。

源代码地址:OpenGL_Beginner在QOpenGL下的3.1triangle_colored、3.2triangle_vbo_same_color、3.3triangle_vbo_colored、3.4ploygon_colored、3.5polygon_vbo_same_color、3.6polygon_vbo_colored、3.7elements_vbo_translate_colored

下一篇:QOpenGL开发入门系列4:旋转