對于高性能的3D遊戲顯示,目前在世界上流行的就兩套API,一套是OpenGL,一套是微軟的D3D。由于OpenGL跨平台的特性,對于第二人生來說,是沒有别的選擇了。那麼在第二人生裡渲染管道到底是怎麼樣調用OpenGL函數的呢?又有什麼特别的方式可以讓調用OpenGL更加友善呢?由于OpenGL并不是基于C++的接口,是以在第二人生裡就肯定先把這些API組織成類的方式,才會更友善使用。下面就來仔細地分析類LLGLImmediate,它的聲明如下: #001 #002 class LLGLImmediate #003 { #004 public: #005 LLGLImmediate(); #006 下面函數通過目前矩陣乘以參數構造的平移矩陣實作平移功能。 #007 void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); 下面函數把目前矩陣壓入到棧裡,避免目前的操作對目前的矩陣下一次使用有影響。 #008 void pushMatrix(); 下面函數把棧頂裡的矩陣取出來,恢複前面儲存的矩陣。 #009 void popMatrix(); 下面函數指明像素混合的方式。 #010 void blendFunc(GLenum sfactor, GLenum dfactor); 下面函數指明一幀圖檔渲染開始。 #011 void start(); 下面函數指明一幀圖檔渲染結束。 #012 void stop(); 下面函數指明OPENGL一幀圖檔渲染生效。 #013 void flush(); #014 下面兩個函數指明OPENGL一幀圖檔渲染開始和結束。 #015 void begin(const GLuint& mode); #016 void end(); 下面的函數都是指明頂點。 #017 void vertex2i(const GLint& x, const GLint& y); #018 void vertex2f(const GLfloat& x, const GLfloat& y); #019 void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z); #020 void vertex2fv(const GLfloat* v); #021 void vertex3fv(const GLfloat* v); #022 下面的函數指明紋理坐标位置。 #023 void texCoord2i(const GLint& x, const GLint& y); #024 void texCoord2f(const GLfloat& x, const GLfloat& y); #025 void texCoord2fv(const GLfloat* tc); #026 下面的函數都是指明目前頂點的顔色。 #027 void color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a); #028 void color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a); #029 void color4fv(const GLfloat* c); #030 void color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b); #031 void color3fv(const GLfloat* c); #032 void color4ubv(const GLubyte* c); #033 #034 // switch clever mode GL immediate rendering on or off. Setting to true builds #035 // client arrays manually, setting to false passes through the GL immediate mode #036 // commands to the GL implementation. Controllable by the RenderUseCleverUI #037 // debug setting. #038 // *NOTE: I have measured that this has about a 9% performance cost (0.6ms) for the #039 // Render/UI fasttimer vs the old #if CLEVER compile time switch. Dave Parks and I #040 // agreed that this was acceptable at the time due to it enabling better regression #041 // testing for QA. #042 // -Brad 下面指明是否使用頂點緩沖區來優化對API的操作,主要減少對API的操作,這樣可以提高速度。 #043 void setClever(bool do_clever); #044 #045 typedef struct Vertex #046 { #047 GLfloat v[3]; #048 GLubyte c[4]; #049 GLfloat uv[2]; #050 }; #051 #052 private: #053 static bool sClever; #054 #055 U32 mCount; #056 U32 mMode; 自己定義的頂點緩沖區,以便儲存資料,最後一次性裡設定到OPENGL裡。 #057 Vertex mBuffer[4096]; #058 }; 通過上面的函數,學會了怎麼樣封裝OPENGL的API函數,并且提出了使用緩沖區的方法來提高渲染速度。在第二人生渲染管道裡會不斷地調用這個類的函數來操作OPENGL,這樣比較容易維護,也達到更加容易使用的目的,并且全局隻一個渲染對象。