Cocos2dx-OpenGL ES 2.0教程:你的第一個三角形(1)

前言

在本系列教程中,我會以當下最流行的2D引擎Cocos2D-X爲基礎,介紹OpenGL ES 2.0的一些基本用法。本系列教程的宗旨是OpenGL掃盲,讓你們在使用Cocos2D-X過程當中,知其然,更知其因此然。由於我本身的圖形學水平有限,因此這些教程不會涉及很是底層的數學原理,同時也不會過多地說起OpenGL自己的一些細節知識。可是我會在每篇文章的最後給出一些參考連接,你們能夠順藤摸瓜,一舉Get OpenGL這個新技能。html

我第一次學習OpenGL是在2008年,可是那時候學得很爛,被各類矩陣變換搞得雲裏霧裏。我於今年年初完全從新學習OpenGL,目前來說,應該算是入門了,至少矩陣變換是理解了,同時也會本身寫一些簡單的shader,能夠進行OpenGL調試了。可是,個人學習之路纔剛剛開始,我但願在我本身學習的過程,把有用的一些知識記錄下來,方便本身和他人查閱。通過此次從新學習,我我的以爲,OpenGL真的沒有那麼難,只要你用心,就必定能夠學會。固然,好的學習方法和好的學習資料確定是會使之事半功倍的,但願接下來個人這些博文能爲你們帶來些許幫助。node

在第一篇文章正式開始前,我談下我本身的入門心得體會吧,而《如何學習OpenGL》這是個更大的話題,等我OpenGL水平精進以後,我再單獨寫一篇文章來談談個人見解。git

目前來講,個人體會是「三要」和「三不要」。api

  • 要理解OpenGL渲染管線緩存

  • 要理解OpenGL是個狀態機ide

  • 要多動手實踐。函數

固然還有最重要的「三不要」:工具

  • 不要天天去羣裏問怎樣最快能學好OpenGL學習

  • 不要天天去看各類資料而不動手寫一點代碼網站

  • 不要出了問題處處問,嘗試先本身解決,實在解決不了再問

正文

準備工做

首先,是建立一個新的工程(注意我這裏使用的版本是3.7. Update: Tuesday, June 16, 2015)。打開命令行工具,而後輸入下列命令:

1
cocos new -l cpp

若是對於上述命令不瞭解的用戶,請猛戳這裏.

編譯並運行成功,而後把HelloWorldScene.cpp裏面的init函數修改爲下面的樣子:

12345678910
bool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }    return true;    }

此時,再編譯運行之。你將會獲得如下界面。

firstfirst

發送CustomCommand

因爲Cocos2D-X 從3.0開始引入了一種新的渲染機制,全部的OpenGL渲染代碼再也不放到每個node的draw函數裏面,而是經過各類RenderCommand封裝起來,而後添加到一個渲染隊列裏面去,最後在每一幀結束時把全部的這些命令都渲染出來。具體細節,你們能夠參考這個文檔.

首先,打開HelloWorldScene.h,添加一個onDraw函數,一個CustomCommand成員變量,而且重載Layer的visit函數,代碼以下:

12345678910
class HelloWorld : public cocos2d::Layer{public:     //其它函數省略    virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;    void onDraw();private:    CustomCommand _command;};

而後咱們實現這個visit函數:

1234567
void HelloWorld::visit(cocos2d::Renderer *renderer, const Mat4 &transform,uint32_t parentFlags){    Layer::visit(renderer, transform, parentFlags);    _command.init(_globalZOrder);    _command.func = CC_CALLBACK_0(HelloWorld::onDraw, this);    Director::getInstance()->getRenderer()->addCommand(&_command);}

這裏要稍微解釋一下。因爲此函數是個重載的虛函數,因此咱們在函數的最開始調用了父類的visit函數。若是你不調用父類的visit函數,那麼當你往HelloWorldScene裏面添加節點的時候,它們是不會被渲染出來的。(這個留給讀者本身去完成)

而後,咱們使用_globalZOrder和一個std::function來初始化CustomCommand。_globalZOrder會影響渲染的順序,這個在後面的博文中再詳細探討。而std::function會在CustomCommand被render隊列處理的時候被調用。最後咱們把該CustomCommand添加到renderer裏面去。

最後,讓咱們看看onDraw函數,它是整個繪製三角形的核心。

123456789101112131415161718192021222324252627282930
void HelloWorld::onDraw(){    //得到當前HelloWorld的shader    auto glProgram = getGLProgram();   //使用此shader    glProgram->use();   //設置該shader的一些內置uniform,主要是MVP,即model-view-project矩陣    glProgram->setUniformsForBuiltins();    auto size = Director::getInstance()->getWinSize();    //指定將要繪製的三角形的三個頂點,分別位到屏幕左下角,右下角和正中間的頂端    float vertercies[] = { 0,0,   //第一個點的座標                            size.width, 0,   //第二個點的座標                           size.width / 2, size.height};  //第三個點的座標    //指定每個頂點的顏色,顏色值是RGBA格式的,取值範圍是0-1    float color[] = { 0, 1,0, 1,    //第一個點的顏色,綠色                        1,0,0, 1,  //第二個點的顏色, 紅色                         0, 0, 1, 1};  //第三個點的顏色, 藍色    //激活名字爲position和color的vertex attribute    GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);    //分別給position和color指定數據源    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertercies);    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, color);    //繪製三角形,所謂的draw call就是指這個函數調用    glDrawArrays(GL_TRIANGLES, 0, 3);    //通知cocos2d-x 的renderer,讓它在合適的時候調用這些OpenGL命令    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3);    //若是出錯了,可使用這個函數來獲取出錯信息    CHECK_GL_ERROR_DEBUG();}

若是你如今直接運行程序,會crash。這是由於咱們尚未指定Shader,因此下面的調用會失敗:

123456789
auto glProgram = getGLProgram();glProgram->use();glProgram->setUniformsForBuiltins();``` 接下來,讓咱們在HelloWorldScene.cpp的init方法中加入下列代碼:```cppthis->setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));

這個調用的含義是從Cocos2D-X的shader緩存中取出一個帶有position和color頂點屬性的shader,而後傳給HelloWorld這個Layer.若是你是第一次接觸OpenGL ES,看到這句話確定沒法理解,不過沒有關係,後面的文章咱們逐步講清楚。若是你等不及,也能夠先看我在文章最後推薦的連接。

接下來,運行一下程序.恭喜你,你的第一個漂亮的三角形完成啦,還算簡單吧:)

cocos2d-x-es-1.1cocos2d-x-es-1.1

本教程源代碼下載,請認準tutorial1分支。

Git倉庫地址: https://git.oschina.net/zilongshanren/Cocos2D-X-OpenGL-ES-2.0

結束語

爲了保持第一篇文章的簡單性,我只在畫三角形的代碼裏面給了一些註釋,由於我並不想一開始就涉及到OpenGL底層的一些細節,並且有些內容我一時半會兒也很難說清楚。因此,我會在文章的最後給出一些參考連接,強烈推薦你們在看完本文後,有時間就多看一看這些連接,相信對理解上面的代碼有幫助。下一篇文章中,我將給你們介紹如何編寫本身的shader,包括vertex attribute, uniform,vertex shader, fragment shader等內容。若是您對本文有什麼建議或者意義,歡迎在下方評論。

寫在最後

關於參考連接:全部的推薦閱讀都是我精心挑選的,部份內容我本身看過,另一些我也正在計劃看。若是你們有好的資料,歡迎推薦給我。
關於評論:請不要找我要電子書,全部的電子書均可以經過google找到。

另外,我推薦的資料大部分都是英文版,若是對英文不是很感冒的同窗,能夠看翻譯的版本

推薦閱讀

網站:

  1. http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html

  2. http://www.opengl-tutorial.org/

  3. http://antongerdelan.net/opengl/index.html

  4. http://www.arcsynthesis.org/gltut/

  5. http://www.scratchapixel.com/

  6. http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-1:-The-Graphics-Pipeline.html

視頻:

https://www.youtube.com/watch?v=-tonZsbHty8&index=26&list=PLRwVmtr-pp06qT6ckboaOhnm9FxmzHpbY

書籍:

Iphone 3D programming

OpenGL ES 2.0 for Android

OpenGL ES 2.0 Programming Guide

Real-Time Rendering, Third Edition

相關文章
相關標籤/搜索