这里只解析之前未学习过的知识点,如果对源码理解起来吃力,可以回顾上一篇文章的基础知识。http://blog.csdn.net/perseverancep/article/details/72885104,在文章后面解析着色器的源码。
GLint myIdentityShader; //加载着色器函数(gltLoadShaderPairWithAttributes)的返回值声明
// 三角形的顶点坐标
GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f };
//三组渲染颜色(RGBA)按顺序是红绿蓝
GLfloat vColors [] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f };
//设置图元批次
triangleBatch.Begin(GL_TRIANGLES, 3); //开始进行图元的批次设置,有3个顶点 triangleBatch.CopyVertexData3f(vVerts); //把顶点坐标拷贝给图元批次 triangleBatch.CopyColorData4f(vColors);//把要渲染的颜色拷贝给图元批次 triangleBatch.End();//结束图元批次的设置
//加载和初始化着色器。传入顶点和片段程序文件(文章后面解析);“2”是顶点程序中包含属性的个数;表明是一个带有顶点和颜色属性的着色器
myIdentityShader = gltLoadShaderPairWithAttributes("ShadedIdentity.vp", "ShadedIdentity.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_COLOR, "vColor");
glDeleteProgram(myIdentityShader);//当不在使用着色器时,需要使用此函数进行删除。
glUseProgram(myIdentityShader); //使用此函数选定使用的着色器
triangleBatch.Draw();//选定着色器后把图元批次提交,进行渲染绘制。
客户端的应用程序的代码解析也是这么多,很简单。下面解析服务端的着色器应用的源码。(回顾上一篇文章的基本着色器架构图)。
ShadedIdentity.vp:
#version 130 in vec4 vColor; in vec4 vVertex; out vec4 vVaryingColor; void main(void) { vVaryingColor = vColor; gl_Position = vVertex; } ShadedIdentity.fp #version 130 out vec4 vFragColor; in vec4 vVaryingColor; void main(void) { vFragColor = vVaryingColor; }#version 130 //指明着色器要求的OpenGL着色语言的最低版本为3.3
in vec4 vColor;//顶点颜色属性值(4分量的向量)(输入值) in vec4 vVertex;//顶点位置属性值(4分量的向量)(输入值) out vec4 vVaryingColor;//将被传递到片段着色器的颜色值(声明输出) void main(void) { //给要输出的颜色赋值 vVaryingColor = vColor; //gl_Position是一个预定义的内建4分量向量,它包含顶点着色器要求的一个输出。 //注意:输入gl_Position的值是几何图形阶段用来装配图元的。既然我们没有进行任何附加的变换,顶点将只映射到所有3个坐标范围都在+/-1.0之间的笛卡尔坐标上。 gl_Position = vVertex;
}
}
到这里通过源码简单的学习理解了一下,基本着色器架构。通过编写顶点和片段程序,在应用中加载这两个着色器程序文件,使用自己定义的着色器渲染和绘制图元。后面继续学习理解着色器程序的统一值寻找和设定的知识。
还有一点要注意:
三角形的颜色为什么是3种颜色过渡的效果,带着这个问题回看一下源码并且回顾一下上一篇文章的对应蓝宝书6.1.3节(p169-p171)“声明输出”部分,
在客户端的程序中,设定了要渲染的颜色值,即三种颜色值的分量,分别是红、绿和蓝。
GLfloat vColors [] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f };
....
triangleBatch.CopyColorData4f(vColors);//把要渲染的颜色拷贝给图元批次
在服务端片段程序中
in vec4 vVaryingColor;
vVaryingColor变量将成为将要传送到片段着色器的顶点的颜色值。默认情况下,变量的声明方式如下:
smooth out vec4 vVaryingColor;
这代表了这个颜色参数将在两个着色器阶段之间以一种透视正确的方法进行补值,这是默认设置(即为声明smooth时,默认的形式)。所以在颜色赋值进行渲染时,实际上是三种颜色之间进行插值,所以测试图形的三角形的颜色是3中图形的过渡效果。
当声明成为flat out vec4 vVaryingColor时,flat关键词代表不进行插值,那么图形就是完全的蓝色。即使用了vColors最后一个分量(蓝色向量)。
关键词可以回顾一下:http://blog.csdn.net/perseverancep/article/details/72885104
最有一点有趣的是我自己做的测试:
在顶点程序中做如下声明:
flat in vec4 vVertex
也就是在in vec4 vVertex前面加上了flat关键词,三角形的颜色变成了白色,同学可以自己理解一下了。
扩展:
上面所注意的是当使用flat限定符修饰时,不进行插值,默认约定是使用为图元的最后一个向量值的值,即为蓝颜色。我们可以使用
Provoking Vertex约定:void glProvokingVertex(GLenum provokMode)
provokMode的合法值为GL_FIRST_VERTEX_CONVENTION和GL_LAST_VERTEX_CONVENTIONS(默认值)
我们在项目中添加如下代码
void KeyPressFunc(unsigned char key, int x, int y) { if(key == 32) { nToggle++; if(nToggle %2 == 0) { glProvokingVertex(GL_LAST_VERTEX_CONVENTION); glutSetWindowTitle("Provoking Vertex - Last Vertex - Press Space Bars"); } else { glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); glutSetWindowTitle("Provoking Vertex - First Vertex - Press Space Bars"); } glutPostRedisplay(); } }当按下空格键可以切换这个约定,而三角形则在实心蓝色和实心红色之间来回切换。