以前学习管线的时候,咱们知道OpenGL的渲染流程是有固定次序的。那么先了解下渲染框架:前端
这里的客户端和服务端都是对OpenGL而言。客户端将数据和渲染指令发送给服务端。c++
顶点着色器(Vertex Shader)
->图元装配(Primitive Assembly)
->片元着色器(Fragment Shader)
->渲染(Render)
。着色器是使用GLSL编写的程序。GLSL看起来与C语言很是相似,实际上GLSL语言的程序甚至是以咱们熟悉的main函数开始的。这些着色器必须从源代码中编译和连接到-起(这一点仍然和C、C++程序很是相似)才能使用。最终准备就绪的着色器程序随后在第一阶段构成顶点着色器,在第二阶段构成片断着色器。请注意,咱们目前讨论的是简化的方式。实际上还有一种几何着色器能够(选择性地)安排在二者之间,就像用来将数据来回传递的全部类型的反馈机制同样。还有一些传递片断的处理特性,诸如混合、模板和深度测试。程序员
顶点着色器处理从客户机输入的数据,应用变换,或者进行其余类型的数学运算来计算光照效果、位移、颜色值,等等。为了渲染一个共有3个顶点的三角形,顶点着色器将执行3次,也就是为每一个顶点执行一次。在目前的硬件上有多个执行单元同时运行,这就意味着全部这3个顶点均可以同时进行处理。今天的图形处理器属于大规模并行计算机。不要将它们和CPU相比而被时钟速度蒙蔽,它们比图形操做要快上几个数量级。编程
如今,3个顶点都作好了光栅化的准备。图元组合( Primitive Assembly )框图意在说明3个顶点已经组合在一块儿,而三角形已经逐个片断地进行了光栅化。每一个片断都经过执行片断着色器而进行了填充,片断着色器会输出咱们将在屏幕上看到的最终颜色值。再强调一次,今天的硬件是大规模并行运算的,同时执行上百个甚至更多的这种片断程序并不困难。后端
在OpenGL核心框架中,并无提供任何内建渲染管线,在提交一个几何图形进行渲染以前, 必须制定一个着色器。咱们可使用的存储着色器。这些存储着色器由GLTools 的C++类GLShaderManager进行管理,它们可以知足进行一般渲染的基本要求。bash
单位( ldentity )着色器
只是简单地使用默认的笛卡尔坐标系(在全部坐标轴上的坐标范围都是1.0~1.0)。全部片断都应用同一种颜色,几何图形为实心和未渲染的。这种着色器只使用一个属性GLT_ATTRIBUTE_VERTEX
。vColor参数包含了要求的颜色。框架
GLShaderManager::UseStockShader (GLT_SHADER_IDENTITY, GLfloat vColor[4]);
复制代码
平面( Flat)着色器
将统一着色器进行了扩展,容许为几何图形变换指定一个4x4变换矩阵。典型状况下这是一种左乘模型视图矩阵和投影矩阵,常常被称做“模型视图投影矩阵”。这种着色器只使用一个属性GLT_ATTRIBUTE__VERTEX
。函数
GLShaderManager::UseStockShader(GLT_SHADER_FLAT, GLfloat mvp[16],GLfloat
vCo1or[4]) ;
复制代码
这种着色器惟一的Uniform 值就是在几何图形中应用的变换矩阵。GLT_ATTRIBUTE_VERTEX
和 GLT_ATTRIBUTE_COLOR
在这种着色器中都会使用。颜色值将被平滑地插入顶点之间(称为平滑着色)。学习
GLShaderManager::UseStockShader(GLT_SHADER_SHADED, GLfloat mvp[16]);
复制代码
这种着色器创造出一种错觉,相似于由位于观察者位置的单漫射光所产生的效果。从本质上讲,这种着色器使对象产生阴影和光照的效果。这里须要模型视图矩阵、投影矩阵和做为基本色的颜色值等Uniform值。所需的属性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。大多数光照着色器都须要正规矩阵( normal matrix )做为Uniform值。测试
GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);
复制代码
点光源着色器和默认光源着色器很类似,可是光源位置多是特定的。这种着色器接受4个Uniform值,即模型视图矩阵、投影矩阵、视点坐标系中的光源位置和对象的基本漫反射颜色。所需的属性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。
GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);
复制代码
着色器经过给定的模型视图投影矩阵,使用绑定到nTextureUnit
指定的纹理单元的纹理对几何图形进行变换。片断颜色是直接从纹理样本中直接获取的。所需的属性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfloat mvpMatrix[16], GLint nTextureUnit);
复制代码
这种着色器将一个基本色乘以一个取自纹理单元nTextureUnit 的纹理。所需的属性有 GLT_ATTRIBUTE_VERTEX
和GLT_AT TRIBUTE_TEXTUREO
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfloat mvpMatrix[16], GLfloat vColor, GLint nTextureUnit);
复制代码
这种着色器将一个纹理经过漫反射照明计算进行调整(相乘),光线在视觉空间中的位置是给定的。这种着色器接受5个Uniform值,即模型视图矩阵、投影矩阵、视觉空间中的光源位置、几何图形的基本色和将要使用的纹理单元。所需的属性有GLT_ATTRIBUTE_VERTEX
、GLT_ATTRIBUTE_NORMAL
和GLT_ATTRIBUTE_TEXTUREO
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfloat pMatrix[16], GLfloat vLightPos[3],
GLfloat vBaseColor[4],GLint nTextureUnit);
复制代码
固然咱们必须首先为这些着色器提供数据,不然什么也作不成。有3种向OpenGL着色器传递渲染数据方法可供程序员选择,即属性、uniform值和纹理。