Android OpenGLes 3.0学习:顶点绘制法 VBOs

移动开发 Android
目前只有android系统中只有android 4.3或以上支持opengles 3.0,但目前很多运行android 4.3系统的硬件能支持opengles 3.0的也是非常少的。不过幸好,opengles 3.0是向后兼容的,当程序发现硬件不支持opengles 3.0时则会自动调用opengles 2.0的API。

目前只有android系统中只有android 4.3或以上支持opengles 3.0,但目前很多运行android 4.3系统的硬件能支持opengles 3.0的也是非常少的。不过幸好,opengles 3.0是向后兼容的,当程序发现硬件不支持opengles 3.0时则会自动调用opengles 2.0的API。废话不多说了,开始进入正题,

实现过程:

1、在manifest中声明程序中使用opengles 3.0

如果程序中使用了纹理压缩的话,还需进行如下声明,以防止不支持这些压缩格式的设备尝试运行程序。

2、实现两个必不可少的类:GLSurfaceView和GLSurfaceView.Renderer

继承GLSurfaceView类的MySurfaceView.java

java代码

package com.gl.gl30_vbos02; 
 
  import android.content.Context; 
  import android.opengl.GLSurfaceView; 
  import android.util.AttributeSet; 
  import android.view.MotionEvent; 
  public class MySurfaceView extends GLSurfaceView { 
  private final float TOUCH_SCALE_FACOTOR = 180.0f / 320
  private GLRender _render = new GLRender(); 
  private float _preX = 0.0f; 
  private float _preY = 0.0f; 
  public MySurfaceView(Context context) 
  { 
  super(context); 
  // TODO Auto-generated constructor stub 
  setEGLContextClientVersion(2); 
  this.setRenderer(_render); 
  setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 
  } 
  public MySurfaceView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  // TODO Auto-generated constructor stub 
  } 
  @Override 
  public boolean onTouchEvent(MotionEvent event) { 
  // TODO Auto-generated method stub 
  float x = event.getX(); 
  float y = event.getY(); 
  switch (event.getAction()) 
  { 
  case MotionEvent.ACTION_MOVE: 
  float dx = x - _preX; 
  float dy = y - _preY; 
  _render.zrot = dx * TOUCH_SCALE_FACOTOR; 
  _render.xrot = dy * TOUCH_SCALE_FACOTOR; 
  this.requestRender(); 
  break
  default
  break
  } 
  _preX = x; 
  _preY = y; 
  return true
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

实现GLSurfaceView.Renderer的GLRender.java:

java代码

package com.gl.gl30_vbos02; 
 
  import java.nio.FloatBuffer; 
  import javax.microedition.khronos.egl.EGLConfig; 
  import javax.microedition.khronos.opengles.GL10; 
  import android.opengl.GLES30; 
  import android.opengl.GLSurfaceView.Renderer; 
  import android.opengl.Matrix; 
  import android.util.Log; 
  //@TargetApi(18) 
  public class GLRender implements Renderer { 
  public float xrot, yrot, zrot; 
  private static final String TAG = "GLRender"
  private final float[] mProjMatrix = new float[16]; 
  private final float[] mVMatrix = new float[16]; 
  private final float[] mMVPMatrix = new float[16]; 
  private final float[] mRotationMatrix = new float[16]; 
  // private volatile float mAngle; 
  private CirclePlane _circlePlane; 
  //定义环境光 
  private FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f, 0.5f, 
0.5f, 1.0f}); 
  //定义漫散射 
  private FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f, 1.0f, 
1.0f, 1.0f}); 
  //光源的位置 
  private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f, 
0.0f, 2.0f, 1.0f}); 
  public GLRender() { 
  // TODO Auto-generated constructor stub 
  } 
  @Override 
  public void onDrawFrame(GL10 gl_unused) { 
  // TODO Auto-generated method stub 
  //清楚屏幕和深度缓存 
  GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | 
GLES30.GL_DEPTH_BUFFER_BIT); 
  Matrix.setLookAtM(mVMatrix, 000, -30.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
0.0f); 
  Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 
  this._circlePlane.Draw(mMVPMatrix); 
  } 
  @Override 
  public void onSurfaceChanged(GL10 gl_unused, int width, int height) { 
  // TODO Auto-generated method stub 
  float ratio = (float) width / height; 
  //设置OPENGL视口 
  GLES30.glViewport(00, width, height); 
  //设置矩阵投影参数 
  Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1137); 
  } 
  @Override 
  public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
  // TODO Auto-generated method stub 
  //black background 
  GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
  this._circlePlane = new CirclePlane(10201.0f); 
  } 
  public static int loadShader(int type, String shaderCode) 
  { 
  // create a shader type (GLES30.GL_VERTEX_SHADER) 
  // or a fragment shader type (GLES30.GL_FRAGMENT_SHADER) 
  int shader = GLES30.glCreateShader(type); 
  GLES30.glShaderSource(shader, shaderCode); 
  GLES30.glCompileShader(shader); 
  return shader; 
  } 
  public static void checkGLError(String glOperation) 
  { 
  int error; 
  while((error = GLES30.glGetError()) != (GLES30.GL_NO_ERROR)) 
  { 
  Log.e(TAG, glOperation + ": glError " + error); 
  throw new RuntimeException(glOperation + ": glError " + error); 
  } 
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.

要完成Opengl es工程,最重要是实现上面两个类。另外本程序为了绘制出图中的图案,还有四个类,可在附件中查看。:

CirclePlane.java //实现图案中顶点缓存,这个类有比较多的数学知识,不过只为了实现图案的话,不用理解其中数学算法问题也没关系。只要修改此类就可以绘制出不同的图案

Vertex3f.java //定义了顶点类型

Until.java //生成顶点缓存的公共工具类

OpenGLES30.java //工程的主类

附录

CirclePlane.java

java代码

package com.gl.gl30_vbos02; 
 
  import java.nio.FloatBuffer; 
  import android.opengl.GLES30; 
  //@TargetApi(18) 
  public class CirclePlane { 
  static final int COORDS_PRE_VERTEX = 3
  private final int vertexStride = COORDS_PRE_VERTEX * 4
  private int vertexCount = 0
  private int mRow = 10
  private int mColumn = 20
  private float mRadius = 1.0f; 
  private FloatBuffer mPlaneBuffer; 
  private final int mProgram; 
  private int mPositionHandle; 
  private int mColorHandle; 
  private int mMVPMatrixHandle; 
  // Set color with red, green, blue and alpha (opacity) values 
  float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //白色不透明 
  private final String vertexShaderCode = 
  "uniform mat4 uMVPMatrix;" + 
  "attribute vec4 vPosition;" + 
  "void main()" + 
  "{" + 
  " gl_Position = vPosition * uMVPMatrix;" + 
  "}"
  private final String fragmentShaderCode = 
  "precision mediump float;" + 
  "uniform vec4 vColor;" + 
  "void main()" + 
  "{" + 
  " gl_FragColor = vColor;" + 
  "}"
  public CirclePlane(int row, int column, float radius) 
  { 
  // TODO Auto-generated constructor stub 
  this.mRow = row; 
  this.mColumn = column; 
  this.mRadius = radius; 
  this.createGraphics(); 
  int vertexShader = GLRender.loadShader(GLES30.GL_VERTEX_SHADER, 
vertexShaderCode); 
  int fragmentShader = GLRender.loadShader(GLES30.GL_FRAGMENT_SHADER, 
fragmentShaderCode); 
  this.mProgram = GLES30.glCreateProgram(); // create empty OpenGL 
Program 
  GLES30.glAttachShader(this.mProgram, vertexShader); // add the vertex 
shader to program 
  GLES30.glAttachShader(this.mProgram, fragmentShader); // add the fragment 
shader to program 
  GLES30.glLinkProgram(this.mProgram); // create OpenGL program 
executables 
  } 
  private void createGraphics() 
  { 
  Vertex3f vertexs[][] = new Vertex3f[this.mRow][this.mColumn]; 
  float intervalR = this.mRadius / this.mRow; 
  Vertex3f centralPos = new Vertex3f(0.0f, 0.0f, 0.0f); 
  for(int i=0;i 
  { 
  float tmpR = intervalR * i; 
  for(int j=0;j 
  { 
  double angle = 2 * j * Math.PI / (this.mColumn - 1); 
  vertexs[i][j] = new Vertex3f((float)(tmpR * Math.cos(angle)), (float)(tmpR 
* Math.sin(angle)), centralPos.z); 
  } 
  } 
  //创建三角形顶点 
  int len = 2 * (this.mRow -1) * (this.mColumn - 1) * 3
  this.vertexCount = len; 
  Vertex3f tri[] = new Vertex3f[len]; 
  int index = 0
  for(int i=0;i 
  { 
  for(int j=0;j 
  { 
  tri[index] = vertexs[i][j]; 
  tri[index+1] = vertexs[i+1][j]; 
  tri[index+2] = vertexs[i+1][j+1]; 
  tri[index+3] = vertexs[i][j]; 
  tri[index+4] = vertexs[i+1][j+1]; 
  tri[index+5] = vertexs[i+1][j]; 
  index += 6
  } 
  } 
  //设置顶点缓存 
  float[] plane = new float[len*3]; 
  for(int i=0;i 
  { 
  int vertexI = 3 * i; 
  plane[vertexI] = tri[i].x; 
  plane[vertexI+1] = tri[i].y; 
  plane[vertexI+2] = tri[i].z; 
  } 
  this.mPlaneBuffer = Util.getFloatBuffer(plane); 
  // plane = null; 
  } 
  public void Draw(float[] mvpMatrix) 
  { 
  GLES30.glUseProgram(this.mProgram); 
  this.mPositionHandle = GLES30.glGetAttribLocation(this.mProgram, 
"vPosition"); 
  GLES30.glEnableVertexAttribArray(this.mPositionHandle); 
  GLES30.glVertexAttribPointer(this.mPositionHandle, COORDS_PRE_VERTEX, 
  GLES30.GL_FLOAT, falsethis.vertexStride, this.mPlaneBuffer); 
  this.mColorHandle = GLES30.glGetUniformLocation(this.mProgram, 
"vColor"); 
  GLES30.glUniform4fv(this.mColorHandle, 1this.color, 0); 
  this.mMVPMatrixHandle = GLES30.glGetUniformLocation(this.mProgram, 
"uMVPMatrix"); 
  GLRender.checkGLError("glGetUniformLocation"); 
  GLES30.glUniformMatrix4fv(this.mMVPMatrixHandle, 1false, mvpMatrix, 
0); 
  GLRender.checkGLError("glUniformMatrix4fv"); 
  GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0this.vertexCount); 
  GLES30.glDisableVertexAttribArray(this.mPositionHandle); 
  // gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
  // gl.glVertexPointer(3, GL10.GL_FLOAT, 0, this.mPlaneBuffer); 
  // gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 
(this.mRow-1)*(this.mColumn-1)*2*3); 
  // 
  // gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
  // gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
  // gl.glFinish(); 
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.

Vertex3f.java

java代码

package com.gl.gl30_vbos02; 
 
  public class Vertex3f { 
  public float x = 0.0f; 
  public float y = 0.0f; 
  public float z = 0.0f; 
  public Vertex3f(float x, float y, float z) 
  { 
  this.x = x; 
  this.y = y; 
  this.z = z; 
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Until.java

java代码

package com.gl.gl30_vbos02; 
 
  import java.nio.ByteBuffer; 
  import java.nio.ByteOrder; 
  import java.nio.FloatBuffer; 
  import java.nio.IntBuffer; 
  public class Util { 
  //获取整形缓冲数据 
  public static IntBuffer getIntBuffer(int[] vertexs) 
  { 
  IntBuffer buffer; 
  ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 4); 
  qbb.order(ByteOrder.nativeOrder()); 
  buffer = qbb.asIntBuffer(); 
  buffer.put(vertexs); 
  buffer.position(0); 
  return buffer; 
  } 
  //获取浮点形缓冲数据 
  public static FloatBuffer getFloatBuffer(float[] vertexs) 
  { 
  FloatBuffer buffer; 
  ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 4); 
  qbb.order(ByteOrder.nativeOrder()); 
  buffer = qbb.asFloatBuffer(); 
  buffer.put(vertexs); 
  buffer.position(0); 
  return buffer; 
  } 
  //获取字节型缓冲数据 
  public static ByteBuffer getByteBuffer(byte[] vertexs) 
  { 
  ByteBuffer buffer = null
  buffer = ByteBuffer.allocateDirect(vertexs.length); 
  buffer.put(vertexs); 
  buffer.position(0); 
  return buffer; 
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

OpenGLES30.java

java代码

package com.gl.gl30_vbos02; 
 
  import android.opengl.GLSurfaceView; 
  import android.os.Bundle; 
  import android.app.Activity; 
  import android.view.Menu; 
  public class OpenGLES30 extends Activity { 
  private GLSurfaceView mGL30View; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  mGL30View = new MySurfaceView(this); 
  setContentView(mGL30View); 
  } 
  @Override 
  public boolean onCreateOptionsMenu(Menu menu) { 
  // Inflate the menu; this adds items to the action bar if it is 
present. 
  getMenuInflater().inflate(R.menu.open_gles30, menu); 
  return true
  } 
  @Override 
  protected void onResume() { 
  // TODO Auto-generated method stub 
  super.onResume(); 
  this.mGL30View.onResume(); 
  } 
  @Override 
  protected void onPause() { 
  // TODO Auto-generated method stub 
  super.onPause(); 
  this.mGL30View.onPause(); 
  } 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

原文:http://bbs.9ria.com/thread-260180-1-1.html

责任编辑:闫佳明 来源: bbs.9ria
相关推荐

2013-04-15 14:23:21

2013-04-26 11:17:48

2013-07-25 09:32:26

OpenGL ESAndroid4.3

2009-11-27 12:02:56

IT运维

2010-10-13 14:35:14

Android 3.0

2011-04-14 17:36:15

Android 3.0iPad佩奇

2011-02-03 10:10:49

Android3.0Android谷歌

2019-08-05 13:20:35

Android绘制代码

2020-08-25 09:50:35

Vue3.0命令前端

2011-01-28 10:14:59

Android 3.0

2011-02-13 11:37:45

Android 3.0

2024-12-19 07:51:50

NacosAPI 接口三方调用

2011-04-28 10:35:51

上网本东芝REGZA Table

2010-10-20 08:53:57

Android 3.0

2011-02-15 13:45:43

Android 3.0

2011-04-04 11:53:05

索尼平板电脑Android 3.0

2011-01-13 13:48:52

Android 3.0

2013-04-26 10:26:08

2014-04-29 14:27:59

OpenGL ES 2Android绘制纹理

2010-12-24 11:08:47

蜂巢Android 3.0
点赞
收藏

51CTO技术栈公众号