使用统一值的着色器渲染花托图元
// FlatShader.cpp
// OpenGL SuperBible
// Demonstrates a simple flat shader with transformations
// Program by Richard S. Wright Jr.
#include
// OpenGL toolkit
#include
#include
#include
#include
#include
#include
#ifdef __APPLE__ #include
#else #define FREEGLUT_STATIC #include
#endif GLFrame viewFrame; GLFrustum viewFrustum; GLTriangleBatch torusBatch; GLMatrixStack modelViewMatrix; GLMatrixStack projectionMatrix; GLGeometryTransform transformPipeline; GLuint flatShader; // The Flat shader GLint locMVP; // The location of the ModelViewProjection matrix uniform GLint locColor; // The location of the color value uniform // This function does any needed initialization on the rendering // context. void SetupRC(void) { // Background glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); viewFrame.MoveForward(4.0f); // Make the torus gltMakeTorus(torusBatch, .80f, 0.25f, 52, 26); flatShader = gltLoadShaderPairWithAttributes("FlatShader.vp", "FlatShader.fp", 1, GLT_ATTRIBUTE_VERTEX, "vVertex"); locMVP = glGetUniformLocation(flatShader, "mvpMatrix"); locColor = glGetUniformLocation(flatShader, "vColorValue"); } // Cleanup void ShutdownRC(void) { } // Called to draw scene void RenderScene(void) { static CStopWatch rotTimer; // Clear the window and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); modelViewMatrix.PushMatrix(viewFrame); modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f, 0.0f, 1.0f, 0.0f); GLfloat vColor[] = { 0.1f, 0.1f, 1.f, 1.0f }; glUseProgram(flatShader); glUniform4fv(locColor, 1, vColor); glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix()); torusBatch.Draw(); modelViewMatrix.PopMatrix(); glutSwapBuffers(); glutPostRedisplay(); } void ChangeSize(int w, int h) { // Prevent a divide by zero if(h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f); projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); } /// // Main entry point for GLUT based programs int main(int argc, char* argv[]) { gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(800, 600); glutCreateWindow("Simple Transformed Geometry"); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC(); glutMainLoop(); ShutdownRC(); return 0; } #version 130 // Transformation Matrix uniform mat4 mvpMatrix; // Incoming per vertex in vec4 vVertex; void main(void) { // This is pretty much it, transform the geometry gl_Position = mvpMatrix * vVertex; }#version 130 // Make geometry solid uniform vec4 vColorValue; // Output fragment color out vec4 vFragColor; void main(void) { vFragColor = vColorValue; }
源码示例,使用了自定义的顶点和片段着色程序,加载后进行渲染。在源码中获取了着色器程序中的统一值并设置值,是着色器程序与Client应用程序结合应用渲染图形。
一、Client程序部分源码分析
1、全局变量
GLuint flatShader; // 将要返回平面着色器的标识
GLint locMVP; // 模型视图矩阵统一值的位置坐标
GLint locColor; // 颜色向量统一值的位置坐标
2、函数
1)void SetupRC(void)
//加载和初始化着色器。传入顶点和片段程序文件;“1”表示顶点程序中包含属性的个数;最后两个参数表明是一个带有顶点属性的着色器
flatShader = gltLoadShaderPairWithAttributes("FlatShader.vp", "FlatShader.fp", 1, GLT_ATTRIBUTE_VERTEX, "vVertex");
//分别获取着色器程序中的“mvpMatrix”和“vColorValue”统一值,mvpMatrix在顶点程序中,vColorValue在片段程序中
locMVP = glGetUniformLocation(flatShader, "mvpMatrix");
locColor = glGetUniformLocation(flatShader, "vColorValue");
2)void RenderScene(void)
static CStopWatch rotTimer; //声明一个时间对象
modelViewMatrix.PushMatrix(viewFrame);//把角色参考帧堆栈到模型视图矩阵堆栈中
modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f, 0.0f, 1.0f, 0.0f);//模型视图矩阵堆栈的顶部矩阵(角色矩阵)随时间沿y轴进行旋转
GLfloat vColor[] = { 0.1f, 0.1f, 1.f, 1.0f };//要渲染的颜色值(蓝色)
glUseProgram(flatShader);//选择使用自定义设置的着色器
glUniform4fv(locColor, 1, vColor);//设置locColor统一值(回顾SetupRC函数)
//设置locMVP统一矩阵。参数2:代表参数4得到的矩阵个数,即一个模型视图投影矩阵;参数3:矩阵复制到着色器时发生改变(变为列优先矩阵);参数4:赋值统一矩阵所用的矩阵(模型视图投影矩阵)
glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
torusBatch.Draw();//提交图元进行渲染绘制
modelViewMatrix.PopMatrix();//模型视图矩阵堆栈出栈,避免对后面图形渲染的影响
注意:在Client程序源码中,获得着色程序的统一值进行设置,设置值实质上在使着色器进行渲染时,是按照Client设置的统一值进行渲染设置。
二、着色器程序源码解析
FlatShader.vp
1、变量
uniform mat4 mvpMatrix; //模型视图投影矩阵统一值,此值可以在Client程序中获得并进行设置
in vec4 vVertex; //顶点位置属性值(4分量向量)
2、函数
void main(void)
{
// 模型视图投影矩阵与顶点坐标相乘,转换顶点坐标到模型视图投影坐标系中
gl_Position = mvpMatrix * vVertex;
}
FlatShader.fp
1、变量
uniform vec4 vColorValue; //颜色统一值,可以在Client程序中更改后提交到着色器程序(片段)
out vec4 vFragColor; //将要进行光栅化的片段颜色(输出值)
2、函数
void main(void)
{
vFragColor = vColorValue; //将颜色统一值复制给要输出的值
}
三、小结
Client源码解析略去了部分了源码,忘记了可回顾前面学过的知识,在Client源码中我们使用了glGetUniformLocation、glUniform4fv和glUniformMatrix4fv获得着色器的统一值并对其进行设置,在载入着色器时,使用这些设置的统一值进行渲染。
在慢慢学习源码的过程中,应该尝试查看GLtools、glut等封装的底层的源码,可以更好的理解渲染机制。