OpenGL蓝宝书源码学习(十五)第六章——FlatShader.cpp

来源:互联网 发布:博客源码手机 编辑:程序博客网 时间:2024/06/05 08:06

使用统一值的着色器渲染花托图元

// 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 #endifGLFrame             viewFrame;GLFrustum           viewFrustum;GLTriangleBatch     torusBatch;GLMatrixStack       modelViewMatrix;GLMatrixStack       projectionMatrix;GLGeometryTransform transformPipeline;GLuintflatShader;// The Flat shaderGLintlocMVP;// The location of the ModelViewProjection matrix uniformGLint   locColor;// The location of the color value uniform// This function does any needed initialization on the rendering// context. void SetupRC(void){// BackgroundglClearColor(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");}// Cleanupvoid ShutdownRC(void){}// Called to draw scenevoid RenderScene(void){static CStopWatch rotTimer;// Clear the window and the depth bufferglClear(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 zeroif(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 programsint 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 Matrixuniform mat4mvpMatrix;// Incoming per vertexin vec4 vVertex;void main(void)     {     // This is pretty much it, transform the geometry    gl_Position = mvpMatrix * vVertex;    }#version 130// Make geometry soliduniform vec4 vColorValue;// Output fragment colorout vec4 vFragColor;void main(void)   {    vFragColor = vColorValue;   }

源码示例,使用了自定义的顶点和片段着色程序,加载后进行渲染。在源码中获取了着色器程序中的统一值并设置值,是着色器程序与Client应用程序结合应用渲染图形。

一、Client程序部分源码分析

1、全局变量

GLuintflatShader;// 将要返回平面着色器的标识

GLintlocMVP;// 模型视图矩阵统一值的位置坐标
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 mat4mvpMatrix; //模型视图投影矩阵统一值,此值可以在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源码中我们使用了glGetUniformLocationglUniform4fvglUniformMatrix4fv获得着色器的统一值并对其进行设置,在载入着色器时,使用这些设置的统一值进行渲染。

在慢慢学习源码的过程中,应该尝试查看GLtools、glut等封装的底层的源码,可以更好的理解渲染机制。


阅读全文
0 0
原创粉丝点击