如果你还手里有老老版 OpenGL编程指南 ,打开来看一看,在真正开始用 OpenGL绘制图形时,使用的是下面的API:
glBegin(GL_TRIANGLES); // 绘制三角形 glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点 glVertex3f(-1.0f,-1.0f, 0.0f); // 左下 glVertex3f( 1.0f,-1.0f, 0.0f); // 右下 glEnd();
http://blog.csdn.net/huutu
先去洗个脑,扔掉你所学过的那些 固定管线 编程 的OpenGL API,留下你脑袋里面的强大的图形数学知识,让我们进入可编程管线。
上图中虚线是 固定管线,黑色粗实线 是 可编程管线 。
可以看到这里 用了 顶点程序、片元程序字样,就是说,这两个过程是可编程的,要我们自己写代码去控制。
顶点程序就是常说的 顶点 Shader ,后缀一般是vsh , 片元程序 就是常说的 片段Shader,后缀一般是 fsh 。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
好。
我们编写的 Shader 代码是可以运行在GPU上的,既然是作为一段程序,那么和我们平时写的C++代码一样,想要最后运行起来也要经过一个流程。
1、创建一个项目 glCreateProgram
2、创建一个代码文件 glCreateShader
3、输入代码 glShaderSource
4、编译代码 glCompileShader
5、查看编译是否错误 glGetShaderiv
6、把Shader添加到项目中 glAttachShader
7、链接每个Shader glLinkProgram
8、获取链接状态 glGetProgramiv
9、运行这个项目 glUseProgram
下面是一个Shader 的完整例子,包含上面的流程
一对简单的 Vertex Shader 和 Fragment Shader 可能长的像下面
const char* vertexShader= { "precision lowp float;" "uniform mat4 m_mvp;" "attribute vec3 m_position;" "attribute vec4 m_color;" "varying vec4 m_outColor;" "void main()" "{" " vec4 pos=vec4(m_position,1);" " gl_Position=m_mvp*pos;" " m_outColor=m_color;" "}" }; const char* fragmentShader = { "precision lowp float;" "varying vec4 m_outColor;" "void main()" "{" " gl_FragColor=m_outColor;" "}" };
uniform 、attribute 都是变量修饰符。这两个修饰符修饰的变量 ,我们可以在 C++ 代码中获取到然后给他们赋值。
varying 修饰符修饰的变量代表在 Vertex 和 Fragment 之间传递。不能从C++代码中操作。
uniform mat4 m_mvp
我们从C++中传入 MVP 矩阵
attribute vec3 m_position
我们从C++中传入 顶点位置
attribute vec4 m_color
我们从C++中传入 顶点颜色
好了。下面就让我们来设置这些变量。
这里继承了上面的类
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
可以看到,在创建Shader 并且编译成功之后,就可以获取 Shader 中的变量了。
bool ret = createProgram(vertexShader, fragmentShader); if (ret) { m_position = glGetAttribLocation(m_programId, "m_position"); m_color = glGetAttribLocation(m_programId, "m_color"); m_mvp = glGetUniformLocation(m_programId, "m_mvp"); }
glUniformMatrix4fv(m_program.m_mvp, 1, false, &proj[0][0]); glVertexAttribPointer(m_program.m_position, 2, GL_FLOAT, false, sizeof(glm::vec3), pos); glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(glm::vec4), color);
这里说下MVP
MVP是一个矩阵,是由 模型矩阵 乘以 视图矩阵 乘以 投影矩阵 得来的,代表对世界坐标系中的一个点执行的一系列 操作。
想详细了解的请百度相关资料,关键字:OpenGL 矩阵变换
好了,我们在教程一的基础上添加了 一些修改,创建了Shader、给Shader设置了值,并且引入了一个三方库 GLM 来进行矩阵的计算。
示例程序下载:
http://pan.baidu.com/s/1eQjW5O2
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn