前言
之前我們繪制的都是一些簡單的基礎(chǔ)圖形榴啸,本章節(jié)我們繪制一個復雜些的形狀,如下膳凝。
圖中的數(shù)字是后期標注碑隆,并非GL繪制。
根據(jù)之前學的知識蹬音,我們知道上煤,這個圖形可以分解為4個三角形,用數(shù)字代表頂點序號著淆,分別是
- 0, 1, 2
- 0, 2, 3
- 0, 4, 1
- 3, 2, 5
在程序中劫狠,每個頂點對應x、y坐標永部,那么我們的頂點數(shù)組數(shù)據(jù)就需要如下聲明:
private static final float[] POINT_DATA = {
// 0, 1, 2
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
// 0, 2, 3
-0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
// 0, 4, 1
-0.5f, -0.5f,
0f, -1.0f,
0.5f, -0.5f,
// 3, 2, 5
-0.5f, 0.5f,
0.5f, 0.5f,
0f, 1.0f,
};
所以嘉熊,實際聲明的頂點數(shù)是4 * 3 = 12個頂點。而其中有很多頂點是可以重復的扬舒,這導致2個問題:
- 頂點數(shù)據(jù)過多阐肤,代碼的可讀性降低,需要隔幾行就注釋一下
- 有重復的頂點數(shù)據(jù)讲坎,造成了內(nèi)存的浪費
這種繪制方式孕惜,叫頂點法繪制。
而本章節(jié)會引入一個新的技巧:索引法繪制晨炕。
代碼實現(xiàn)
1. 定義坐標衫画、索引
/**
* 頂點數(shù)據(jù)
*/
private static final float[] POINT_DATA = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
0f, -1.0f,
0f, 1.0f,
};
/**
* 數(shù)組繪制的索引:當前是繪制三角形,所以是3個元素構(gòu)成一個繪制順序
*/
private static final short[] VERTEX_INDEX = {
0, 1, 2,
0, 2, 3,
0, 4, 1,
3, 2, 5};
這里第一個float類型的數(shù)組瓮栗,定義了每個頂點的坐標位置削罩。
第二個數(shù)組是short類型的,定義了上一個數(shù)組的繪制順序费奸。也就是0代表著POINT_DATA數(shù)組的第0組的數(shù)據(jù)(-0.5f, -0.5f)弥激。再解釋下,之后我們會聲明為2個點為一個頂點愿阐,所以索引0并非表示第0位的POINT_DATA[0]微服,而是第0組。
2. 繪制圖形
@Override
public void onDrawFrame(GL10 glUnused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// 1. 繪制模式缨历; 2. 從數(shù)組中讀取的數(shù)據(jù)長度以蕴; 3. 加載的數(shù)據(jù)格式; 4. 讀取的數(shù)據(jù)緩沖區(qū)
GLES20.glDrawElements(GLES20.GL_TRIANGLES, VERTEX_INDEX.length,
GLES20.GL_UNSIGNED_SHORT, mVertexIndexBuffer);
}
這里使用到了一個新的方法GLES20.glDrawElements辛孵,方法參數(shù)分別是
- 圖形繪制方式
- 繪制的頂點數(shù)
- 索引的數(shù)據(jù)格式
- 索引的數(shù)據(jù)Buffer
這里再回顧下頂點法的繪制方法GLES20.glDrawArrays丛肮,方法參數(shù)分別是
- 圖形繪制方式
- 從頂點數(shù)據(jù)讀取數(shù)據(jù)的起點位置(以點作為單位,而非向量)
- 繪制的頂點數(shù)
3. 頂點法魄缚、索引法的比較
按照索引的數(shù)據(jù)聲明方式宝与,代碼的可讀性大大地提高,那么性能上有多大提升呢?
首先伴鳖,我們知道GL中,一個Float類型的數(shù)據(jù)占4個Byte徙硅,一個Short類型的占2個Byte榜聂。
那么在前言中聲明的12個頂點的方式,也就是頂點法繪制方式嗓蘑,占的內(nèi)存空間是:
12(頂點數(shù)) * 2(x须肆、y兩個向量為一組) * 4(Float格式占的Byte字節(jié)) = 96字節(jié)
而索引法的占的內(nèi)存空間是:
6(頂點數(shù)) * 2(x、y兩個向量為一組) * 4(Float格式占的Byte字節(jié)) + 12(索引數(shù)) * 2(Short格式占的Byte字節(jié)) = 48 + 24 = 72字節(jié)
本章節(jié)繪制的圖形頂點屬性比較單一桩皿,只有頂點位置豌汇,假若包含了顏色等其他頂點信息,那么頂點法占的內(nèi)存將更大泄隔。
歸納下兩種繪制方式的對比情況拒贱。
繪制方式 | 適用場景 | 可讀性 | 內(nèi)存計算方式 |
---|---|---|---|
頂點法 | 頂點復用情況少 | 低 | 頂點數(shù) * 頂點屬性數(shù) * 頂點數(shù)據(jù)格式類型 |
索引法 | 頂點復用情況多 | 高 | 頂點數(shù) * 頂點屬性數(shù) * 頂點數(shù)據(jù)格式類型 + 索引數(shù) * 索引數(shù)據(jù)格式類型 |
參考
見Android OpenGL ES學習資料所列舉的博客、資料佛嬉。
GitHub代碼工程
本系列課程所有相關(guān)代碼請參考我的GitHub項目GLStudio逻澳。
課程目錄
本系列課程目錄詳見 簡書 - Android OpenGL ES教程規(guī)劃