OpenGLES-03 使用索引繪制矩形

這篇文章我們同樣借助上篇文章《OpenGLES-02 繪制基本圖元(點(diǎn)兽狭、線环揽、三角形)》的代碼腊尚,使用另外一種畫法來(lái)繪制一個(gè)矩形吨拗。

修改render方法如下:

-(void)render
{
    //設(shè)置清屏顏色,默認(rèn)是黑色,如果你的運(yùn)行結(jié)果是黑色婿斥,問(wèn)題就可能在這兒
    glClearColor(0.3, 0.5, 0.8, 1.0);
    /*
    glClear指定清除的buffer
    共可設(shè)置三個(gè)選項(xiàng)GL_COLOR_BUFFER_BIT劝篷,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT
    也可組合如:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    這里我們只用了color buffer,所以只需清除GL_COLOR_BUFFER_BIT
     */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Setup viewport
    glViewport(0, 0, self.frame.size.width, self.frame.size.height);
    
    GLfloat vertices[] = {
        // 第一個(gè)三角形
        0.5f, 0.5f, 0.0f,   // 右上角
        0.5f, -0.5f, 0.0f,  // 右下角
        -0.5f, 0.5f, 0.0f,  // 左上角
        // 第二個(gè)三角形
        0.5f, -0.5f, 0.0f,  // 右下角
        -0.5f, -0.5f, 0.0f, // 左下角
        -0.5f, 0.5f, 0.0f   // 左上角
    };
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(_positionSlot);
    
    glDrawArrays(GL_TRIANGLES, 0, 6);
    [_context presentRenderbuffer:_renderBuffer];
}
運(yùn)行結(jié)果.png

如上代碼所示民宿,我們繪制的矩形是由2個(gè)三角形組成的娇妓,一個(gè)三角形3個(gè)頂點(diǎn),共使用了6個(gè)頂點(diǎn)勘高,其中第2個(gè)頂點(diǎn)與第4個(gè)頂點(diǎn)相同(0.5,-0.5,0.0)峡蟋,第3個(gè)頂點(diǎn)與第6個(gè)頂點(diǎn)相同(-0.5,0.5,0.0)坟桅。
其實(shí)對(duì)于矩形來(lái)說(shuō)华望,它只有4個(gè)而不是6個(gè)頂點(diǎn),繪制這個(gè)矩形仅乓,我們指定了右下角和左上角兩次赖舟,這樣就產(chǎn)生了50%的額外開銷。還好我們這會(huì)兒只要畫一個(gè)矩形夸楣,當(dāng)我們要畫成千上萬(wàn)個(gè)矩形或者別的多邊形的時(shí)候宾抓,這樣的繪制方法產(chǎn)生的額外消耗會(huì)更多從而產(chǎn)生一大堆浪費(fèi)。
更好的解決方案是只儲(chǔ)存不同的頂點(diǎn)豫喧,并設(shè)定繪制這些頂點(diǎn)的順序石洗。這樣子我們只要儲(chǔ)存4個(gè)頂點(diǎn)就能繪制矩形了,之后只要指定繪制的順序就行了紧显。還好OpenGL有這樣的方式:

glDrawElements()讲衫;

glDrawElements 函數(shù)的原型為:glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);

第一個(gè)參數(shù) mode 為描繪圖元的模式,其有效值為:GL_POINTS, GL_LINES, GL_LINE_STRIP,  GL_LINE_LOOP,  GL_TRIANGLES,  GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN孵班。這些模式具體含義下面有介紹涉兽。

第二個(gè)參數(shù) count 為頂點(diǎn)索引的個(gè)數(shù)也就是招驴,type 是指頂點(diǎn)索引的數(shù)據(jù)類型,因?yàn)樗饕冀K是正值枷畏,索引這里必須是無(wú)符號(hào)型的非浮點(diǎn)類型别厘,因此只能是 GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT 之一,為了減少內(nèi)存的消耗拥诡,盡量使用最小規(guī)格的類型如 GL_UNSIGNED_BYTE触趴。

第三個(gè)參數(shù) indices 是存放頂點(diǎn)索引的數(shù)組。(indices 是 index 的復(fù)數(shù)形式袋倔,3D 里面很多單詞的復(fù)數(shù)都挺特別的雕蔽。)

索引緩沖對(duì)象(簡(jiǎn)稱EBO)的工作方式正是這樣的。和頂點(diǎn)緩沖對(duì)象一樣宾娜,EBO也是一個(gè)緩沖批狐,它專門儲(chǔ)存索引,OpenGL調(diào)用這些頂點(diǎn)的索引來(lái)決定該繪制哪個(gè)頂點(diǎn)前塔。所謂的索引繪制(Indexed Drawing)正是我們問(wèn)題的解決方案嚣艇。首先,我們先要定義(獨(dú)一無(wú)二的)頂點(diǎn)华弓,和繪制出矩形所需的索引:

GLfloat vertices[] = {
    0.5f, 0.5f, 0.0f,   // 右上角
    0.5f, -0.5f, 0.0f,  // 右下角
    -0.5f, -0.5f, 0.0f, // 左下角
    -0.5f, 0.5f, 0.0f   // 左上角
};

GLubyte indices[] = { // 注意索引從0開始! 
    0, 1, 3, // 第一個(gè)三角形
    1, 2, 3  // 第二個(gè)三角形
};

然后整個(gè)render函數(shù)的代碼該是這樣的:

-(void)render
{
    //設(shè)置清屏顏色,默認(rèn)是黑色食零,如果你的運(yùn)行結(jié)果是黑色,問(wèn)題就可能在這兒
    glClearColor(0.3, 0.5, 0.8, 1.0);
    /*
    glClear指定清除的buffer
    共可設(shè)置三個(gè)選項(xiàng)GL_COLOR_BUFFER_BIT寂屏,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT
    也可組合如:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    這里我們只用了color buffer贰谣,所以只需清除GL_COLOR_BUFFER_BIT
     */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Setup viewport
    glViewport(0, 0, self.frame.size.width, self.frame.size.height);
 
    GLfloat vertices[] = {
        0.5f, 0.5f, 0.0f,   // 右上角
        0.5f, -0.5f, 0.0f,  // 右下角
        -0.5f, -0.5f, 0.0f, // 左下角
        -0.5f, 0.5f, 0.0f   // 左上角
    };
    
    GLubyte indices[] = { // 注意索引從0開始!
        0, 1, 3, // 第一個(gè)三角形
        1, 2, 3  // 第二個(gè)三角形
    };
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(_positionSlot);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);  //6表示有6個(gè)索引數(shù)據(jù),可以使用sizeof(indices)/sizeof(GLubyte)來(lái)確定
    
    [_context presentRenderbuffer:_renderBuffer];
}

兩種方式的運(yùn)行結(jié)果是一樣的,我們可以發(fā)現(xiàn)迁霎,運(yùn)行圖中的矩形是個(gè)長(zhǎng)方形吱抚,而我們給的坐標(biāo),照理來(lái)講應(yīng)該是正方形的考廉,這是因?yàn)槠聊坏膶捀弑炔煌乇瑢?duì)應(yīng)的openGL坐標(biāo)x、y坐標(biāo)也不一樣昌粤,后面我們會(huì)講到投影矩陣既绕,投影矩陣能修復(fù)這個(gè)問(wèn)題。

所有教程代碼在此 : https://github.com/qingmomo/iOS-OpenGLES-

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涮坐,一起剝皮案震驚了整個(gè)濱河市凄贩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌袱讹,老刑警劉巖疲扎,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡评肆,警方通過(guò)查閱死者的電腦和手機(jī)债查,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瓜挽,“玉大人盹廷,你說(shuō)我怎么就攤上這事【贸龋” “怎么了俄占?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)淆衷。 經(jīng)常有香客問(wèn)我缸榄,道長(zhǎng),這世上最難降的妖魔是什么祝拯? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任甚带,我火速辦了婚禮,結(jié)果婚禮上佳头,老公的妹妹穿的比我還像新娘鹰贵。我一直安慰自己,他們只是感情好康嘉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布碉输。 她就那樣靜靜地躺著,像睡著了一般亭珍。 火紅的嫁衣襯著肌膚如雪敷钾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天肄梨,我揣著相機(jī)與錄音阻荒,去河邊找鬼。 笑死峭范,一個(gè)胖子當(dāng)著我的面吹牛财松,可吹牛的內(nèi)容都是我干的瘪贱。 我是一名探鬼主播纱控,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼菜秦!你這毒婦竟也來(lái)了甜害?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤球昨,失蹤者是張志新(化名)和其女友劉穎尔店,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚣州,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鲫售,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片该肴。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡情竹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匀哄,到底是詐尸還是另有隱情秦效,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布涎嚼,位于F島的核電站阱州,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏法梯。R本人自食惡果不足惜苔货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望立哑。 院中可真熱鬧蒲赂,春花似錦、人聲如沸刁憋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)至耻。三九已至若皱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尘颓,已是汗流浹背走触。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疤苹,地道東北人互广。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像卧土,于是被迫代替她去往敵國(guó)和親惫皱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348