Android開發之OpenGL ES 畫多邊形

來源:互聯網
上載者:User

  一、基礎知識:

  OpenGL ES目前只支援三角形,但任何多邊形都可拆分成多個三角形,所以無所謂這個限制的存在。

  1.OpenGL中的座標點:

  每一個座標點由(X, Y, Z)組成。

  定義一個三角形的頂點數組:

  [java]

  int one = 0x10000;

  //三角形三個頂點

  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{

  0,one,0, //上頂點

  -one,-one,0, //左下點

  one,-one,0,}); //右下點

  int one = 0x10000;

  //三角形三個頂點

  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{

  0,one,0, //上頂點

  -one,-one,0, //左下點

  one,-one,0,}); //右下點定義一個正方形的頂點數組:

  [java]

  //正方形的4個頂點

  private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{

  one,one,0,

  -one,one,0,

  one,-one,0,

  -one,-one,0});

  //正方形的4個頂點

  private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{

  one,one,0,

  -one,one,0,

  one,-one,0,

  -one,-one,0});

  2.OpenGL中的座標系:

  當調用gl.glLoadIdentity()函數之後,實際上是將當前點移動到了螢幕中心,

  X座標軸從左至右,Y座標軸從下至上,Z座標軸從裡至外。

  OpenGL螢幕中心的座標值是X軸和Y軸的0.0f點。

  中心左邊的座標值是負值,右邊是正值;

  移向螢幕頂端是正值,移向螢幕底端是負值;

  移入螢幕深處是負值,移出螢幕則是正值。

  在繪製時,我們可以使用glTranslatef函數來移動畫筆的位置,從而使圖形顯示在我們

  想要的位置。

  [java]

  gl.glTranslatef(-1.5f, 0.0f, -6.0f);

  gl.glTranslatef(-1.5f, 0.0f, -6.0f);此函數,就是將畫筆沿X軸左移1.5f個單位,Y軸保持不變,Z軸向螢幕裡面移動6.0f個單位。

  將視圖推入螢幕背後足夠的距離以便可以看見全部的情境,這裡需要注意的是螢幕內移動的單位

  必須小於我們前面通過glFrustumf方法設定的最遠距離,否則超出視角範圍,將顯示不出來。

  3.OpenGL中的頂點數組:

  在實際畫圖時,我們往往需要定位幾個點,然後讓OpenGL以此為基準來畫圖。在設定頂點位置前,

  我們需要按照以下步驟來啟用我們的頂點數組:

  ①開啟頂點設定動能:

  [java]

  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);②設定頂點數組:

  [java] view plaincopyprint?gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);

  gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);glVertexPointer(int size, int type, int stride, Buffer pointer)

  size用於描述頂點的尺寸(本例使用XYZ,所以是3),type描述頂點的類型,固定的使用

  GL_FIXED,stride描述步長,pointer指向頂點緩衝,即我們建立的頂點數組。

  ③繪製頂點:

  [java]

  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //繪製三角形

  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //繪製四邊形

  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //繪製三角形

  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //繪製四邊形glDrawArrays(int mode, int first, int count)

  mode指明繪製的模式,first和count分別是開始的位置和要繪製的頂點計數。

  4、執行個體: 畫一個三角形和正方形。

  根據我們上一節的架構分析,目前,我們只需將精力集中在onDrawFrame方法裡面的繪圖操作部分了。

  1. 介面編輯(reslayoutmain.xml):

  [java]

  

  android:orientation="vertical"

  android:layout_width="fill_parent"

  android:layout_height="fill_parent"

  >

  

  android:layout_width="fill_parent"

  android:layout_height="wrap_content"

  android:text="@string/hello"

  />

  

  

  android:orientation="vertical"

  android:layout_width="fill_parent"

  android:layout_height="fill_parent"

  >

  

  android:layout_width="fill_parent"

  android:layout_height="wrap_content"

  android:text="@string/hello"

  />

  

  2.代碼編輯

  (srcwyfzclMyActivity.java):

  [java]

  package wyf.zcl;

  import android.app.Activity;

  import android.opengl.GLSurfaceView;

  import android.opengl.GLSurfaceView.Renderer;

  import android.os.Bundle;

  public class Activity01 extends Activity

  {

  Renderer render = new GLRender();

  /** Called when the activity is first created. */

  @Override

  public void onCreate(Bundle savedInstanceState)

  {

  super.onCreate(savedInstanceState);

  GLSurfaceView glView = new GLSurfaceView(this);

  glView.setRenderer(render);

  setContentView(glView);

  }

  }

  package wyf.zcl;

  import android.app.Activity;

  import android.opengl.GLSurfaceView;

  import android.opengl.GLSurfaceView.Renderer;

  import android.os.Bundle;

  public class Activity01 extends Activity

  {

  Renderer render = new GLRender();

  /** Called when the activity is first created. */

  @Override

  public void onCreate(Bundle savedInstanceState)

  {

  super.onCreate(savedInstanceState);

  GLSurfaceView glView = new GLSurfaceView(this);

  glView.setRenderer(render);

  setContentView(glView);

  }

  }

  (srcwyfzclGLRender.java):

  [java]

  package wyf.zcl;

  import java.nio.IntBuffer;

  import javax.microedition.khronos.egl.EGLConfig;

  import javax.microedition.khronos.opengles.GL10;

  import android.opengl.GLSurfaceView.Renderer;

  public class GLRender implements Renderer

  {

  int one = 0x10000;

  //三角形三個頂點

  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{

  0,one,0, //上頂點

  -one,-one,0, //左下點

  one,-one,0,}); //右下點

  //正方形的4個頂點

  private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{

  one,one,0,

  -one,one,0,

  one,-one,0,

  -one,-one,0});

  @Override

  public void onDrawFrame(GL10 gl)

  {

  // 清除螢幕和深度緩衝

  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

  // 重設當前的模型觀察矩陣

  gl.glLoadIdentity();

  // 左移 1.5 單位,並移入螢幕 6.0

  gl.glTranslatef(-1.5f, 0.0f, -6.0f);

  // 允許設定頂點

  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

  // 設定三角形

  gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);

  //繪製三角形

  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

  // 重設當前的模型觀察矩陣

  gl.glLoadIdentity();

  // 左移 1.5 單位,並移入螢幕 6.0

  gl.glTranslatef(1.5f, 0.0f, -6.0f);

  //設定和繪製正方形

  gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);

  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

  // 取消頂點設定

  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

  }

  @Override

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

  {

  float ratio = (float) width / height;

  //設定OpenGL情境的大小

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

  //設定投影矩陣

  gl.glMatrixMode(GL10.GL_PROJECTION);

  //重設投影矩陣

  gl.glLoadIdentity();

  // 設定視口的大小

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

  // 選擇模型觀察矩陣

  gl.glMatrixMode(GL10.GL_MODELVIEW);

  // 重設模型觀察矩陣

  gl.glLoadIdentity();

  }

  @Override

  public void onSurfaceCreated(GL10 gl, EGLConfig config)

  {

  // 啟用陰影平滑

  gl.glShadeModel(GL10.GL_SMOOTH);

  // 黑色背景

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

  // 設定深度緩衝

  gl.glClearDepthf(1.0f);

  // 啟用深度測試

  gl.glEnable(GL10.GL_DEPTH_TEST);

  // 所作深度測試的類型

  gl.glDepthFunc(GL10.GL_LEQUAL);

  // 告訴系統對透視進行修正

  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

  }

  }

  package wyf.zcl;

  import java.nio.IntBuffer;

  import javax.microedition.khronos.egl.EGLConfig;

  import javax.microedition.khronos.opengles.GL10;

  import android.opengl.GLSurfaceView.Renderer;

  public class GLRender implements Renderer

  {

  int one = 0x10000;

  //三角形三個頂點

  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{

  0,one,0, //上頂點

  -one,-one,0, //左下點

  one,-one,0,}); //右下點

  //正方形的4個頂點

  private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{

  one,one,0,

  -one,one,0,

  one,-one,0,

  -one,-one,0});

  @Override

  public void onDrawFrame(GL10 gl)

  {

  // 清除螢幕和深度緩衝

  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

  // 重設當前的模型觀察矩陣

  gl.glLoadIdentity();

  // 左移 1.5 單位,並移入螢幕 6.0

  gl.glTranslatef(-1.5f, 0.0f, -6.0f);

  // 允許設定頂點

  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

  // 設定三角形

  gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);

  //繪製三角形

  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

  // 重設當前的模型觀察矩陣

  gl.glLoadIdentity();

  // 左移 1.5 單位,並移入螢幕 6.0

  gl.glTranslatef(1.5f, 0.0f, -6.0f);

  //設定和繪製正方形

  gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);

  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

  // 取消頂點設定

  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

  }

  @Override

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

  {

  float ratio = (float) width / height;

  //設定OpenGL情境的大小

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

  //設定投影矩陣

  gl.glMatrixMode(GL10.GL_PROJECTION);

  //重設投影矩陣

  gl.glLoadIdentity();

  // 設定視口的大小

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

  // 選擇模型觀察矩陣

  gl.glMatrixMode(GL10.GL_MODELVIEW);

  // 重設模型觀察矩陣

  gl.glLoadIdentity();

  }

  @Override

  public void onSurfaceCreated(GL10 gl, EGLConfig config)

  {

  // 啟用陰影平滑

  gl.glShadeModel(GL10.GL_SMOOTH);

  // 黑色背景

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

  // 設定深度緩衝

  gl.glClearDepthf(1.0f);

  // 啟用深度測試

  gl.glEnable(GL10.GL_DEPTH_TEST);

  // 所作深度測試的類型

  gl.glDepthFunc(GL10.GL_LEQUAL);

  // 告訴系統對透視進行修正

  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

  }

  }

  3.運行效果:

相關文章

聯繫我們

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