1. 程式人生 > >Android 平臺下OpenGL繪製立方體(1)

Android 平臺下OpenGL繪製立方體(1)

寫在文前的話

回顧Opengl繪製圖形的開發步驟

1.新建自己的View 實現 GLSurfaceView
2.初始化著色器Render

1)設定Opengl 版本 非必需
2)設定著色器
3)設定渲染模式
4)實現 onSurfaceCreated
4.1)設定背景
4.2)開啟深度測試
4.3)複雜圖形的物件的例項化
5)實現onSurfaceChanged
5.1)設定視口
5.2)設定投影矩陣
5.3)設定相機
6)實現onDrawFrame

本文的一些說明

本文 用到了著色器語言 暫時 暫時先這樣用 以後會 介紹書寫和使用

圖形類的實現

抽出部分功能方法 形成抽象類Utils

Utils 實現

/**
* 本次畫的是 立方體
* 以下設定 頂點資料
* 注意 頂點資料的順序
*
* 頂點的 順序依次是 (數字代表的是 頂點索引)
* 正面 左上 0 左下 1 右下2 右上3
* 反面 左上4 左下5 右下6 右上7
*
* 注意 OpenGl中沒有四邊形的繪製 所以 我們採用三角形繪製
* 這裡的定點數順序 不是唯一的 之所要注意 是因為 我們畫矩形是用兩個三角形實現
* 這裡的注意是 畫三角形使用頂點資料的時候 方向要一致
*
* 例如畫 正面的時候 如果第一個三角形使用 032頂點 那麼下個三角形必須是021
* 這裡的每個面的三角形的繪製 可以是任何一個 該面上的頂點 但是 一旦定下 頂點順序 那麼該面繪製下一個的時候順序要保持一致
* 在例如 後面 後面的索引是 4567 你可以選擇任何一個開始 例如 674 那麼下一個 必須是645
*
* 這裡在 普及一下 座標知識 立方體中心是(0,0,0);
* 這裡我們畫一個正方體 為了計算方便 設定 邊長為2
* x軸 為順平向右 y軸 豎直向上 z軸 垂直螢幕 向外
*/

public float[] cubePositions = {
        -1.0f, 1.0f, 1.0f,    //正面左上0
        -1.0f, -1.0f, 1.0f,   //正面左下1
        1.0f, -1.0f, 1.0f,    //正面右下2
        1.0f, 1.0f, 1.0f,     //正面右上3
        -1.0f, 1.0f, -1.0f,    //反面左上4
        -1.0f, -1.0f, -1.0f,   //反面左下5
        1.0f, -1.0f, -1.0f,    //反面右下6
        1.0f, 1.0f, -1.0f,     //反面右上7
};

/**
 * 因為一個面要有兩個三角形 所以 一個面要有6個頂點
 * 六個面 共有36個(實際上 就有8個頂點 這裡為了畫三角形 重複用了一些頂點)
 * 以下是頂點索引
 */
public short index[] = {
        6, 7, 4, 6, 4, 5,    //後面
        6, 3, 7, 6, 2, 3,    //右面
        6, 5, 1, 6, 1, 2,    //下面
        0, 3, 2, 0, 2, 1,    //正面
        0, 1, 5, 0, 5, 4,    //左面
        0, 7, 3, 0, 4, 7,    //上面
};

給頂點設定顏色八個頂點 8 個顏色

 顏色排列:RGB A

public float color[] = {

        1f, 1f, 1f, 1f,
        0f, 1f, 0f, 1f,
        1f, 1f, 0f, 1f,
        1f, 0f, 1f, 1f,
        0f, 0f, 1f, 1f,
        0f, 0f, 0.5f, 1f,
        1f, 1f, 1f, 1f,
        0.5f, 0f, 0f, 1f,
};

/**
 * @Effect 頂點著色器;
 */
public final String vertexShaderCode =
        "attribute vec4 vPosition;" +//宣告一個用attribute修飾的變數(頂點)
                "uniform mat4 vMatrix;" +//總變換矩陣
                "varying  vec4 vColor;" +//顏色易變變數(成對出現)
                "attribute vec4 aColor;" +//宣告一個用attribute修飾的變數(顏色)
                "void main() {" +
                "  gl_Position = vMatrix*vPosition;" +//根據總變換的矩陣計算繪製此頂點的位置
                "  vColor=aColor;" + //將接收的顏色傳遞給片元著色器
                "}";
/**
 * @Effect 片段著色器;
 */
public final String fragmentShaderCode =

// 片元語言沒有預設浮點精度修飾符
// 因此,對於浮點數,浮點數向量和矩陣變數宣告,
// 要麼宣告必須包含一個精度修飾符,要麼不預設精度修飾符在之前 已經被宣告過。
“precision mediump float;” +//預定義的全域性預設精度
“varying vec4 vColor;” +//接收從頂點著色器過來的引數
“void main() {” +
” gl_FragColor = vColor;” + //給此片源顏色值
“}”;

/**
 * @param shaderType(著色器型別,頂點和片元);
 * @param shaderCode(著色器程式碼);
 * @return 返回著色器物件
 * @Effect 載入Shader的方法;
 */
public int loadShader(int shaderType, String shaderCode) {
    //根據type建立頂點著色器或者片元著色器
    int shader = GLES20.glCreateShader(shaderType);
    //將資源加入到著色器中,並編譯
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);
    return shader;
}


/**
 * @param ver_Tex(陣列,一般為頂點資料);
 * @return Float型緩衝
 * @Effect 獲取FloatBuffer資料緩衝;
 */
public FloatBuffer getFloatBuffer(float ver_Tex[]) {
    //建立頂點座標資料緩衝
    // vc.length*4是因為一個整數四個位元組
    ByteBuffer bb = ByteBuffer.allocateDirect(ver_Tex.length * 4);
    //設定位元組順序
    // 由於不同平臺位元組順序不同資料單元不是位元組的一定要經過ByteBuffer轉換
    bb.order(ByteOrder.nativeOrder());
    //轉換為Float型緩衝
    FloatBuffer vertexBuffer = bb.asFloatBuffer();
    //向緩衝區中放入頂點座標資料
    vertexBuffer.put(ver_Tex);
    //設定緩衝區起始位置
    vertexBuffer.position(0);
    return vertexBuffer;
}

/**
 * @param index(這個是繪製頂點的索引陣列);
 * @return Short型緩衝
 * @Effect 獲取ShortBuffer資料緩衝;
 */
public ShortBuffer getShortBuffer(short index[]) {
    ByteBuffer cc = BcateDirect(index.length * 2);
    cc.order(ByteOrder.nativeOrder());
    ShortBuffer indexBuffer =    cc.asShortBuffer();
    indexBuffer.put(index);
    indexBuffer.position(0);
    return indexBuffer;
}

圖形類