Qt5.12 + OpenGL 着色器
原教程地址:
https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/
一、 着色器概述
从基本意义上来讲,着色器只是一种把输入转化为输出的程序。它们之间唯一的“通讯”方式只有通过输入和输出来实现。
着色器是使用一种叫GLSL的类 C
语言写成的, GLSL
是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。
1. 输入与输出
顶点着色器中定义一个输出,在片段着色器中定义输入来接收这个输出。
顶点着色器:
out vec4 vertexColor;
// 为片段着色器指定一个颜色输出
片段着色器:
in vec4 vertexColor;
// 从顶点着色器传来的输入变量
(名称相同、类型相同)
就是红色三角形的例子!
2. Uniform 数据发送方式
Uniform 是一种从
CPU 中的应用向
GPU 中的着色器发送数据的方式,但
uniform 和顶点属性有些不同。
首先,
uniform 是全局的
(Global) 。
第二,无论你把
uniform 值设置成什么,
uniform
会一直保存它们的数据,直到它们被重置或更新。
为了实现例程中的效果,我使用了QObject自带的定时器事件,并使用 Qt update()
函数来更新绘图。
程序例子:
//使用uniform的片段着色器 static const char *fragmentShaderSourceUniform = "#version 330 core\n" "out vec4 FragColor;\n" "uniform vec4 ourColor;\n" // 在OpenGL程序代码中设定这个变量 "void main(){\n" " FragColor = ourColor;\n" "}\n\0";
paintGL中更新 Uniform :
#ifdef COLORCHANGE // 更新uniform颜色 float greenValue = sin(m_timeout) / 2.0f + 0.5f; int vertexColorLocation = m_core->glGetUniformLocation(m_shaderProgram, "ourColor"); m_core->glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); #elif MULTICOLOR
#endif
定时器更新计数:
void MyGLWidget::timerEvent(QTimerEvent *e) { Q_UNUSED(e);
if(m_timeout >= 1.0) { m_timeout = -1.0; }
m_timeout = m_timeout + 0.05;
update(); }
效果视频:
三角形颜色渐变:
矩形颜色渐变:
3. 顶点属性传递颜色
GLfloat vertices[] = { // 位置 // 颜色 0.5f, -0.5f, 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 // 顶部 };
m_core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr); m_core->glEnableVertexAttribArray(0); //以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的 m_core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3* sizeof(float))); m_core->glEnableVertexAttribArray(1); //以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的
效果图:
二、 总结
1、 小结
原教程中主要介绍了着色器的语法,改变颜色的三种方式。不同着色器间的输入输出、全局变量Uniform的使用、在顶点属性中设置颜色等。
最后,如需完整工程可在公众号后台留言
学不可以已