久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

OpenGL ES基礎(chǔ)教程

 昵稱3554661 2014-08-12


一,、設(shè)置OpenGL ES視圖
設(shè)置OpenGL視圖并不難,,Android上也較簡單。我們一般只需要2個步驟,。
GLSurfaceView
我們要為GLSurfaceView提供一個專門用于渲染的接口
public void  setRenderer(GLSurfaceView.Renderer renderer)

GLSurfaceView.Renderer
GLSurfaceView.Renderer是一個通用渲染接口,。我們必須實現(xiàn)下面的三個抽象方法:
// 畫面創(chuàng)建
public void onSurfaceCreated(GL10 gl, EGLConfig config)
// 畫面繪制
public void onDrawFrame(GL10 gl)
// 畫面改變
public void onSurfaceChanged(GL10 gl, int width, int height)
onSurfaceCreated
在這里我們主要進行一些初始化工作,比如對透視進行修正,、設(shè)置清屏所用顏色等,。
onDrawFrame
繪制當(dāng)前畫面
onSurfaceChanged
當(dāng)設(shè)備水平或者垂直變化時調(diào)用此方法,,設(shè)置新的顯示比例

案例代碼:

  1. public class OpenGLDemo extends Activity {
  2.     @Override
  3.     public void onCreate(Bundle savedInstanceState) {
  4.         GLSurfaceView view = new GLSurfaceView(this);
  5.         view.setRenderer(new OpenGLRenderer());
  6.         setContentView(view);
  7.     }
  8. }
復(fù)制代碼
實現(xiàn)renderer需要更多的設(shè)置

  1.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  2.         // 黑色背景
  3.         gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
  4.         // 啟用陰影平滑(不是必須的)
  5.         gl.glShadeModel(GL10.GL_SMOOTH);
  6.         // 設(shè)置深度緩存
  7.         gl.glClearDepthf(1.0f);
  8.         // 啟用深度測試
  9.         gl.glEnable(GL10.GL_DEPTH_TEST);
  10.         // 所作深度測試的類型
  11.         gl.glDepthFunc(GL10.GL_LEQUAL);
  12.         // 對透視進行修正
  13.         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
  14.     }

  15.     public void onDrawFrame(GL10 gl) {
  16.         // 清除屏幕和深度緩存
  17.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  18.     }

  19.     public void onSurfaceChanged(GL10 gl, int width, int height) {
  20.         // 設(shè)置畫面的大小
  21.         gl.glViewport(0, 0, width, height);
  22.         // 設(shè)置投影矩陣
  23.         gl.glMatrixMode(GL10.GL_PROJECTION);
  24.         // 重置投影矩陣
  25.         gl.glLoadIdentity();
  26.         // 設(shè)置畫面比例
  27.         GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,100.0f);
  28.         // 選擇模型觀察矩陣
  29.         gl.glMatrixMode(GL10.GL_MODELVIEW);
  30.         // 重置模型觀察矩陣
  31.         gl.glLoadIdentity();
  32.     }
  33. }
復(fù)制代碼
只要加入這段代碼到OpenGLDemo class里就可實現(xiàn)全屏this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
設(shè)置完視圖后,即可編譯運行,,可以看到一個“漂亮”的黑屏 = =,!



OpenGLDemo01.rar (48.38 KB, 下載次數(shù): 102)

二、繪制多邊形前面的教程都是關(guān)于設(shè)置GLSurfaceView.的,,接下來的教程將教我們渲染出一個多邊形,。3D模型用較小的元素創(chuàng)建(點,邊,,面),,他們可以被分別操作。
頂點

  

   在Android中,,我們通過float數(shù)組定義頂點,,并將它放到字節(jié)型緩沖區(qū)內(nèi)來獲取更好的性能。下例的代碼即為上圖所示頂點,。OpenGL ES的很多功能都必須手動的開啟和關(guān)閉,。
  1. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  2. // 設(shè)置頂點數(shù)據(jù),3代表XYZ坐標(biāo)系
  3. gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  4. // 關(guān)閉頂點設(shè)置
  5. gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
復(fù)制代碼



     




計算多邊形面的時候,,一定要注意正確的方向.,。因為這將決定哪一面為正面哪一面為背面。 所以我們盡量保證整個項目都使用相同的環(huán)繞,。gl.glFrontFace(GL10.GL_CCW);控制多邊形的正面是如何決定的,。在默認(rèn)情況下,mode是GL_CCW,。mode的值為:   GL_CCW 表示窗口坐標(biāo)上投影多邊形的頂點順序為逆時針方向的表面為正面,。   GL_CW 表示頂點順序為順時針方向的表面為正面。頂點的方向又稱為環(huán)繞,。gl.glEnable(GL10.GL_CULL_FACE);gl.glCullFace(GL10.GL_BACK);剔除多邊形的背面,,禁用多邊形背面上的光照、陰影和顏色計算及操作,。gl.glDisable(GL10.GL_CULL_FACE);  
多邊形



   


到了繪制面的時候了,, 我們使用默認(rèn)的逆時針環(huán)繞。下例代碼將繪制上圖多邊形,。
  1.     // 將坐標(biāo)數(shù)組放入字節(jié)緩存中
  2.     // (1) 分配緩存,,一個short為2個字節(jié),所以要乘以2
  3.     ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
  4.     // (2) 設(shè)置字節(jié)處理規(guī)則
  5.     ibb.order(ByteOrder.nativeOrder());
  6.     // (3) 轉(zhuǎn)換為short型字符
  7.     ShortBuffer indexBuffer = ibb.asShortBuffer();
  8.     // (4) 放入坐標(biāo)數(shù)組
  9.     indexBuffer.put(indices);
  10.     // (5) 復(fù)位
  11.     indexBuffer.position(0);
復(fù)制代碼
渲染是時候弄些玩意兒到屏幕上去了,,繪制時我們將用到兩個函數(shù)public abstract void glDrawArrays(int mode, int first, int count)通過我們構(gòu)造的頂點緩存來繪制頂點public abstract void glDrawElements(int mode, int count, int type, Buffer indices)和glDrawArrays類似,,但需要直接傳入type(索引值的類型,如GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT),和indices(索引緩存)兩者的共同點是,,都必須知道他們需要畫什么,。怎樣渲染圖元,有不同方式,,為了幫助調(diào)試,我們應(yīng)該了解它們,。
ModeGL_POINTS繪制獨立的點到屏幕  

  
GL_LINE_STRIP連續(xù)的連線,,第n個頂點與第n-1個頂點繪制一條直線  
  
GL_LINE_LOOP和上面相同,但首尾相連  
  
GL_LINES各對獨立的線段  
  
GL_TRIANGLES各個獨立的三角形  

GL_TRIANGLE_STRIP
繪制一系列的三角形,,先是頂點 v0, v1, v2, 然后是 v2, v1, v3 (注意規(guī)律), 然后v2, v3, v4等,。該規(guī)律確保所有的三角形都以相同的方向繪制。

  
GL_TRIANGLE_FAN和GL_TRIANGLE_STRIP類似, 但其先繪制 v0, v1, v2, 再是 v0, v2, v3, 然后 v0, v3, v4等,。   
我認(rèn)為GL_TRIANGLES是使用最方便的,,所以我們將先使用它。
  1. public class Square {
  2.     // 頂點坐標(biāo)數(shù)組
  3.     private float vertices[] = { -1.0f, 1.0f, 0.0f, // 0, 左上
  4.         -1.0f, -1.0f, 0.0f, // 1, 左下
  5.         1.0f, -1.0f, 0.0f, // 2, 右下
  6.         1.0f, 1.0f, 0.0f, // 3, 右上
  7.     };
  8.     // 連接規(guī)則
  9.     private short[] indices = { 0, 1, 2, 0, 2, 3 };
  10.     // 頂點緩存
  11.     private FloatBuffer vertexBuffer;
  12.     // 索引緩存
  13.     private ShortBuffer indexBuffer;


  14.     public Square() {
  15.         // 一個float為4 bytes, 因此要乘以4
  16.         ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  17.         vbb.order(ByteOrder.nativeOrder());
  18.         vertexBuffer = vbb.asFloatBuffer();
  19.         vertexBuffer.put(vertices);
  20.         vertexBuffer.position(0);
  21.         // short類型同理
  22.         ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
  23.         ibb.order(ByteOrder.nativeOrder());
  24.         indexBuffer = ibb.asShortBuffer();
  25.         indexBuffer.put(indices);
  26.         indexBuffer.position(0);
  27.         }

  28.     /**
  29.      * 繪制正方形到屏幕
  30.      *
  31.      * @param gl
  32.      */
  33.     public void draw(GL10 gl) {
  34.         // 逆時針環(huán)繞
  35.         gl.glFrontFace(GL10.GL_CCW);
  36.         // 開啟剔除功能
  37.         gl.glEnable(GL10.GL_CULL_FACE);
  38.         // 剔除背面
  39.         gl.glCullFace(GL10.GL_BACK);
  40.         // 開啟頂點緩存寫入功能
  41.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  42.         // 設(shè)置頂點
  43.         // size:每個頂點有幾個數(shù)指描述,。
  44.         // type:數(shù)組中每個頂點的坐標(biāo)類型,。
  45.         // stride:數(shù)組中每個頂點間的間隔,步長(字節(jié)位移),。
  46.         // pointer:存儲著每個頂點的坐標(biāo)值,。初始值為0
  47.         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  48.         gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
  49.         GL10.GL_UNSIGNED_SHORT, indexBuffer);
  50.         // 關(guān)閉各個功能
  51.         gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  52.         gl.glDisable(GL10.GL_CULL_FACE);
  53.     }
  54. }
復(fù)制代碼
我們必須在OpenGLRenderer類中初始化square
  1. square = new Square();<!--EndFragment-->
復(fù)制代碼
并在主繪制方法中調(diào)用square的繪制方法
  1. public void onDrawFrame(GL10 gl) {
  2.     // 清除屏幕和深度緩存
  3.     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  4.     // 繪制正方形
  5.     square.draw(gl);
  6. }
復(fù)制代碼
如果你現(xiàn)在運行應(yīng)用,我們又看到了華麗的黑屏,,為什么,?因為OpenGL ES渲染默認(rèn)的當(dāng)前位置為(0,0,0),窗口的定位也一樣,。而且OpenGL ES不渲染太靠近窗體定位的東西,。解決方法就是移動繪制的位置。
  1. gl.glTranslatef(0, 0, -4);  <!--EndFragment-->
復(fù)制代碼
再次運行應(yīng)用你將看到該正方形已經(jīng)被繪制,,但是它好像離我們越來越遠(yuǎn)一樣,,最后消失了。OpenGL ES不會在畫面之間復(fù)位繪制點,,所以我們要自己完成,。
  1. // 重置當(dāng)前的模型觀察矩陣
  2. gl.glLoadIdentity();<!--EndFragment-->
復(fù)制代碼
現(xiàn)在,我們運行應(yīng)用將會看到一個固定位置的正方形,。









    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多