編輯:關於Android編程
原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html
在定義了圖形之後,你接下來需要做的就是將它繪制到屏幕上。不過使用OpenGL ES 2.0 API來繪制這個圖形所需要的代碼量可能要比想象中的多一些,這是因為API為圖形渲染管道提供了大量的控制細節。
這節課會展示如何繪制上節課所定義的圖形。
在開始任何繪制之前,你必須先初始化並加載這個圖形。除非是在執行的過程中圖形的結構發生了改變。這個時候你應該在渲染器的onSurfaceCreated()方法中去初始化它們,這樣可以使內存和進程的效率提升。
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
private Triangle mTriangle;
private Square mSquare;
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
...
// initialize a triangle
mTriangle = new Triangle();
// initialize a square
mSquare = new Square();
}
...
}
繪制自定義圖形需要大量的代碼,因為你必須給圖形渲染管道提供大量的渲染細節。尤其是下面這些必須定義:
Vertex Shader - 圖形頂點的渲染. Fragment Shader - 圖形表面的顏色或紋理的渲染。 Program - 一個含有多個渲染器的OpenGL ES對象,可以用它來繪制一個或者多個圖形。你需要至少一個頂點渲染器來繪制圖形,並需要一個表面渲染器來為圖形著色。這些渲染器首先必須是可執行的,然後才能將其添加到OpenGL ES程序中,這時才能被用來繪制圖形。下面定義了一個最基本的可以用來繪制圖形的渲染器:
public class Triangle {
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渲染語言代碼,這些代碼必須先在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;
}
為了可以繪制圖形,必須先編譯這些渲染器代碼,然後再將其添加到OpenGL程序中,最後再鏈接到程序中。需要將這些工作放入繪制對象的構造方法中,所以這些工作只用做一次。
Note: OpenGL ES的編譯與鏈接過程需要消耗較高的CPU資源與時間,所以你應該避免這些工作做多次。如果在程序運行之前不知道渲染器的代碼,應該確保這部分的構建代碼只會執行一次,並需要將其緩存下來以便稍後使用。
public class Triangle() {
...
private final int mProgram;
public Triangle() {
...
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
}
}
這時就可以真正的開始繪制了。圖形的繪制需要提供若干的參數來告訴渲染管道想要繪制什麼及如何繪制。因為繪制選項可以定義多種多樣的圖形形式,所以可以自定義一個擁有獨立繪制邏輯的類來繪制各種圖形。
創建一個draw()方法開始繪制這個圖形。這部分代碼將會為頂點渲染器設置位置數據,並為表面渲染器設置顏色數據。然後開始執行繪制功能。
private int mPositionHandle;
private int mColorHandle;
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
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);
}
一旦完成以上所有的代碼,最後只需要調用一下draw()方法就可以開始繪制了:
public void onDrawFrame(GL10 unused) {
...
mTriangle.draw();
}
當程序啟動之後,設備上就會出現以下圖形:
vcfQzrvh09DSu7XjsbvRubHitcS40L71oaPV4srH0vLOqtTa0P3XqrXEyrG68qOstPrC69bQy/m2qNLltcS2pbXjtcTP4LbUzrvWw7G70bnL9cHLoaPV4tCpzsrM4r2ru+HU2s/Cvdq/zrXDtb294r72oaM8L3A+DQo8cD7X7rrzo6zV4sj9vcfQzsrHucy2qLK7seS1xKOs1eK74dPQ0KnIw8jL09DQqbK7y6y1xLjQvvWho9TaPGEgaHJlZj0="http://android.xsoftlab.net/training/graphics/opengl/motion.html">Adding Motion的課程中將會使這個圖形可以隨著手勢旋轉而旋轉,還可以通過渲染管道做到其它更多有意思的事情。
在中國找到錢不難,但你的一個點子不意味著是一個創業。你談一個再好的想法,比如我今天談一個創意說,新浪為什麼不收購GOOGLE呢?這個創意很好。新浪一收購GOOGLE,是
關於布局動畫是針對ViewGroup而言的,意指ViewGroup在增加子View或者刪除子View時其子View的過渡動畫,在android官網有這麼一個簡單的例子,其
在android開發中,經常用到去解析xml文件,常見的解析xml的方式有一下三種:SAX、Pull、Dom解析方式。最近做了一個android版的CSDN閱讀器,用到了
一、申請你的AppIDhttp://open.weixin.qq.com/ 友情提示:推薦使用eclipse打包軟件最後一步的MD5值去申請AppID二、官網