OpenGL繪製形狀

用OpenGL繪製有可能需要跟多的代碼,因爲API提供了許多對graphics渲染管道的控制。

一、初始化形狀

在繪製之前,需要初始化和加載想要畫的形狀。除非執行過程中形狀的初始座標改變,否則都要在哦你Surf二測Created()中初始化他們。

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    ...

    // initialize a triangle
    mTriangle = new Triangle();
    // initialize a square
    mSquare = new Square();
}
二、畫形狀

爲graphics rendering pipeline提供詳細信息,需要定義以下

Vertex Shader vertex頂點渲染,形狀頂點的渲染

Fragment Shader渲染形狀的一個面的顏色和質地

Program繪製一個或者多個形狀的多個着色器

要畫一個形狀,至少需要一個vertex shader來畫形狀和一個fragment shader來染色,這些着色器必須被編譯然後加入到一個OpenGL ES program中,用來畫一個形狀。下面是怎麼樣畫一個形狀。

private final String vertexShaderCode =
    "attribute vec4 vPosition;" +
    "void main() {" +
    "  gl_Position = vPosition;" +
    "}";

private final String fragmentShaderCode =
    "precision mediump float;" +
    "uniform vec4 vColor;" +
    "void main() {" +
    "  gl_FragColor = vColor;" +
    "}";
着色器包含了OpenGL Shading Language(GLSL)語言用在OpenGL ES環境的配置中。爲了編譯這段代碼,創建一個工具類在渲染類中。

public static int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}
爲了能繪製圖形,要編譯shader code,將他們加入到OpenGL ES program object鏈接program,在drawn object的構造器中完成,確保只執行一次。
public class Triangle() {
    ...

    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables
}
到這,基本可以調用來畫形狀。用OpenGL ES畫畫形狀需要設置幾個參數告訴rendering pipeline你想要畫什麼和這麼畫。畫的形狀不同參數也不同,在形狀類裏包含各自的繪製邏輯是個好主意。
爲形狀創建一個draw()方法,設置形狀的vertex shader和fragment shader的位置和顏色值,然後執行繪製功能。
public void draw() {
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}
完成以上工作,在渲染器Renderer的onDrawFrame()方法裏調用draw()方法就能看到以下結果。

但是會有問題,當改變屏幕的方向時,形狀會發生抖動,原因是形狀的頂點沒有正確的比例。

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