編輯:關於Android編程
本文實例講述了Android基於OpenGL在GLSurfaceView上繪制三角形及使用投影和相機視圖方法。分享給大家供大家參考,具體如下:
定義三角形
OpenGL 允許我們使用三維坐標來定義物體。在繪制三角形前,我們需要定義它各個點的坐標。我們一般使用數組來存儲各個頂點的坐標。
OpenGL ES 默認 [0,0,0] (X,Y,Z) 在GLSurfaceView的中心,[1,1,0]在右上角,[-1,-1,0]在左下角。
繪制三角形
在繪制三角形之前,我們必須告訴OpenGL我們正在使用頂點數組。然後我們才使用繪制函數畫出三角形。
實驗步驟:
1. 添加新的類Triangle
代碼如下:
public class Triangle { public Triangle() { float triangleCoords[] = { // X, Y, Z 這是一個等邊三角形 -0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.559016994f, 0 }; // 初始化三角形的頂點緩存 ByteBuffer vbb = ByteBuffer.allocateDirect( // (# of coordinate values * 4 bytes per float) triangleCoords.length * 4); vbb.order(ByteOrder.nativeOrder());// 使用設備硬件本身的字節序 triangleVB = vbb.asFloatBuffer(); // 從ByteBuffer中創建一個浮點緩存 triangleVB.put(triangleCoords); // 向浮點緩存中添加頂點坐標 triangleVB.position(0); // 使緩存讀第一個坐標 } public void draw(GL10 gl) { gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f); //設置當前顏色 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);//設置頂點 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);//繪制三角形 } private FloatBuffer triangleVB; }
2. 在myGLRenderer類中添加成員privateTriangle mTriangle並在構造函數中初始化。
代碼如下:
public myGLRenderer() { mTriangle = new Triangle(); }
3. 在myGLRenderer類的onSurfaceCreated()函數最後添加glEnableClientState()方法來啟用頂點數組。
代碼如下:
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); }
4. 在myGLRenderer類的onDrawFrame()函數最後添加三角形繪制方法。
代碼如下:
@Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); mTriangle.draw(gl); }
這樣,我們便完成了一個平面三角形的繪制。但我們發現這個三角形並不像我們定義的那樣是一個等邊三角形,這是由於OpenGL總假設我們的屏幕是一個正方形,這樣在繪制的時候最終圖形會隨著屏幕長寬比例的不同而被拉伸。為了得到正確的顯示,我們需要將圖形投影到正確的位置。這一功能我們在下一節進行實現。
Android設備屏幕通常不是正方形的,而OpenGL總是默認地將正方形坐標系投影到這一設備上,這就導致圖形無法按真實比例顯示。要解決這一問題,我們可以使用OpenGL 的投影模式和相機視圖將圖形的坐標進行轉換以適應不同的設備顯示。
實驗步驟:
1. 修改myGLRenderer類的onSurfaceCreated()函數來啟用GL10.GL_PROJECTION模式,計算屏幕的長寬比並使用這一比例來轉換物體的坐標。
代碼如下:
@Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub gl.glViewport(0, 0, width, height); float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); // 設置當前矩陣為投影矩陣 gl.glLoadIdentity(); // 重置矩陣為初始值 gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // 根據長寬比設置投影矩陣 }
2. 修改myGLRenderer的onDrawFrame()方法,啟用MODELVIEW模式,並使用GLU.gluLookAt()來設置視點。
代碼如下:
@Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 設置當前矩陣為模型視圖模式 gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); // reset the matrix to its default state // 設置視點 GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); mTriangle.draw(gl); }
這樣,我們繪制的圖形比例就總是正確的,不再受設備的影響而被拉伸變形了。
更多關於Android相關內容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結》、《Android開發入門與進階教程》、《Android調試技巧與常見問題解決方法匯總》、《Android多媒體操作技巧匯總(音頻,視頻,錄音等)》、《Android基本組件用法總結》、《Android視圖View技巧總結》、《Android布局layout技巧總結》及《Android控件用法總結》
希望本文所述對大家Android程序設計有所幫助。
開發者都知道驗證表單裡的數據是令人厭煩而且容易出錯的,日期輸入框的驗證也是如此。我們可以開發出一個外觀看起來與EditText相同Button,點擊該Button後,會顯
前言Handler是Android消息機制的上層接口,平時使用起來很方便,我們可以通過它把一個任務切換到Handler所在的線程中去運行。而最常用的就是拿來從子線程切換到
寫在前面從事Android開發至今,一提及Android開發中使用的對話框就想起AlertDialog或者PopupWindow,我在上一篇博客中也總結了這兩種對話框的使
問題:橫豎屏切換時Activity的生命周期?測試環境:華為mate7 package com.virglass.beyond.activity;import