Gamebryo遍历子结点
for (NiUInt32 i = 0; i < pkNode->GetArrayCount(); ++i)
DoSomething(pkNode->GetAt(i);
for (NiUInt32 i = 0; i < pkNode->GetChildCount(); ++i)
DoSomething(pkNode->GetAt(i);
两段代码,天壤之别,前者正确,后者错误。由于GB在DetachNode时不删除结点而只是置空,被删除结点仍然占据一个位置而被GetAt()访问到,所以后者可能导致遍历不到很多结点。
Gamebryo坐标系
Gamebryo中貌似默认Y轴为上方向,X轴为右方向,Z轴为前方想;而矩阵相乘,貌似谁在前就采取谁的坐标系。
Gamebryo和Unicode
Gamebryo同时提供显示二字节的Unicode字符(UTC-2)和Ascii字符的支持。
UnicodeCharacterSets例子里展示了这种支持。程序可以从NFF文件中获取字体信息生成NiFont对象。NFF文件可以通过NiFontCreator创建。
尽管如此,Gamebryo里的其他字符串,比如文件名,文件路径,对象名称等,仍然是Ascii编码。
而且,通过定义UNICODE或_UNIOCDE宏来定制Gamebryo是不被支持的。
Ni2DBuffer VS NiPixelData
Ni2DBuffer和NiPixelData的区别在于,Ni2DBuffer存储于显存中,而作为Gamebryo里最主要的纹理数据(纹理文件系统大多数都通过这种数据类型操作纹理),NiPixelData存储于内存中。
使用CEGUI
使用CEGUI需要实现其Texture和Renderer两个接口。其中Renderer要实现其addQuad()方法,而Texture要实现其loadFromFile()和loadFromMemory()方法。
CEGUI使用类成员函数作为回调函数的办法
类成员函数作为回调函数一般会声明该成员函数为static,之后采用类似全局函数一样的调用方法来使用;
CEGUI则使用普通的类成员函数作为回调函数。要求传入该类的指针,以及成员函数的指针,之后做类似“类->函数()”这样的调用。而与第一种方法不同的是,后者需要保存一份类成员的指针,由于各个类不尽相同,所以采用一个模板对象用来进行保存。在这里,CEGUI使所有的模板对象首先继承自一个纯虚接口,之后管理器中保存接口指针即可。这样就达到了保存不同模板对象的目的。非常取巧。
CEGUI渲染
CEGUI在每个窗口保存一份待渲染的RenderCache对象,该对象里维护了一份渲染所需的图像列表和文本列表,分别对应窗口的图素和文字。
渲染时,由图像(image)上溯到图像集(imageset)进而得到实体的Texture并通过它调用addQuad完成渲染。
文字在渲染时被转换成一张一张图片,之后按照上述方法进行渲染。由于在解析文字时,CEGUI以换行符'/n'作为换行标志,所以可以看成一块文本其实就是以'/n'为分隔的一排排小张图片渲染而成的。由文本得到图像的方法见font类的getGlyphData()函数。这个过程涉及到从内存创建图片,因此所有希望使用CEGUI字的程序,都需要实现其Texture的loadFromMemory()方法。
Gamebryo Alpha Blending
Gamebryo中带有AlphaProperty的物体会在绘制时将自身像素点与屏幕上对应的像素点按照指定方式进行Alpha混合。
CEGUI Property
CEGUI以字符串作为类属性Property的索引,同时CEGUI通过Property的方式提供一种无差别访问对象属性(get/setProperty)的一种方法。例如,继承自PropertySet的Window中包含有d_windowRender和d_lookNFeel成员,外部要访问这两个成员,一般不通过调用getWindowRender或者getlookNFeel这样的方法;而是通过Window中同时包含的静态成员d_windowRenderProperty和d_lookNFeelProperty,利用其(静态)方法得到/更改对应这两个成员的字符串。这种方法的代价是,字符串作为索引可能在性能方面有所下降。
to be continued...