AndroidOpenGLes3.0学习:顶点绘制法VBOs

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

10多年的都兰网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整都兰建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“都兰网站设计”,“都兰网站推广”以来,每个客户项目都认真落实执行。

实现过程:

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

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

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

继承GLSurfaceView类的MySurfaceView.java

java代码

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

实现GLSurfaceView.Renderer的GLRender.java:

java代码

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

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

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

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

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

OpenGLES30.java //工程的主类

附录

CirclePlane.java

java代码

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

Vertex3f.java

java代码

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

Until.java

java代码

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

OpenGLES30.java

java代码

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

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

文章题目:AndroidOpenGLes3.0学习:顶点绘制法VBOs
网址分享:http://www.mswzjz.com/qtweb/news26/200176.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联