Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android OpenGL ES繪圖教程之三 : 繪制圖形

Android OpenGL ES繪圖教程之三 : 繪制圖形

編輯:關於Android編程

在定義了將要被OpenGL繪制的形狀之後,你當然想要繪制它們。使用OpenGL ES 2.0繪制圖形需要的代碼可能比你想象的要多,因為API提供了大量的圖形渲染管道控制接口。
這一章將介紹如何使用OpenGL ES 2.0 API繪制上一章中定義的形狀
1. 初始化形狀
在你做任何的繪制操作之前,你都必須進行初始化和加載計劃繪制的形狀。除非在執行的過程中形狀所在的結構(原坐標)發生變化,你應該在render中的onSurfaceCreated()方法中初始化它們以提高內存和執行效率。
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
...

// initialize a triangle
mTriangle = new Triangle();
// initialize a square
mSquare = new Square();
}


2. 繪制形狀
使用OpenGL ES 2.0繪制定義的形狀需要大量的代碼,因為你必須給圖形渲染管線提供許多細節,特別是,你需要定義下面的細節:
Vertex Shader - OpenGL ES graphics code for rendering the vertices of a shape.
譯:頂點著色器 - 渲染形狀頂點的OpenGL ES圖形代碼
Fragment Shader - OpenGL ES code for rendering the face of a shape with colors or textures.
譯:片元著色器 - 使用顏色或者紋理渲染形狀表面的OpenGL ES圖形代碼
Program - An OpenGL ES object that contains the shaders you want to use for drawing one or more shapes.
譯:Program - 包含了用來繪制形狀的著色器的OpenGL ES對象
你至少需要一個頂點著色器來繪制形狀,一個片元著色器來對形狀著色。這些著色器必須被編譯和被添加到OpenGL ES程序中。下面是一個如何通過定義著色器來繪制圖形的例子:
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著色語言(GLSL)代碼,在OpenGL ES環境中使用之前必須被編譯,為了編譯這些代碼,在你的renderer類中創建一個方法:
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;
}


為了繪制圖形,你必須編譯著色器代碼,將它們添加到OpenGL ES編程對象中,鏈接程序,在繪制對象的構造方法中執行這些操作,所以只會執行一次。
注意:編譯OpenGL著色器和鏈接程序從CPU處理周期和時間來看消耗是比較昂貴的,所以你應該避免執行超過一次。如果你在運行時還不知道著色器的內容,你應該只在著色器被創建的時候編譯一次,然後緩存起來使用。
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繪圖需要指定一些參數來告訴渲染管線畫什麼和怎麼畫。因為繪圖選項可以通過形狀區分,所以讓你的shape類包含繪制邏輯是個不錯的方法。
創建draw()方法來進行繪制,下面的代碼設置了頂點著色器和片元著色器的position和color值,然後執行繪制方法。
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方法。下面是程序的執行效果:


\
這個代碼示例還有一些問題。首先它不會讓你的朋友印象深刻,其次當屏幕方向改變的時候形狀會改變,有點被壓扁。形狀被扭曲的原因是對象的頂點沒有跟著屏幕上GLSurfaceView展示的區域的比例進行修正,你可以使用下一節介紹的projection and camera view來修復這個問題。
最後,這個三角形是固定的,有點枯燥。在後面的課程中,你可以學習使這個形狀旋轉,使OpenGL ES圖形管線更加有趣。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved