非典型2D遊戲引擎 Orx 源碼閱讀筆記 完結篇(7) 渲染流程

來源:互聯網
上載者:User

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞群組及檔案

   本文應該是該系列的最後一篇,看看一個物體在Orx中從載入到顯示的完整流程。

   在Orx,渲染部分,一直與object糾纏在一起,一般不直接由外部使用。最主要的函數是2個:

orxDisplay_LoadBitmap

orxDisplay_BlitBitmap

假如還需要加一個,那就是

orxDisplay_ClearBitmap

事實是向作者討教過顯示一個位元影像最快的方式,大概是下面這個樣子的:

void
 GameApp::Update(const
 orxCLOCK_INFO *_pstClockInfo, void
 *_pstContext) {

    //m_states.top()->Update(_pstClockInfo->fDT);

  orxDisplay_ClearBitmap(orxDisplay_GetScreenBitmap(), orx2RGBA(0
, 0
, 0
, 0
));

  orxDisplay_BlitBitmap(orxDisplay_GetScreenBitmap(), spstBitmap, 100.0f
, 000.0f
, orxDISPLAY_BLEND_MODE_ALPHA);

}

orxSTATUS GameApp::Init() {

  spstBitmap = orxDisplay_LoadBitmap("Dragon.png"
);

  //orxDisplay_SetDestinationBitmap(orxDisplay_GetScreenBitmap());

  orxCLOCK *pstClock = orxClock_Create(orx2F(0.05f
), orxCLOCK_TYPE_USER);

  

  /*
 Registers our update callback
*/

  orxClock_Register(pstClock, sUpdate, orxNULL, orxMODULE_ID_MAIN, orxCLOCK_PRIORITY_NORMAL);

  return
 orxSTATUS_SUCCESS;

}

也就是說,事實上也可以在Orx不通過配置,直接通過API,調用上面的3個函數完成圖形的繪製。

 

orxDisplay_LoadBitmap

圖形資訊載入後儲存的結構是:
/*
* Internal bitmap structure

 */

struct
 __orxBITMAP_t

{

  GLuint                    uiTexture;

  orxBOOL                   bSmoothing;

  orxFLOAT                  fWidth, fHeight;

  orxU32                    u32RealWidth, u32RealHeight, u32Depth;

  orxFLOAT                  fRecRealWidth, fRecRealHeight;

  orxCOLOR                  stColor;

  orxAABOX                  stClip;

};

在圖形的載入過程中,在Orx中使用了SOIL這個外部的庫,用於支援多種圖形格式,而又可以不直接與jpeg和png的那一堆解壓庫打交道,說實話,就我使用那些庫的感覺來說,為了通用及功能強大,API還是太複雜了一些,而且文檔並不詳細,而是用SOIL,Orx僅僅用

  /* Loads image */

  pu8ImageData = SOIL_load_image(_zFilename, (int *)&uiWidth, (int *)&uiHeight, (int *)&uiBytesPerPixel, SOIL_LOAD_RGBA);

這麼一句,就支援了多種圖形檔案。

在orxDisplay_LoadBitmap的函數調用中,對圖形的寬和高還是進行了修正,代碼如下:

      /* Gets its real size */

      uiRealWidth   = orxMath_GetNextPowerOfTwo(uiWidth);

      uiRealHeight  = orxMath_GetNextPowerOfTwo(uiHeight);

使得寬高都位置在2的冪上,以支援更多的顯卡。

 

然後儲存好圖形的相關資訊,手工調用OpenGL進行紋理綁定:

      /*
 Creates new texture
*/

      glGenTextures(1
, &pstResult->uiTexture);

      glASSERT();

      glBindTexture(GL_TEXTURE_2D, pstResult->uiTexture);

      glASSERT();

      glTexImage2D(GL_TEXTURE_2D, 0
, GL_RGBA, pstResult->u32RealWidth, pstResult->u32RealHeight, 0
, GL_RGBA, GL_UNSIGNED_BYTE, pu8ImageBuffer);

      glASSERT();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

      glASSERT();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

      glASSERT();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (pstResult->bSmoothing != orxFALSE) ? GL_LINEAR : GL_NEAREST);

      glASSERT();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (pstResult->bSmoothing != orxFALSE) ? GL_LINEAR : GL_NEAREST);

      glASSERT();

用下面的語句刪除臨時載入的資源:

    /* Deletes surface */

    SOIL_free_image_data(pu8ImageData);

 

最後圖形的相關資訊,包括通過OpenGL載入的紋理的控制代碼,都儲存__orxBITMAP_t
結構中。

 

orxDisplay_ClearBitmap

主要就是如下幾句:

    /*
 Clears the color buffer with given color
*/

    glClearColor((1.0f
 / 255.f
) * orxU2F(orxRGBA_R(_stColor)), (1.0f
 / 255.f
) * orxU2F(orxRGBA_G(_stColor)), (1.0f
 / 255.f
) * orxU2F(orxRGBA_B(_stColor)), (1.0f
 / 255.f
) * orxU2F(orxRGBA_A(_stColor)));

    glASSERT();

    glClear(GL_COLOR_BUFFER_BIT);

 

只要瞭解OpenGL,這個沒有什麼好說的。

 

 

orxDisplay_BlitBitmap

    此函數是渲染流程中最主要的函數,其中又調用了如下函數完成繪製:

orxDisplay_GLFW_DrawBitmap(_pstSrc, _eSmoothing, _eBlendMode);

 

 

orxDisplay_GLFW_DrawBitmap

orxDisplay_GLFW_DrawBitmap分兩部分:

1。用orxDisplay_GLFW_PrepareBitmap指定當前的紋理,及通過當前渲染的配置,調整OpenGL渲染狀態,比如是否消除鋸齒,是否應用定點色等。

2。實際進行紋理的映射,然後最終調用

/* Draws arrays */

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

完成圖形的繪製。

全系列小結

    到這裡,全部的Orx原始碼閱讀就結束了。Orx算是一個相對較小,實現遊戲相關概念不多,但是相對完整,並且有特色的的一個遊戲引擎了。完整的看下來,會發現,在2D遊戲引擎中,其實渲染的這一部分代碼非常少,基本上也就是一個OpenGL使用紋理映射顯示位元影像的翻版,(可參考這裡
)主要的部分在於整個遊戲引擎的組織。這一點上,作為完全使用C語言完成的Orx來說,代碼的組織上還是非常有可借鑒之處的。每個單獨的模組都是用幾個關鍵的結構,構成一個局部的(單檔案中)全域結構實現,然後僅對外開放必要的介面,基本上能做到僅僅看到結構,就能瞭解整個模組的大概實現,看起來非常的清晰。在部分模組的實現中,也借鑒的物件導向的實現方式,實現了可配置的簡單的update及init,setup等操作。這些都是引擎中的亮點。

    假如說Orx有什麼缺點的話,通過通讀代碼,我最大的感覺就是因為其實現的大量可配置的特點,給引擎帶來的太多額外的負擔,比如update,init,setup等模組的實現,幾乎都是從這個目的出發的,是引擎變得複雜了很多,而且,因為這個關係,引擎內部之間的模組設計,從實體設計上來看,太多的交錯,離正交太遠。

    這些可能是從一開始作者對Orx的資料驅動的理念是相關的,在作者看來,外部使用者甚至就不應該直接使用其更多的API,而是直接僅僅使用配置。而從我個人的感覺,已經在推廣Orx的過程中一些中國使用者的反饋來看,在沒有合適編輯的情況下,config的配置負擔在Orx比編寫和修改代碼的負擔要重更多,而且總體結合起來的易用性及開發的速度上面並不比一個不需要配置驅動但是API設計合理的傳統2D引擎要強。而且,在使用上並沒有獲得更好的易用性,在實現上由於一開始的理念存在,也使得實現更加複雜。個人感覺有點得不償失。Orx的設計是超前,但是目前來看,傳統之所以成為傳統,還有有其道理所在。

    個人認為,Orx可改進的方向有幾個:

其一,Orx的底層就是應該通過傳統的手法去構建,不要弄的配置那麼深入,各個模組需要那麼靈活的配置,實現上的負擔可以減輕很多。並且,這一部分的API設計也是可以對外的。也有文檔指明各個API的搭配使用,外部使用者可以在完全不使用配置的情況下,將Orx作為一個普通的不是資料驅動的引擎來使用。雖然這個比較不符合作者的初衷。

其二,配置驅動的設計完全構建在上面那一層傳統的不是資料驅動的那一層遊戲引擎上,只要下層的API設計合理,這完全可以做到。對於普通使用者來說,學習曲線也可以更加平緩,在學習和瞭解了底層的API使用後,配置僅僅是用於加速自己設計的實現,而不是僅僅知道配置,一旦某個地方的配置出現隱晦的錯誤就一籌莫展(這個問題我自己和很多中國使用者都出現過),因為瞭解底層的API 的使用,出現類似問題,通過在上層的調試,(即讀取配置使用底層介面這一層)就能很容易的發現。而且,配置的使用不應該成為強制性的,這僅僅是使用者提高開發速度的一種方式,假如使用者認為底層的API已經足夠使用,完全可以不用配置層。前面這兩條說簡單點就是將資料驅動與傳統的介面相分離,而不是真的作為引擎的強制項。

其三,配置其實不能完全等同與一般意義的資料,需要手工編寫的格式嚴格的配置,會給使用者帶來很大的負擔,我有時甚至覺得寫代碼比寫配置更加容易,起碼出錯了更加方便調試。這些問題就需要能夠保證產生正確配置的工具來解決了。作為了遊戲引擎,Orx在這方面還比較欠缺,因為作者“憎恨”寫UI的特點,估計這也不能靠作者來完成了,需要Orx的社區力量來完成。沒有工具組建組態的配置驅動,根本就稱不上真正的資料驅動,不過是將寫代碼的負擔移到寫配置而已。。。。。。。。。。。。。。。。。。

以上純屬個人看法,而曆史證明,由於懂得東西不是很多,所以我的個人看法很多是不正確的,比如前面我提到的Orx的list實現很奇怪的問題
。。。。。。。。。。。。。。。。。。所以請讀者不要輕信上述問題,那僅僅是一家之言。

 

原創文章作者保留著作權 轉載請註明原作者 並給出連結





write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.