Android OpenGL ES 四.基礎(chǔ)圖形、多邊形的繪制(轉(zhuǎn)載補(bǔ)充)

基礎(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

案例圖示

image
GL_LINES
image
GL_LINE_LOOP
image
GL_LINE_STRIP
image
GL_TRIANGLES
image
GL_TRIANGLE_STRIP
image
GL_TRIANGLE_FAN
image

多邊形繪制

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

33019-b88c09bdab9b877c[1].gif

關(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)注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容