GpuProgram在Ogre中是以Resource的形式保存。
GpuProgram部分的头文件涉及如下:
OgreGpuProgram.h
OgreGpuProgramManager.h
OgreGpuProgramParams.h
OgreGpuProgramUsage.h
OgreHighLevelGpuProgram.h
OgreHighLevelGpuProgramManager.h
这些头文件在OgreMain中,由于该部分与RenderSystem有关,Ogre中处理成外部插件的形式,所以外部插件以D3D9,D3D10,D3D11,GL四种类型的GpuProgram与之对应。
由于这部分内容涉及的文件较多,不能逐一分解各个类的成员函数与成员变量,以理清所有类的关系为主。
首先附上GpuProgram与HighLevelGpuProgram部分UML类图。
GpuProgram与HighLevelGpuProgram
GpuProgram直接继承于Ogre::Resource,用来表示低层次Gpu语言。
HighLevelGpuProgram正如注释里所写,是高层次的Gpu语言,如Cg、HLSL和GLSL等,高层语言可以编译成低底层的语言。
这两个class是外部RenderSystem插件的重要基类。两者的子类UML图如下
GpuProgram子类:
HighLevelGpuProgram子类:
这两个基类的主要作用是提供Gpu语言(以文件或者字符的形式)导入、编译与参数管理。
(i)导入、编译操作由保护型虚函数loadFromSource执行。
该函数在GpuProgram中是纯虚函数。
以D3D9GpuPrgoram为例,loadResource做如下操作:
- 调用D3DXAssembleShader对读入的shader字符串进行编译生成一个包含该shader的D3DX buffer
- 再有虚函数loadFromMicrocode根据D3D9GpuPrgoram子类类型(vertex/fragment)创建相应的D3DX buffer(IDirect3DVertexShader9/IDirect3DPixelShader9)
(ii)参数管理部分需要说到GpuProgramParameters,这是一个相对比较复杂的结构。
GpuProgramParameters
图中央的核心类就是GpuProgramParameters,这是一个汇集了所有Gpu参数的类。
大致上Gpu参数可以分为3类:
- 高级语言使用的参数定义类GpuConstantDefinition及其子类
- 低级语言使用的参数定义类GpuLogicalIndexUse及其子类
- 自动绑定的参数类AutoConstantDefinition及其子类(上述两类定义参数属于手动更新)
(1)GpuConstantDefinition
预定义了常量数据类型,物理、逻辑索引,元素和数组长度等,是个基础的常量定义类。
(2)GpuNamedConstants
对GpuConstantDefinitionMap的封装,同时保存了浮点和整型数据所需要的buffer大小。
(3)GpuNamedConstantsSerializer
类如其名,通过遍历GpuConstantDefinitionMap,将GpuConstantDefinition信息进行序列化。
(4)GpuLogicalIndexUse
适用于低级语言的参数定义,包括物理索引,大小等信息。
(5)GpuLogicalBufferStruct
对GpuLogicalIndexUse的一次封装,记录buffer大小。
(6)GpuSharedParameters
一组手动更新的参数集,用于在不同参数集之间进行共享。主要的数据类型是GpuNamedConstants。
(7)GpuSharedParametersUsage
连接GpuProgramParameters与GpuSharedParameters,用来记录shared参数的使用以及参数的相互复制。
(8)AutoConstantType、ACDataType、ElementType
自动绑定参数枚举。
(9)AutoConstantDefinition
自动绑定参数类
(10)AutoConstantEntry
用来记录自动绑定的参数
(11)GpuProgramParameters
核心参数类,在GpuProgram类中用来记录每个program的参数信息。
- 自动绑定的参数定义是一个静态数组成员AutoConstantDefinition[]
- 以物理索引保存两个list:FloatConstantList、IntConstantList,分别对应浮点与整型的常量参数
- 为低级语言保存的GpuLogicalBufferStruct(也分浮点与整型)
- 为高级语言保存的GpuNamedConstantsPtr
- 自动绑定参数列表AutoConstantList
- 大量的成员函数为重载类型以完成设置常量,函数名为setConstant。但在这些函数中最终都是调用了_writeRawConstants函数将参数值写入浮点或者整形缓冲区。在绘制流程中由RenderSystem进行设置。“如果说逻辑索引标志着GPU参数在GPU寄存器中的顺序的话,那么物理索引就指示了GPU参数在缓冲区中的位置。把它们结合起来,就可以让RenderSystem去正确的缓冲区中获取正确的值去调用底层的API。”(此话出自另一个博客,此人应该是位大牛,最后会附上他百度的blog,也是关于这部分代码的解读。)
GpuProgramManager
最后简单提下GpuProgramManager结构
Resource的Manager都是负责创建Resource的。在GpuProgram中也不例外。有些不同的是高级语言中多了HighLevelGpuProgramFactory接口,针对不同的高层语言,HighLevelGpuProgramManager调用相应的Factory来创建Program。看了不少Resource,对Ogre中的ResourceManager与Resource结构应该非常了解了,不再赘述。
最后附上前人的总结http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2/blog/item/4e24e9b78103bbf830add130.html