openGL管线各环节细节
固定编程管线图:
被着色器替代的部分:
↓
↓
一、内存开始
1、一次一个顶点: glBegin 顶点 法线 颜色 纹理 ... glEnd
2、顶点数组:glDrayArrays
3、显示列表:glNewList glEndList
4、缓存区对象:glBufferData
↓
↓
二、各顶点操作
1、各顶点会通过模型矩阵和投影矩阵来转换。
2、法线会通过从模型矩阵获得的左上角的3x3矩阵的逆变换来转换。
3、纹理坐标会通过纹理矩阵来转换。
4、光照算法会得到应用以修改基色。
5、可能会自动生成纹理坐标、应用颜色材质状态以及计算点的大小。 这个阶段最主要的操作是转换与光照。
↓
↓
三、图元组装
这个阶段顶点会合成完成的图元。将图元传递到下一个阶段。
↓
↓
四、图元处理
1、裁剪
2、透视投影(视口变换以生成窗口坐标)。
3、消隐culling操作,如背面剔除。
↓
↓
五、栅格化
1、图元将被分解成更小的单元,这些单元对应目标帧缓存区中的像素(片元)。
2、走样化处理,使图元消除锯齿变的更加平滑。
↓
↓
六、片元处理
1、上纹理。会访问纹理内存。
2、雾化。根据片元距离当前视点的位置修改其颜色。
3、颜色汇总。将片元的主颜色与次(第二)颜色的值整合在一起。
↓
↓
七、逐个片元的操作
1、像素所有权测试。确定目标像素是可见的还是被一个重叠的窗口盖住呢。
2、剪切测试。根据通过调用glScissor建立的一个矩形区域来裁剪片元。
3、Alpha测试。根据片元的Alpha值和通过调用glAlphaFunc建立的函数来确定是否丢弃片元。
4、混合。根据片元的颜色以及存储在帧缓存区的颜色通过混合状态(由glBlendFunc、glBlendColor 和glBlendEquation设置)来确定要写入帧缓存区的的颜色。
5、抖动。允许一种只有少量离散颜色的显示系统模拟出更宽的颜色范围。可以大幅度改善低端颜色系 统的显示效果。默认是打开的,会影响性能。可以glDisable(GL_DITHER)关闭。
6、逻辑操作。使用通过glLogicOp建立的逻辑操作将最终的片元值与帧缓存区中的值结合起来。
↓
↓
八、帧缓存区操作
1、glDrawBuffer指定之后渲染操作的目标。openGL支持显示立体图像以及双重缓存区,因此对于渲染的目标有多个选择。
帧缓存区的各个区域被称为缓存区buffers,分别为前、后、左、右、前左、前右、后左、后右以及前后。
2、glColorMask。该函数决定是否允许对目标缓存区的颜色分值R、G、B和A部分执行写入操作。
3、glDepthMask。决定是否可以修改目标缓存区的深度部分。
4、glStencilMask。控制了对目标缓存区的模板部分中的特定为的写入操作。
5、glAccum。指定积聚缓存区操作。
6、glClear。初始化帧缓存区的值。分别调用glClearColor、glClearDepth、glClearStencil和glClearAccum设置来初始 化颜色部分、深度部分、模板部分和积聚缓存区的值。
7、glFlush。 为了确保一个特定渲染环境的全部图元是逐渐完成的。
8、glFinish。为了确保一个特定渲染环境的全部图元是完成了渲染。这个命令会一直阻塞到之前所有的命令的效果已全部 完成为止。就性能而言,这样做的代价是昂贵的,需谨慎使用。
↓
↓
九、绘制图像
1、glDrawPixels。将图像数据渲染到帧缓存区。
2、glBitmap。将位图渲染到帧缓存区中。
3、glTexImage、glTexSubImage。将图像渲染到纹理内存中。
4、像素解码。glPixelStore指定那些定义了如何在内存中存储图像数据的参数。从应用程序内存中读取的像素通过像素解码后转换成一个连贯的像素流。
通过glDrawPixel这样的调用将图像传输到openGl时,这个操作会应用当前的一组像素解码参数来确定如何读取和解析像素图像。
从内存中读取各个像素时,像素会被转换为一个其中包含了颜色、深度和模板值的像素组。
5、像素传输。无论何时将图像从应用程序传输到OpenGL(glDrawPixels、glBitmap、glTexImage、glTexSubImage),或者从OpenGL传回应用程序(glReadPixels),
或者从OpenGL内部使用它们(glCopyPixels、glCopyTexImage、glCopyTexSubImage),都会应用像素传输。
glPixelTransfer。修改传输阶段的行为。
6、栅格化和后端处理。通过栅格化像素矩形(图像)的过程来生成片元。
glRasterPos、glWindowPos。指定当前的光栅位置。
glPixelZoom。当前的缩放因子。
之后又回到上图中的(6,7,8,9)步骤。
↓
↓
十、坐标转换
1、模型变换矩阵(MODEL TRANSFORMATION MATRIX)。它表示从对象坐标系到世界坐标系的转换。为了把对象放到世界坐标系中的正确位置,通常需要这样一次模型矩阵变化。
2、视图矩阵(VIEWING MATRIX)。从世界坐标系转换到相机坐标系。在构成了场景之后,需要指定视图参数。其一就是确定相机的位置。经过模型变换矩阵转换后,将其与该矩阵相乘。之后其坐标就会从世界
坐标系转换到相机坐标系。相机的位置被定义为坐标原点。要注意的是OpenGL将这两个矩阵合二为一,称为模型视图矩阵(MODELVIEW MATRIX),它用来从对象坐标系到相机坐标系的转换。
3、glMatrixModel:指定当前操作的矩阵、glLoadIdentity:重置当前矩阵到原点、glLoadMatrix:替换当前矩阵、glMultiMatirx:乘以当前矩阵、glPushMatrix:将当前矩阵入栈,glPopMatrix:出栈。
4、glLight指定光源时,OpenGL默认会使用模型视图矩阵进行转换,让其用相机坐标系中表示。因此在指定光源位置之前,必须先设置好模型视图矩阵。
5、法线到相机坐标系的转换。因为光照计算是发生在相机坐标系中,因此需要将表面法线也要转化到相机坐标系中来。这个过程可以通过模型视图矩阵的逆转置矩阵来完成。
6、投影转换。将坐标转换到相机坐标空间之后,要做的下一件事就是定义一个视景。这是三维场景中可以在最终图像中看到的那个区域。glMatrixModel(GL_PROJECTION)设置当前矩阵为投影矩阵,
glOrtho(正视投影)、glFrustum(透视投影)和gluPerspective(更直观的透视投影)。