乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android OpenGL基本結(jié)構(gòu)

       華 飛 鷹 2011-04-11

      android是用OpenGL來實現(xiàn)3d的。OpenGL的處理機制是把所有的數(shù)據(jù)都用代碼傳遞給opengl service,如果用戶(這里是應(yīng)用程序)想要畫什么東西,就用告訴opengl 什么東西是可用的,然后在開始畫。

      這個例子一共分三步:
      1."
      "一個3d的圖形(這里畫的是菱形),把它傳遞給opengl service 端,然后建立一個畫自己的方法。
      2.
      創(chuàng)建這個圖形運行的環(huán)境。
      3.
      把這個環(huán)境,加載到android 的界面上去。

      下面是具體的實現(xiàn)方法:
      首先需要建兩個array,第一array是用來告訴opengl這個圖形有哪些頂點:
      畫一個三維的坐標軸,然后把你要畫的點都算出來,然后放在這個array里。

      float l=1.5f;
      float[] vertex={

      0.0f,l,0.0f,

      l,0.0f,0.0f,

      0.0f,0.0f,l,

      -l,0.0f,0.0f,

      0.0f,0.0f,-l,

      0.0f,-l,0.0f

      };
      第二個array是告訴opengl 你要怎樣組織這些點:
      這里我要畫三角形,所以每三個點是一組。
      byte[] edge=

      {

      0,1,2,

      1,2,5,



      0,2,3,

      5,2,3,



      0,3,4,

      5,3,4,



      0,4,1,

      5,4,1

      };

      這里的數(shù)字,是第一個arrayindex。
      下面你要建立兩個Buffer它們是用來存放這兩個array的。


      ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length*4);

      bb.order(ByteOrder.nativeOrder());

      fbv=bb.asFloatBuffer();

      fbv.put(vertex);

      fbv.position(0);




      ffe=ByteBuffer.allocateDirect(edge.length);

      ffe.put(edge);

      ffe.position(0);
      這樣一個三維的菱形就畫好了。

      下面你要寫一個方法能讓它自己把自己畫出來!
      public void draw(GL10 gl)

      {

      gl.glFrontFace(GL10.GL_CW);

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fbv);

      gl.glDrawElements(GL10.GL_TRIANGLES, 24, GL10.GL_UNSIGNED_BYTE, ffe);

      }
      這幾句話費了我好大力氣去理解。
      先說第一個glFrontFace,物體都有一個正面一個反面,這里告訴opengl顯示這個物體按順時針方向(CW=> clockwise

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fbv);
      這個方法是把本程序所用的點都傳遞個opengl。opengl需要知道什么哪?首先是 這個點是幾維的(opengl 支持2,34 維),這里是3所以是三維的,第二個參數(shù)告訴opengl,這個點是用什么樣類型的變量來儲存的,這里是float類型。第三個是步長(stride), 這個我還沒弄明白,不過我看的例子都為0. 最后把你建立好的三維坐標點都傳給opengl

      gl.glDrawElements
      。 這個方法是告訴opengl如果要畫這個圖形,應(yīng)該怎么畫。第一個參數(shù),告訴opengl 用畫三角形(這樣opengl就以三個點為一組),然后告訴opengl你要用到多少個點(注意這個點是在第二個array里的點數(shù))。 第三個是告訴opengl這些點(其實是三維坐標點的reference)的類型。這里是unsigned byte。最后把你排列點的array 放進去!


      這樣一個三維的圖形就建立完成了!


      第二個大的步驟是創(chuàng)建一個讓這個三維坐標運行的環(huán)境(Renderer)。
      這是一個interface
      首先,在onDrawFrame里,我們告訴本程序這個三維圖形的行為:
      在做任何事情之前,我們要清空所有以前內(nèi)存里的東西,這個內(nèi)存包括:Color Depth
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
      然后告訴opengl你要用那個MatrixMode 這個就比較難解釋了。

      如果寫程序 只要記住 GL_MODELVIEW 是管理圖形的 縮放,移動,和轉(zhuǎn)動就行了.

      gl.glTranslatef(0, 0, -3.0f);
      這個方法告訴opengl把圖形沿z軸遷移3unit。這三個值分別是xy,z軸。
      gl.glRotatef(angle,0, 1, 0);
      這個方法告訴我們以y為軸。 轉(zhuǎn)angle個度數(shù)。注意這里的10是告訴沿著那個軸轉(zhuǎn),別的值應(yīng)該沒有意義。
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      還記得上邊說的openglclient sideservice side嗎。 這個是告訴opengl如果client side調(diào)用draw什么的時候,這個vertex array是可用的。opengl有很多這樣的可選項,所以需要告訴opengl,因為我們已經(jīng)設(shè)置了vertex array(我們的第一個array,所以告訴opengl 它是可用的(如果不告訴,opengl會忽略)!

      trian.draw(gl);
      這個方法是把圖形畫出來。

      angle++;
      為了達到動態(tài)的效果,我們讓每一個frame angle,比上一個多一度。

      當顯示空間大小發(fā)生變化的時候,我們應(yīng)該告訴opengl一下信息:

      public void onSurfaceChanged(GL10 gl, int width, int height) 

      {

      // TODO Auto-generated method stub

      gl.glViewport(0, 0, width, height);

      gl.glMatrixMode(GL10.GL_PROJECTION);

      gl.glLoadIdentity();

      float ratio = (float)width/height;

      gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);



      }
      首先是opengl可用的空間 
      gl.glViewport(0, 0, width, height);
      想象一下用這四個點畫出來的四邊形,就是opengl所能用的空間。

      gl.glMatrixMode(GL10.GL_PROJECTION);
      這個matrix是如何把三維坐標轉(zhuǎn)換為二維坐標并把它放在顯示器上。
      gl.glLoadIdentity
      是告訴opengl初始化這個matrix

      gl.glFrustumf
      要把三維的東西用二維顯示出來,需要知道幾個東西,第一是這個顯示平面有多大,你可以看多近和多遠。這里的頭四個參數(shù),建立了一個四邊形,告訴opengl把圖形顯示在這個范圍了。后兩個參數(shù)告訴opengl這里顯示平面里可以顯示三維空間里最近和最遠的位置。


      當這個三維圖形建立的是時候,我們可以告訴opengl一些基本參數(shù)。這里把能省略的都省略了(其實什么都沒有也可以運行?。?/span>
      public void onSurfaceCreated(GL10 gl, EGLConfig arg1) 

      {

      gl.glEnable(GL10.GL_DEPTH_TEST);

      gl.glClearColor(0,0, 0, 0);

      }

      gl.glEnable(GL10.GL_DEPTH_TEST); 
      告訴opengl要檢查depth,為什么哪。在三維空間里一個物體A在另一個物體B后面,那么這個AB擋住里,所以你是看不見的。我們要告訴 opengl,我們不想看見被擋住的東西。這個GL_DEPTH_TEST 就是這個功能。
      gl.glClearColor(0,0, 0, 0);
      設(shè)置這個背景顏色為黑色,應(yīng)為我們沒有給我們的三維圖形設(shè)置顏色(為了簡單),它的初始化顏色是白色。

      這樣這個環(huán)境就建立起來了!

      下面該把它放進,android里了
      public class Triangle extends Activity {
          /** Called when the activity is first created. */

      private GLSurfaceView my_view;
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);
              my_view = new GLSurfaceView(this);
              my_view.setRenderer(new MySimpleRendered());
              this.setContentView(my_view);
          }
          public void onResume()
          {
          
      super.onResume();
          
      my_view.onResume();
          }
          public void onPause()
          {
          
      super.onPause();
          
      my_view.onPause();
          }
      }

      這就是我的第一個3D例子。希望能給初學(xué)者一點點提示!

      源代碼:
      package Beta.ThreeD;

      import java.nio.ByteBuffer;
      import java.nio.ByteOrder;
      import java.nio.FloatBuffer;

      import javax.microedition.khronos.opengles.GL10;

      public class TriangleShape 
      {

      private final float l=1.5f;

      private FloatBuffer fbv;

      private ByteBuffer ffe;

      public TriangleShape()

      {

      float[] vertex={

      0.0f,l,0.0f,

      l,0.0f,0.0f,

      0.0f,0.0f,l,

      -l,0.0f,0.0f,

      0.0f,0.0f,-l,

      0.0f,-l,0.0f

      };


      byte[] edge=

      {

      0,1,2,

      1,2,5,



      0,2,3,

      5,2,3,



      0,3,4,

      5,3,4,



      0,4,1,

      5,4,1

      };

      ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length*4);

      bb.order(ByteOrder.nativeOrder());

      fbv=bb.asFloatBuffer();

      fbv.put(vertex);

      fbv.position(0);




      ffe=ByteBuffer.allocateDirect(edge.length);

      ffe.put(edge);

      ffe.position(0);

      }

      public void draw(GL10 gl)

      {

      gl.glFrontFace(GL10.GL_CW);

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fbv);

      gl.glDrawElements(GL10.GL_TRIANGLES, 24, GL10.GL_UNSIGNED_BYTE, ffe);

      }
      }


      package Beta.ThreeD;

      import javax.microedition.khronos.egl.EGLConfig;
      import javax.microedition.khronos.opengles.GL10;

      import android.opengl.GLSurfaceView.Renderer;

      public class MySimpleRendered implements Renderer
      {

      private int angle=50;

      private TriangleShape trian;

      public MySimpleRendered()

      {

      trian = new TriangleShape();

      }

      @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();

      gl.glTranslatef(0, 0, -3.0f);

      gl.glRotatef(angle,0, 1, 0);

      gl.glRotatef(angle, 1, 0, 0);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

      trian.draw(gl);

      angle++;

      }


      @Override

      public void onSurfaceChanged(GL10 gl, int width, int height) 

      {

      // TODO Auto-generated method stub

      gl.glViewport(0, 0, width, height);

      gl.glMatrixMode(GL10.GL_PROJECTION);

      gl.glLoadIdentity();

      float ratio = (float)width/height;

      gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);



      }


      @Override

      public void onSurfaceCreated(GL10 gl, EGLConfig arg1) 

      {

      gl.glEnable(GL10.GL_DEPTH_TEST);

      gl.glClearColor(0,0, 0, 0);

      }

      }
      package Beta.ThreeD;

      import android.app.Activity;
      import android.os.Bundle;
      import android.opengl.GLSurfaceView;
      public class Triangle extends Activity {
          /** Called when the activity is first created. */

      private GLSurfaceView my_view;
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);
              my_view = new GLSurfaceView(this);
              my_view.setRenderer(new MySimpleRendered());
              this.setContentView(my_view);
          }
          public void onResume()
          {
          
      super.onResume();
          
      my_view.onResume();
          }
          public void onPause()
          {
          
      super.onPause();
          
      my_view.onPause();
          }
      }

       

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多