渲染效果一般由材质、灯光、纹理结合相应的渲染计算得到,现在的GPU都支持可编程渲染管线,用户可通过shader来跟GPU交互,为了提高渲染计算速度以及可扩展性,SPE的效果框架正是基于shader的。如图1所示:
图1:效果框架图
如上图所示,效果框架以cLightManager类,cMaterial类以及cShaderManager类为中心,附带其他一些支持类。下面一一说明。
1、灯光
cLight类包装了灯光的属性,如环境光强度,漫反射强度等等。cLightManager是一个单例类,表示了系统中所有的灯光,里面维护着一个有效的灯光list,另外提供了一些操作该list的方法,另外其提供了一个与shader交互的方法:Apply(),使用该方法可以将所有灯光属性以uniform的形式传递给当前的Shader Program,以进行光照计算。
2、材质及纹理
cTexture是所有纹理类的基类,它定义了纹理类的公共接口,目前有三个子类,分别对应于1D,2D以及Cube纹理。下面把公共接口列出来:
void SetFilterMode(eFilterMode filterMode, eWrapMode wrapMode); void SetAnisFilter(int level); GLuint LoadImageToGL(const std::string &texFile); GLuint GetTextureId(); void Bind();
类中维护着一个texture id,另外可以从外部文件加载纹理(基于DevIL),设置纹理过滤器类型,以及绑定纹理到当前纹理单元。
一个材质除了具有一般的材质属性如对各种光的反射强度之外,还代表着一个特定的效果,一个特定的效果一般又对应着一个特定的shader,当然,不同的shader有一组不一样的shader参数。材质中维护着一个eMaterialEffect枚举成员,指示当前的效果,然后它具有一个ApplyMaterial()函数,它会检查该效果枚举成员,以决定使用什么shader,并将参数以uniform的形式传给相应的shader。
3、shader的管理
每一种效果往往对应于一个特定的shader,随着效果变多,以及各种效果组合,系统中可能会有很多shader,怎么管理和使用这些shader就显得重要了。SPE使用配置文件来向程序添加shader。下面是一个shader配置文件的内容:
#comments #shader configuration file, version 1.0 #by linling([email protected]) begin_shaders #one shader per line geopassstd.vs geopassstd.fs end_shaders begin_programs #one program per line #format: prgname a.vs,b.fs, geopassstd geopassstd.vs,geopassstd.fs end_programs
#开头的表示注释,所有shader的文件名放到begin_shaders和end_shaders中,program的配置放在begin_programs和end_programs之间,每一个program对应着一个名字和shaders,该名字是惟一的,用来标识一个program。
cShaderManager负责管理程序中所有的shader,它也是一个单例类,在程序启动时它会分析shader配置文件,并建造一个Program列表,当某Program需要用到时会对其进行编译链接。它提供外界一些访问接口,可以查询当前的Program,把某个Program设为当前Program等。最后,cProgram类提供了很多对Program设置uinform以及顶点属性的实用方法。程序结束时,cShaderManager会把所有跟shader相关的资源都释放掉。有点晚了~~ 先写到这了。