基礎(chǔ)圖形繪制
之前講解過(guò),OpenGL ES中,只提供了3種基本圖形:點(diǎn)、線、三角形。而其他我們熟知的圖形,都是基于這3種基本圖形處理拼接合成的。那么本章節(jié)我們先從OpenGL中給我們提供的3種基礎(chǔ)圖形講起,再介紹下其他圖形的繪制。
基礎(chǔ)圖形繪制API
/**
* 使用頂點(diǎn)數(shù)據(jù)繪制圖形
*/
GLES20.glDrawArrays(int mode, int first, int count);
基本上,很多場(chǎng)景下我們都使用這個(gè)方法來(lái)進(jìn)行圖形的繪制,這個(gè)方法通過(guò)調(diào)用GLES20.glVertexAttribPointer傳遞進(jìn)去的頂點(diǎn)數(shù)據(jù)來(lái)繪制目標(biāo)圖形。相關(guān)參數(shù)作用如下
- mode:繪制模式,控制繪制點(diǎn)、線段、三角形以及其具體的連接方式
- first:從頂點(diǎn)數(shù)據(jù)讀取數(shù)據(jù)的起點(diǎn)位置(以點(diǎn)作為單位,而非向量)
- count:繪制的頂點(diǎn)數(shù)(以點(diǎn)作為單位,而非向量)
廢話說(shuō)明:以點(diǎn)作為單位,而非向量,也就是說(shuō)無(wú)論頂點(diǎn)數(shù)組是用x、y兩個(gè)向量來(lái)標(biāo)識(shí),或者是用x、y、z、w來(lái)標(biāo)識(shí),最終都是以一個(gè)點(diǎn)的距離來(lái)控制繪制。主要原因是這里是傳遞給GL層的,而GL層的坐標(biāo)是vec4的,和我們從java層傳進(jìn)去的無(wú)關(guān),畢竟沒(méi)傳遞的是有默認(rèn)值的。
當(dāng)前我們有個(gè)案例,按順序有A、B、C、D、E、F一共6個(gè)點(diǎn)。
而mode的具體參數(shù)值如下:
| 參數(shù) | 類型 | 作用 | 案例圖形 |
|---|---|---|---|
| GL_POINTS | 點(diǎn) | 繪制獨(dú)立的點(diǎn) | A、B、C、D、E、F |
| GL_LINES | 線段 | 每2個(gè)點(diǎn)構(gòu)成一條線段 | AB、CD、EF |
| GL_LINE_LOOP | 線段 | 按順序?qū)⑺械狞c(diǎn)連接起來(lái),包括首位相連 | AB、BC、CD、DE、EF、FA |
| GL_LINE_STRIP | 線段 | 按順序?qū)⑺械狞c(diǎn)連接起來(lái),不包括首位相連 | AB、BC、CD、ED、EF |
| GL_TRIANGLES | 三角形 | 每3個(gè)點(diǎn)構(gòu)成一個(gè)三角形 | ABC、DEF |
| GL_TRIANGLE_STRIP | 三角形 | 相鄰3個(gè)點(diǎn)構(gòu)成一個(gè)三角形,不包括首位兩個(gè)點(diǎn) | ABC、BCD、CDE、DEF |
| GL_TRIANGLE_FAN | 三角形 | 第一個(gè)點(diǎn)和之后所有相鄰的2個(gè)點(diǎn)構(gòu)成一個(gè)三角形 | ABC、ACD、ADE、AEF |
案例圖示

GL_LINES

GL_LINE_LOOP

GL_LINE_STRIP

GL_TRIANGLES

GL_TRIANGLE_STRIP

GL_TRIANGLE_FAN

多邊形繪制
實(shí)心的多邊形我們可以通過(guò)三角形拼接而成來(lái)實(shí)現(xiàn),非實(shí)心的則可以通過(guò)線段拼接實(shí)現(xiàn)。具體效果如下圖,黃色部分為實(shí)心多邊形,紅線為非實(shí)心多邊形。當(dāng)邊數(shù)足夠多的時(shí)候,多邊形便接近于圓形。

關(guān)鍵代碼實(shí)現(xiàn)如下:
/**
* 多邊形的頂點(diǎn)數(shù),即邊數(shù)
*/
private int mPolygonVertexCount = 3;
/**
* 繪制所需要的頂點(diǎn)數(shù)
*/
private float[] mPointData;
/**
* 多邊形頂點(diǎn)與中心點(diǎn)的距離
*/
private static final float RADIUS = 0.5f;
private void updateVertexData() {
// 邊數(shù)+中心點(diǎn)+閉合點(diǎn);一個(gè)點(diǎn)包含x、y兩個(gè)向量
mPointData = new float[(mPolygonVertexCount + 2) * 2];
// 組成多邊形的每個(gè)三角形的中心點(diǎn)角的弧度
float radian = (float) (2 * Math.PI / mPolygonVertexCount);
// 中心點(diǎn)
mPointData[0] = 0f;
mPointData[1] = 0f;
// 多邊形的頂點(diǎn)數(shù)據(jù)
for (int i = 0; i < mPolygonVertexCount; i++) {
mPointData[2 * i + 2] = (float) (RADIUS * Math.cos(radian * i));
mPointData[2 * i + 1 + 2] = (float) (RADIUS * Math.sin(radian * i));
}
// 閉合點(diǎn):與多邊形的第一個(gè)頂點(diǎn)重疊
mPointData[mPolygonVertexCount * 2 + 2] = (float) (RADIUS * Math.cos(0));
mPointData[mPolygonVertexCount * 2 + 3] = (float) (RADIUS * Math.sin(0));
mVertexData = ByteBufferUtil.createFloatBuffer(mPointData);
mVertexData.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
false, 0, mVertexData);
}
private void drawShape() {
GLES20.glUniform4f(uColorLocation, 1.0f, 1.0f, 0.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, mPolygonVertexCount + 2);
}
思考與推論
上面的示例圖中,在onDrawFrame里,同時(shí)繪制了點(diǎn)、線、三角形,也就是多次調(diào)用glDrawArrays,并且繪制出來(lái)了。
我們暫時(shí)定義glDrawArrays是進(jìn)行一次圖元組裝,也就是繪制一個(gè)圖層,那么一次onDrawFrame只繪制一幀,而這一幀可以繪制多種圖元,多個(gè)圖層。
也就是:一次只繪制一幀,但是一幀可以繪制多個(gè)圖層。
參考
見Android OpenGL ES學(xué)習(xí)資料所列舉的博客、資料。
GitHub代碼工程
本系列課程所有相關(guān)代碼請(qǐng)參考我的GitHub項(xiàng)目GLStudio。
課程目錄
本系列課程目錄詳見 簡(jiǎn)書 - Android OpenGL ES教程規(guī)劃
作者:Benhero
鏈接:http://www.itdecent.cn/p/eb11a8346cf6
來(lái)源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。