用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; }
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你想要畫什麼和這麼畫。畫的形狀不同參數也不同,在形狀類裏包含各自的繪製邏輯是個好主意。
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()方法就能看到以下結果。