06 - OpenGL ES學習之繪制一個立方體

看過之前一系列的文章之后潦牛,我們對ES有了一個比較基礎(chǔ)的理解了泛领,下面我們通過繪制一個隨時間旋轉(zhuǎn)的立方體一喘,來匯總前幾篇文章的內(nèi)容酝豪,以加深對OpenGL ES渲染過程的理解涛碑。

示例代碼在git倉庫

正如讀者所知,一個正方體是由六個面組成的孵淘,那這里我們拆分需求蒲障,逐次繪制六個面,然后用時間作為輸入量瘫证,改變MVP矩陣揉阎,就能最終實現(xiàn)我們的效果。在后續(xù)的文章中背捌,我都是在VSCode里編寫著色器毙籽,安裝GLSL擴展后,可以高亮顯示毡庆,比較方便坑赡。

1.首先我們先來展示一下立方體的空間示意圖

立方體空間示意圖

繪制與X軸垂直的平面的代碼:

- (void)drawPositiveXWithColorLocation:(GLuint)colorLocation andPositionLocation:(GLuint)positionLocation {
    //每一行代表(x,y,z,r,g,b)
    static GLfloat positiveX[24] = {
        0.5f,  0.5f,  0.5f, 1.0f, 0.6f, 0.3f,
        0.5f,  -0.5f, 0.5f, 1.0f, 0.6f, 0.3f,
        0.5f, -0.5f, -0.5f, 1.0f, 0.6f, 0.3f,
        0.5f, 0.5f,  -0.5f, 1.0f, 0.6f, 0.3f,
        
    };
    
    if (self.vertexBufferId == 0) {
        glGenBuffers(1, &_vertexBufferId);
        glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId);
    }
    glBufferData(GL_ARRAY_BUFFER, sizeof(positiveX), positiveX, GL_STATIC_DRAW);
    
    GLuint offset = 3 * sizeof(float);
    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), NULL);
    glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void *) offset);
    
    _esContext.drawFunc(&_esContext);
    
}

這里我們先找出與X軸垂直相交的這個面的四個頂點坐標,因為我們繪圖采用的是GL_TRIANGLE_FAN模式么抗,所以只需要四個頂點就可以了毅否。
其它5個面也是這樣繪制的

加載MVP矩陣的代碼如下:

 [super glkView:view drawInRect:rect];
    _elapsedTime += 0.02;
    //時間系數(shù)
    float varyFactor =  (sin(self.elapsedTime) + 1.0) / 2.0; //0 ~ 1
    _esContext.width = view.drawableWidth;
    _esContext.height = view.drawableHeight;
    
    
    //開啟深度測試,為了確定繪制的時候哪一個面繪制在上面
    glEnable(GL_DEPTH_TEST);
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    //獲取屬性color和position的index
    GLint colorIndex = glGetAttribLocation(_esContext.program, "vColor");
    GLint positionIndex = glGetAttribLocation(_esContext.program, "vPosition");
    
    //創(chuàng)建MVP矩陣
    GLint modelIndex = glGetUniformLocation(_esContext.program, "modelTransform");
    GLint viewIndex = glGetUniformLocation(_esContext.program, "viewTransform");
    GLint projectIndex = glGetUniformLocation(_esContext.program, "projectTransform");
    
    GLKMatrix4 rotate = GLKMatrix4MakeRotation(varyFactor * M_PI * 2, 1, 1, 1);
    GLKMatrix4 translate = GLKMatrix4MakeTranslation(-0.1, -0.1, -0.1);
    
    GLKMatrix4 modelMatrix = GLKMatrix4Multiply(translate, rotate);
    

    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(90), view.frame.size.width / view.frame.size.height, 0.2, 10.0);
    
    
    GLKMatrix4 cameraMatrix = GLKMatrix4MakeLookAt(0, 0, 2 * (varyFactor + 1), 0, 0, 0, 0, 1, 0);
    
    //加載MVP矩陣
    glUniformMatrix4fv(modelIndex, 1, GL_FALSE, modelMatrix.m);
    glUniformMatrix4fv(viewIndex  , 1, GL_FALSE, cameraMatrix.m);
    glUniformMatrix4fv(projectIndex, 1, GL_FALSE, projectionMatrix.m);
    
    //開啟頂點屬性
    glEnableVertexAttribArray(colorIndex);
    glEnableVertexAttribArray(positionIndex);
    
    
    //加載頂點數(shù)據(jù)蝇刀,并且依次繪制立方體的六個面
    [self drawPositiveXWithColorLocation:colorIndex andPositionLocation:positionIndex];
    [self drawNegativeXWithColorLocation:colorIndex andPositionLocation:positionIndex];
    [self drawPositiveYWithColorLocation:colorIndex andPositionLocation:positionIndex];
    [self drawNegativeYWithColorLocation:colorIndex andPositionLocation:positionIndex];
    [self drawPositiveZWithColorLocation:colorIndex andPositionLocation:positionIndex];
    [self drawNegativeZWithColorLocation:colorIndex andPositionLocation:positionIndex];
   
    //關(guān)閉頂點屬性
    glDisableVertexAttribArray(colorIndex);
    glDisableVertexAttribArray(positionIndex);

這里需要注意兩點
1.需要開啟深度測試螟加,如果沒有開啟深度測試的話,ES是不知道你繪制面的層次吞琐,會出現(xiàn)如下效果:


未開啟深度測試

2.開啟深度測試后捆探,除了需要清除顏色緩沖區(qū)外,還需要清除深度緩沖區(qū)

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

最終正確的效果如下圖:


開啟深度測試
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末站粟,一起剝皮案震驚了整個濱河市徐许,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卒蘸,老刑警劉巖雌隅,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缸沃,居然都是意外死亡恰起,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門趾牧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來检盼,“玉大人,你說我怎么就攤上這事翘单《滞鳎” “怎么了蹦渣?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長貌亭。 經(jīng)常有香客問我柬唯,道長,這世上最難降的妖魔是什么圃庭? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任锄奢,我火速辦了婚禮,結(jié)果婚禮上剧腻,老公的妹妹穿的比我還像新娘拘央。我一直安慰自己,他們只是感情好书在,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布灰伟。 她就那樣靜靜地躺著,像睡著了一般儒旬。 火紅的嫁衣襯著肌膚如雪栏账。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天义矛,我揣著相機與錄音,去河邊找鬼盟萨。 笑死凉翻,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的捻激。 我是一名探鬼主播制轰,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胞谭!你這毒婦竟也來了垃杖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤丈屹,失蹤者是張志新(化名)和其女友劉穎调俘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旺垒,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡彩库,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了先蒋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骇钦。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖竞漾,靈堂內(nèi)的尸體忽然破棺而出眯搭,到底是詐尸還是另有隱情窥翩,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布鳞仙,位于F島的核電站寇蚊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏繁扎。R本人自食惡果不足惜幔荒,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梳玫。 院中可真熱鬧爹梁,春花似錦、人聲如沸提澎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盼忌。三九已至积糯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谦纱,已是汗流浹背看成。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留跨嘉,地道東北人川慌。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像祠乃,于是被迫代替她去往敵國和親梦重。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容