我们为什么要用RTSS.
Ogre如计算物体位置,纹理,光照都有固定API如(glMatrixFrustumEXT, glLoadmatrix, glTexture, glLight ),使用这些API渲染称之为固定渲染管线,而最新的如D3D11,OpenGL3.0+都在淘汰固定渲染管线功能了,对应的都全力支持可编程管线,用shader实现各个方面的功能.二者详细的区别大家可以google.而Ogre之前默认采用固定渲染管线,对应的D3D9,而Ogre2.0+版本对应的DirectX是D3D11,这个版本已经完全放弃了固定渲染管线的实现,OpenGL因为扩展集的存在,OpenGL3+也还是可以使用固定渲染管线,但是官方的API对应的固定渲染API已经越来越少了,而在移动设备上使用的OpenGL ES2.0同D3D11一样完全不支持固定渲染管线,所以使用固定渲染管线已经不是一个明智的选择.
主要实现如下功能:
1.模拟固定管线功能,对于D3D10+,OpenGL ES2.0就能不写着色器代码而使用对应的固定管线功能(顶点转换,模型颜色,灯光,纹理,Alpha混合,雾等).
2.可定制组合各个功能,定义好相关的功能,可以根据当前条件,选择是否需要相应功能.
3.易维护,自成生成管理代替每个材质管理材料和程序.
RTSS类介绍.
模拟着色器程序
简单来说,下面这些类演示如何模拟着色器程序,我们编写一个程序,程序由入口函数和调用函数构成,其中每个函数在前面包含参数,内部包含针对参数和局部变量的各个操作.
ProgramSet:包含二个模拟着色器程序,一个顶点,一个片断.还包含这二个Program生成对应的GpuProgram,其中GpuProgram就是我们对应的着色器资源(请看前文Ogre GpuProgram分析),插入到Pass中使用.
Program:在这我们称模拟着色器程序,能转化成GpuProgram,在这主要封装头文件名与函数列表与参数列表,注意这里的参数是在下面的Function外部,针对这整个Program相当于全局函数,同时这些参数要求GPU自动封装的(自动根据场景填值),请看下面的UniformParameter.
Function:模拟一个函数,包含输入,输出,局部变量,内部包含针对这些参数的原子操作,如赋值,加减乘除,请看下面FunctionInvocation.
Parameter:模拟参数,主要有Semantic, Content二个主要类型参数, Semantic指明参数语义,如顶点,法线点,非Unknown的Semantic参数一般用做入口函数的参数, 反之Unknown的参数一般用做局部变量.而Content指定语义里的具体内部,如顶点分别有坐标空间,世界空间,视图空间,投影空间.最后GpuConstantType上文链接有说过,指明当前参数float,float2,mat4等类型的.
UniformParameter: Parameter的子类,包装的由GPU自动管理的参数,如MVP矩阵,一些场景参数如雾,灯光等,用户也可以自定义,但需自己在相应位置更新(具体请看下面SubRenderState),需要注意的是,纹理参数也是用这个包装,会与别的自动管理参数有些区别,后面例说.这类参数直接由Program持有,不由Function持有,后面会绑定到对应的GpuProgram的GpuProgramParameters上.
ConstParameter: Parameter的泛型子类,一般会做声明局部变量并初始化值.
FunctionAtom:模拟函数内部的每个原子函数,指明每个原子函数的顺序(分组,组顺序,组内部顺序).抽象类.
FunctionInvocation: FunctionAtom的子类,具体用来指明每个子函数,小时小到时前所面所说的赋值,加减乘除,点乘,叉乘. 大时大到一些算法如点光,方向光,平行光算法,或者是骨骼动画算法.
Operand: FunctionInvocation是每子操作,操作的是参数,Operand就是包装的参数,用于FunctionInvocation中,指定参数是传入,传出,传入传出,以及参数的使用位,如使用xy,xz,xyz,xyzw等.
整个过程差不多如下,在RTSS中,定义了一些常用的FunctionInvocation,我们要做的是生成Program,根据函数目的先想出要用的UniformParameter(场景参数或模型参数),添加头文件,然后生成入口Function,生成要用的Parameter(这里一般是顶点参数),把对应的Parameter包装成Operand给相应的FunctionInvocation使用,最后Function根据顺序排序,生成GpuProgram.
我们来看下如下代码,加深理解,首先是RTSS文件中,我所说的一些常用的FunctionInvocation的定义.
void FFP_Transform(in float3x3 m, in float3 v, out float3 vOut) { vOut = mul(m, v); } //----------------------------------------------------------------------------- void FFP_Transform(in float4x4 m, in float4 v, out float4 vOut) { vOut = mul(m, v); } //----------------------------------------------------------------------------- #ifndef OPENGL_ES_2 //----------------------------------------------------------------------------- void FFP_Transform(in float3x4 m, in float4 v, out float3 vOut) { vOut = mul(m, v); } //----------------------------------------------------------------------------- void FFP_Transform(in float3x4 m, in float3 v, out float3 vOut) { vOut = mul((float3x3)m, v); } //----------------------------------------------------------------------------- #endif //----------------------------------------------------------------------------- void FFP_Transform(in float4x4 m, in float3 v, out float3 vOut) { vOut = mul((float3x3)m, v); }