Android OpenGL ES 應用(一)

來源:互聯網
上載者:User

Android OpenGL ES 應用(一)


OpenGL已經成了3D的一個"標準" 因為它能跨平台,介面也比較豐富,幾乎大部分的手機3D遊戲都和OpenGL有關係。

當然還有微軟有direct X 但只能在微軟平台上使用。

OpenGL底層是c/c++實現,JAVA中使用都是用封裝好的類庫。Android提供了以下幾個介面包 可使用,基本能達到3D技術的要求。

Android平台用OpenGL ES 這個子集來處理映像,現在OpenGL ES基本用2.0的了,很少再用1.0的,3.0還未流行起來。


首先編寫判斷Android裝置是否支援OpenGL 2.0.

GLHelper.java加入一個判斷是否支援2.0版本的代碼方法。

public static boolean enableOpenGL2(Activity act) {final ActivityManager mg = (ActivityManager) act.getSystemService(Context.ACTIVITY_SERVICE);ConfigurationInfo configuration = mg.getDeviceConfigurationInfo();boolean b = configuration.reqGlEsVersion >= 0x20000);return b;}

我們需要擴充 android.opengl.GLSurfaceView 這個類,讓映像繪製在SurfaceView上面,看看源碼發現這個類其實是擴充了SurfaceView做了寫封裝。


public class MyOpenGLView extends GLSurfaceView { //這個類就先空著,這一次沒有太多的代碼public MyOpenGLView(Context context) {super(context);}public MyOpenGLView(Context context, AttributeSet attrs) {super(context, attrs);}}


我們把處理的各種方法封裝一下。

public class GLData {public GLData() {}public static float[] singelTriangles = { //定義了2個三角形,組成了一個正方形,因為openGL ES只能是點,線和三角形-0.3f, -0.3f,  0.3f, 0.3f, -0.3f, 0.3f, -0.3f, -0.3f, 0.3f, -0.3f,  0.3f, 0.3f};}

OpenGL ES在Android的座標系是 [-1,1]的區間內




編寫2個簡單的頂點著色器和片段做色器。


<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">public class GLScript {public GLScript() {}public static final String vertex1 = "attribute vec4 mPosition;\n" +"void main()\n" +"{\n" +"gl_Position=mPosition;\n " +"}\n";public static final String fragment1 = "precision mediump float;\n" +"uniform vec4 mColor;\n" +"void main(){ gl_FragColor=mColor;\n}";}

vec4 mPosition 這個表示定義了一個4分量(x,y,z,w)的頂點,然後付給gl_Position 內建的變數中,OpenGL會編譯並且自動處理。
vec4 mColor 這個表示定義了一個顏色分量RGBA,最後一個是透明度,即是 紅綠藍.


指令碼語言是OpenGL ES的核心,很多的渲染效果都需要指令碼處理。

GLHelper.java添加編譯指令碼的代碼方法.

public static int compileScript(int type, String script){int objID  = GLES20.glCreateShader(type); //建立一個著色器對象,TYPE表示頂點著色器和片段著色器if (objID == 0) { //0表示有錯誤    return 0;}GLES20.glShaderSource(objID, script); //把指令碼代碼傳給OpenGL 引擎GLES20.glCompileShader(objID); //開始編譯int[] status = new int[1];GLES20.glGetShaderiv(objID, GLES20.GL_COMPILE_STATUS, status, 0); //看看編譯結果是否有錯誤。Log.d("OPENGL","compileScript status info:" + GLES20.glGetShaderInfoLog(objID));if (status[0] == 0) {GLES20.glDeleteShader(objID);//有錯誤我們刪除這個對象。Log.e("OPENGL", "Error Compile Script:" + script);return 0;}return objID;}


如果編譯成功我們開始關聯OpenGL ES程式。


public static int linkGL(){int programId = GLES20.glCreateProgram();//建立一個程式if (programId == 0) {   Log.e("OPENGL", "Error Create Link Program");   return 0;}return programId;}public static int linkAttach(int vertexsharder,int fragmentsharder){int programId = linkGL();GLES20.glAttachShader(programId, vertexsharder); //和著色器進行關聯GLES20.glAttachShader(programId, fragmentsharder);//和著色器進行關聯GLES20.glLinkProgram(programId); //把program連結起來int status[] = new int[1];GLES20.glGetProgramiv(programId, GLES20.GL_LINK_STATUS, status, 0); //這地方一樣是檢查是否有錯誤發生。Log.d("OPENGL","linkAttach link status is " + GLES20.glGetProgramInfoLog(programId));if (status[0] == 0) {Log.e("OPENGL","link status is error.");GLES20.glDeleteProgram(programId);return 0;}return programId;}


最後我們驗證程式是否有錯誤

public static boolean checkProgram(int programId){GLES20.glValidateProgram(programId);int status[] = new int[1];GLES20.glGetProgramiv(programId,GLES20.GL_VALIDATE_STATUS, status,0);if (status[0] == 0) {Log.e("OPENGL","program is error");return false;}return true;}

以上代碼都寫在 GLHelper.java中,

我們把代碼加入到渲染類中Renderer


渲染類

public class MyOpenGLRenderer implements Renderer {public static FloatBuffer verDataBuffer;int colorLocation ;int positionLocation ;public MyOpenGLRenderer() {// 申請直接記憶體空間,並使用native位元組序列verDataBuffer = ByteBuffer.allocateDirect(4 * GLData.singelTriangles.length).order(ByteOrder.nativeOrder()).asFloatBuffer();verDataBuffer.put(GLData.singelTriangles);  //這是一個正方形,等會貼代碼。}@Overridepublic void onDrawFrame(GL10 arg0) { //這個方法會不斷的重繪GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);GLES20.glUniform4f(colorLocation, 0f, 0f, 0F, 0f); //這裡是黑色,顏色將傳入給colorLocationGLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);//畫三角形,有6個頂點 所以從0,6開始}@Overridepublic void onSurfaceChanged(GL10 arg0, int w, int h) {GLES20.glViewport(0, 0, w, h);}@Overridepublic void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {GLES20.glClearColor(1F, 1F, 1F, 0.0F); //下面的代碼都是組織起來用我們編寫的GLHelper類.int vertexsharder = GLHelper.compileScript(GLES20.GL_VERTEX_SHADER, GLScript.vertex1);int fragmentsharder = GLHelper.compileScript(GLES20.GL_FRAGMENT_SHADER, GLScript.fragment1);int programId = GLHelper.linkAttach(vertexsharder, fragmentsharder);boolean isOK = GLHelper.checkProgram(programId);if (isOK) {Log.d("","start draw.............."); GLES20.glUseProgram(programId); //我們開始使用這個程式 colorLocation = GLES20.glGetUniformLocation(programId, "mColor");//獲得變數位置,可以理解為記憶體位址,OpenGL 將為在這個地址中取資料 positionLocation = GLES20.glGetAttribLocation(programId, "mPosition"); verDataBuffer.position(0);//資料開始端讀取 GLES20.glVertexAttribPointer(positionLocation, 2, GLES20.GL_FLOAT, false, 0, verDataBuffer);//這個地方把頂點資料與變數關聯起來 GLES20.glEnableVertexAttribArray(positionLocation);//這地方使得能夠使用頂點數組   }}}

最後Activity部分代碼.

private MyOpenGLView gLView;private boolean openGLEnable;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (GLHelper.enableOpenGL2(this)) {openGLEnable = true;}Log.d("","OpenGL is Enable:" + openGLEnable);gLView = new MyOpenGLView(this);gLView.setEGLContextClientVersion(2);//可以使用OpenGL ES 2.0gLView.setRenderer(new MyOpenGLRenderer());setContentView(gLView);}




運行結果很簡單就是中間一個正方形。

OpenGL ES入門相對還是比較複雜的,因為函數的調用和平時用的JAVA,, C++ 庫都不太一樣

3D的東西複雜不僅僅是多了一個座標Z,還有很多的渲染技術。


工程結構:




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.