OpenGL状态机(State Machine)
OpenGL状态机的目前只有1.1版本,也是最经典的,大家可以参考下述链接:
ftp://ftp.sgi.com/opengl/doc/opengl1.1/state.pdf
ftp://ftp.sgi.com/opengl/doc/opengl1.1/state.ps
它们是内容相同而格式不同的状态机表达。整个文件中只有一张Postscript的图。这张图实际上就是SGI RealityEngine的硬件程序流程描述。
首先硬件接受应用程序输入的顶点信息,(Color, Normal, Texture, EdgeFlag, Vertex, ),经过世界坐标变换(glTranslate, glRotate, glScale),接着进 行User Clip Plane,之后进入视图变幻和裁减(Projection Matrix),然后视 口变换(ViewPort),经过Primitive Setup,光栅化处理(Flat或Phong)生成 片断Fragment,下面的对每个依次作纹理贴图计算,纹理混合(Texture Blend), 深度测试(Depth Test),模板测试(Stencil测试),透明测试(Alpha Test), 透明混合(Apha Blend),然后写入颜色缓冲区,深度缓冲区,模板缓冲区。
整个流程如下:
- Application
- Vertex Information (Material , Normal, Textcoord, EdgeFlag, Vertex Position)
- Lighting
- World Matrix Transform
- User Clip Plane Clipping
- Projection Matrix Transform and Clip
- ViewPort
- Primitive Setup ( point, Line, Triangle)
- Rasterization( Flat or Phong ) == > Generate Fragment
- Fragment Texture Addressing () == Texture In Video memory
- Fragment Texture Blend ( blend Diffuse, Specular and Texture of Fragment )
- Depth Test == with Depth Buffer
- Stencil Test == with Stencil Buffer
- Alpha Test == with alpha channel of color buffer
- Alpha Blend == with color buffer
- Fragment write to FrameBuffers
我们可以看到OpenGL每处理一个几何图元,需要经过大量的处理过程。大家应该对这个图的每个步骤地工作相当清晰。这里有几个概念需要说明。
第一个概念是Fragment,片断或者片元。每一个片断对应屏幕上的一个像素点, 它是光栅化(Rasterization)引擎使用FLAT shading或 Phong Shading生成的。 Rasterization引擎产生的片断包含一下信息:
- 屏幕坐标;
- 颜色信息,Diffuse和Specular;
- 深度信息和模板信息;
- 纹理坐标,u,v。
第二个概念是纹理混合(Texture Blend),它是指纹理颜色和片断颜色(Diffuse和Specular)合成的方式。就是指glTexEnv的效果,根据不同的参数决定片断只保留Texel(纹理元)还是使用Texel(纹理元)和片断的颜色做混合。
第三个概念是透明融合Alpha Blend。如果一个片断经过深度测试,模板测试和透明测试,那么它将和缓冲区对应位置的像素作透明融合。
相信大家对OpenGL 状态机有了一定的了解,实际上这也是Direct3D8以前的图形流水线的主要参考模型(graphics processing pipeline)。
如果我们能够在流水线中减少一个操作,我们就能够获得性能的提高,当然前提是我们能够绘制正确的图像。
典型的D3D9硬件体系结构
上面的OpenGL状态机实际上就是SGI的Reality Engine和其他Direct3D7及其一下 版本的图形硬件流水线结构。下面我向大家介绍D3D9的典型硬件体系结构(或者 说Direct3D9的参考模型)。
- Application
- IDirect3DDevice9::DrawIndexedPrimitive
- D3D Driver (Display Driver ) Send Commands to Hardware by AGP
- following is hardware Command Interpreter
- “Fetch” Indexed Primitive data to Vertex Shader Cache (access index buffer and Vertex Buffer)
- “Put“ Cached data to Vertex Shader Input
- Vertex Shader do Transform, Light and Vertex Blend
- Vertex Shader Output Vertices in Screen coordinate Space, Screen Pos, Diffuse, Texture Coord
- User Clip plane
- Guard band clip
- Primitive Setup (Point, Line, Triangle)
- Rasterizaiton(flat or Phong)
- Pixel Shader (Texture addressing and texture blend)
- Depth Test
- Stencil Test
- Alpha Test
- Alpha Blend
- Frame Buffers
我们可以看到D3D9的流水线和OpenGL 1.1的流水线有很大的不同。
- OpenGL的顶点数据是通过调用OpenGL API一个个的送到流水线的几何变换处理单元,立即模式(immediate mode),而D3D9通过 Fetch和Put两步工作,从Vertex Buffer中读出送入Vertex Sahder的Input寄存器;
- OpenGL 1.1的光照计算和几何变换是通过传统的固定流水线(TnL: Transform and Lighting)完成的—fixed function graphics processing(FGP),而D3D9时通过Vertex Shader实现,它比FFGP更为复杂,可以完成更多的功能;
- OpenGL 1.1的Texture mapping和Texture Blend独立的两个步骤,而D3D9是通过Pixel Shader,PS是可编程的(Programmable Graphics Processing)。
D3D8/D3D9的Vertex Shader和Pixel Shader是两个图形体系结构巨大的进步,当然使得图形程序设计更为灵活,也更为困难和复杂。
对于D3D8/D3D9的硬件体系结构,我们的程序优化工作有多了两个内容,优化Vertex Shader和Pixel Shader。
今天我的重点放在传统图形流水线(TnL)的性能优化上。