三角形的颜色,一直在片段着色器中写的,通过程序设置三角形绘制的颜色。
一、向量类定义
3D向量是图形学最基本的数据类型,为了进一步的学习,我们需要定义自己的向量类。下面是它的代码实现:
//三维向量类 template<typename N> class Vector3 { public: typedef N ValueType; public: // 默认构造一个0向量 Vector3(); // 初始化函数 Vector3(N xx, N yy, N zz); // 拷贝构造函数 Vector3(const Vector3& vec); public: N x, y, z; }; template<typename N> Vector3<N>::Vector3() { x = y = z = ValueType(0); } template<typename N> Vector3<N>::Vector3( N xx, N yy, N zz) { x = xx; y = yy; z = zz; } template<typename N> Vector3<N>::Vector3(const Vector3& vec) { x = vec.x; y = vec.y; z = vec.z; }
这个向量类是一个模板类,主要是为了根据不同的精度要求,方便我们定义所需精度的向量类型。这个向量类有x,y和z三个分量,它不仅可以用来表示3D向量,也可以表示3D点,或者RGB颜色等。
二、着色器之间传递数据
(1)顶点着色器源码:
//输入变量 attribute vec4 vPosition;//顶点坐标 attribute vec3 vColor; //顶点颜色 uniform mat4 matModel; //变换矩阵 //输出变量 varying vec3 varColor; //输出的颜色 void main() { varColor = vColor; gl_Position = matModel * vPosition; }
第3行:新增了一个顶点颜色的属性变量,vColor向量的x,y,z分量分别表示RGB三个通道的颜色值。
第7行:定义了一个类型为vec3的输出变量,前面的varying是易变变量的修饰符,表示我们声明了一个易变变量。
第10行:直接输出顶点颜色到varColor变量,没有做任何处理。
(1)片段着色器源码:
//输入变量 varying vec3 varColor; void main() { gl_FragColor = vec4(varColor, 1.0); }
第2行:定义了一个vec3类型的输入变量,表示输入的RGB颜色。它的声明必须和顶点着色器中的声明完全保持一致,表示这个输入来自于顶点着色器的输出。
第6行:将varColor变量转换成vec4类型的变量,赋给内置变量gl_FragColor,作为片段着色器最终输出的颜色。在GLSL中没有默认的3维到4维的转换,因此需要添加一个w分量,进行明确的转换。新增的w分量表示颜色的透明度,1.0表示没有透明度。
易变变量是顶点着色器向片段着色器传递数据使用的。这里的数据传递不是简单的赋值操作。易变变量从顶点着色器输出之后,然后在图元范围内对每个片段进行插值,最后将插值好的数据传递给片段着色器中的易变变量。
三、绘制渐变三角形
使用3D向量类定义三角形的顶点数组和颜色数组,如下:
// 定义三角形的3个顶点坐标 Vector3f vVertices[] = { Vector3f( 0.0f, 0.5f, 0.0f), //第1个点 Vector3f(-0.5f, -0.5f, 0.0f), //第2个点 Vector3f( 0.5f, -0.5f, 0.0f) //第3个点 }; // 定义三角形的3个顶点颜色 Vector3f vColor[] = { Vector3f(1.0f, 0.0f, 0.0f), //第1个顶点的颜色,依次为rgb Vector3f(0.0f, 1.0f, 0.0f), //第2个顶点的颜色 Vector3f(1.0f, 1.0f, 0.0f) //第3个顶点的颜色 };
在窗口类的场景渲染函数中,将三角形的顶点属性数据发送给传递顶点着色器,然后启用对应的顶点索引就可以,代码如下:
// 为顶点属性 指定 顶点数据 GL30::glVertexAttribPointer(m_posLoc, //顶点属性的索引 3, //顶点坐标有x,y,z三个分量 GL30::GL_FLOAT, //顶点坐标的数据类型为float GL_FALSE, //顶点数组为float类型,无需规范化 3*sizeof(float), //顶点之间的跨距为3个float大小 vVertices); //顶点数组的指针 GL30::glVertexAttribPointer(m_clorLoc, //顶点颜色的索引 3, //顶点颜色有r,g,b三个分量 GL30::GL_FLOAT, //顶点颜色的数据类型为float GL_FALSE, //顶点颜色为float类型,无需规范化 3*sizeof(float), //顶点颜色之间的跨距为3个float大小 vColor); //顶点数组的指针 // 启用顶点坐标的顶点索引 GL30::glEnableVertexAttribArray (m_posLoc); // 启用顶点颜色的顶点索引 GL30::glEnableVertexAttribArray (m_clorLoc); // 使用顶点绘制三角形 GL30::glDrawArrays ( GL30::GL_TRIANGLES, 0, 3 );
四、配套代码
源码下载:ColorGradient