好久没写了,并不是没有学习,而是最近在看CEGUI的渲染逻辑,我看得超级慢,看了好多遍都没弄明白,不过今天终于看懂了,今天就简略的写一下,等过一段时间完全理解透彻了,再写一个完成的。
首先要说的是,CEGUI每个控件都用GeometryBuffer对象,这个对象中存着渲染该控件所需的面片数据。CEGUI出于效率的考虑,它的渲染分为两步,第一步是计算每个控件的面片数据,并保存到其GeometryBuffer对象中,然后将所有的面片写到一个容器中,这个容器在内存中,不是在显存中,第二步是将这个容器中的所有面片,传人显存,然后画到屏幕上。比较有意思的第一步使用的函数叫render,而第二步使用的函数叫draw。这样做能提高效率的原因是,当控件的图片没有改变时,就不需要重新计算控件的面片数据,直接将原有的存入内存中的那个容器就可以了。
另外CEGUI还做了一个非常好的优化,它在上面的第一步的时候,将每个对话框的内容画到了一个新创建的纹理上,也就是整个对话框成为了一个面片,而不是由底图面片、已经上面的各种控件的面片组成的面片集了,如果游戏的时候这个对话框上面的图片没有任何变化(例如移到对话框的时候),那就可以一直用这个面片,这就使得渲染的效率有了很大的提升,以前是要渲染对话框的底图面片然后再渲染上面的其他控件的面片,而现在只用渲染一个面片就可以了。
而我之所以看了好久都没看明白,就是上面那个优化没看明白,更具体的说,是我没找到,渲染到纹理和渲染到屏幕是在哪个函数切换的,今天找到了,是RnderingSurface::draw()里面有一句d_target.activate();对于上面所说的优化,此处的d_target是Direct3D9TextureTarget对象,它的activate()调用了enableRenderTexture(),这个函数做了底层的D3D的渲染目标的切换。
上面写的还是太混乱,以后在细化吧,表达能力的提升是很重要的。