OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!

如果你还手里有老老版  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,留下你脑袋里面的强大的图形数学知识,让我们进入可编程管线。

OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!_第1张图片


上图中虚线是 固定管线,黑色粗实线 是 可编程管线 。

可以看到这里 用了 顶点程序片元程序字样,就是说,这两个过程是可编程的,要我们自己写代码去控制。

顶点程序就是常说的 顶点 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

OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!_第2张图片


下面是一个Shader 的完整例子,包含上面的流程

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

一对简单的 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



你可能感兴趣的:(OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!)