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

來源:互聯網
上載者:User

Android OpenGL ES繪圖教程之三 : 繪製圖形
在定義了將要被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圖形管線更加有趣。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.