一步一步學android OpenGL ES2.0編程(2)



定義形狀

會定義在OpenGLES view上所繪製的形狀,是你創建高端圖形應用傑作的第一步。如果你不懂OpenGLES定義圖形對象的一些基本知識,使用OpenGLES可能有一點棘手。

本文解釋OpenGLES相對於Android設備屏幕的座標系統、定義一個形狀的基礎知識、形狀的外觀、以及如何定義三角形和正方形。

定義一個三角形


OpenGLEs允許你使用坐本在三個維度上定義繪製對象。所以,在你可以繪製一個三角形之前,你必須定義它的座標。在OpenGL中,典型的方式是爲座標定義一個浮點類型的頂點數組。爲了最高效,你應把這些座標都寫進一個ByteBuffer,它會被傳到OpenGLES圖形管線以進行處理。

class Triangle {

    private FloatBuffer vertexBuffer;

    // 數組中每個頂點的座標數
    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = { // 按逆時針方向順序:
         0.0f,  0.622008459f, 0.0f,   // top
        -0.5f, -0.311004243f, 0.0f,   // bottom left
         0.5f, -0.311004243f, 0.0f    // bottom right
    };

    // 設置顏色,分別爲red, green, blue alpha (opacity)
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

    public Triangle() {
        // 存放形狀的座標,初始化頂點字節緩衝
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (座標數 * 4)float佔四字節
                triangleCoords.length * 4);
        // 設用設備的本點字節序
        bb.order(ByteOrder.nativeOrder());

        // ByteBuffer創建一個浮點緩衝
        vertexBuffer = bb.asFloatBuffer();
        // 把座標們加入FloatBuffer
        vertexBuffer.put(triangleCoords);
        // 設置buffer,從第一個座標開始讀
        vertexBuffer.position(0);
    }
}

缺省情況下,OpenGLES假定[0,0,0](X,Y,Z)GLSurfaceView 幀的中心,[1,1,0]是右上角,[-1,-1,0]是左下角。

注意此形狀的座標是按逆時針方向定義的。繪製順序很重要,因爲它定義了哪面是形狀的正面,哪面是反面,使用OpenGLEScullface特性,你可以只畫正面而不畫反面。

定義一個正方形


OpenGL中定義正方形是十分容易的,有很多方法能做的,但是典型的做法是使用兩個三角形:


1.使用兩個三角形畫一個正方形

你要爲兩個三角形都按逆時針方向定義頂點們,並且將這些座標值們放入一個ByteBuffer中。爲了避免分別爲兩個三角形定義兩個座標數組,我們使用一個繪製列表來告訴OpenGLES圖形管線如果畫這些頂點們。下面就是這個形狀的代碼:

class Square {

    private FloatBuffer vertexBuffer;
    private ShortBuffer drawListBuffer;

    // 每個頂點的座標數
    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                    -0.5f, -0.5f, 0.0f,   // bottom left
                                     0.5f, -0.5f, 0.0f,   // bottom right
                                     0.5f,  0.5f, 0.0f }; // top right

    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // 頂點的繪製順序

    public Square() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
        // (座標數 * 4)
                squareCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);

        // 爲繪製列表初始化字節緩衝
        ByteBuffer dlb = ByteBuffer.allocateDirect(
        // (對應順序的座標數 * 2)short2字節
                drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);
    }
}

本例讓你見識了用OpenGL如何創建更復雜的形狀。通常,你都是使用一羣小三(三角形)來繪製對象。下一章,你將學會如何將這些形狀畫到屏幕上。

上一講

下一講


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章