天天看點

蔡軍生先生第二人生的源碼分析(五十五)OpenGL的API函數管理

對于高性能的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,這樣比較容易維護,也達到更加容易使用的目的,并且全局隻一個渲染對象。

繼續閱讀