本文讲述使用GLSurfaceView创建一个3D旋转的图形
代码1:OpenGLESActivity.java
public class OpenGLESActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 如果本设备支持OpenGl ES 2.0 if (IsSupported()) { // 先建GLSurfaceView实例 glSurfaceView = new GLSurfaceView(this); // 创建渲染器实例 MyRenderer mRenderer = new MyRenderer(); // 设置渲染器 glSurfaceView.setRenderer(mRenderer); // 显示SurfaceView setContentView(glSurfaceView); }else{ Toast.makeText(OpenGLESActivity.this,"此设备不支持OpenGL ES 2.0!",Toast.LENGTH_LONG).show(); } } /** * 当前设备是否支持OpenGL ES 2.0 * */ private boolean IsSupported() { ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000 ||(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86"))); return supportsEs2; } /** * GLSurfaceView.Renderer实现类 * */ public class MyRenderer implements GLSurfaceView.Renderer { /** * 1.定义立方体的8个顶点 * */ float[] cubeVertices = { //左面 -0.5f,0.5f,0.5f, -0.5f,-0.5f,0.5f, -0.5f,0.5f,-0.5f, -0.5f,-0.5f,-0.5f, //右面 0.5f, 0.5f,0.5f, 0.5f,-0.5f,0.5f, 0.5f,-0.5f,-0.5f, 0.5f,0.5f,-0.5f , //前面 -0.5f,0.5f,0.5f, -0.5f,-0.5f,0.5f, 0.5f,-0.5f,0.5f, 0.5f, 0.5f,0.5f, //后面 0.5f,-0.5f,-0.5f, 0.5f,0.5f,-0.5f, -0.5f,0.5f,-0.5f, -0.5f,-0.5f,-0.5f, //上面 -0.5f,0.5f,0.5f, 0.5f, 0.5f,0.5f, 0.5f,0.5f,-0.5f, -0.5f,0.5f,-0.5f, //下面 -0.5f,-0.5f,0.5f, 0.5f,-0.5f,0.5f, 0.5f,-0.5f,-0.5f, -0.5f,-0.5f,-0.5f }; /** * 2.各个位置对应的颜色数组 * */ float [] cubeColors = { 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, 1f,0f,0f,1f , 0f,1f,0f,1f, 0f,0f,1f,1f, 1f,0f,0f,1f, }; /** * 索引数组 * */ private short[] indices={ 0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23, }; private float rotate;// 控制旋转的角度 private FloatBuffer VerticesBuffer;//浮点形缓冲数据 private FloatBuffer Colorbuffer;//浮点型颜色数据 private ShortBuffer indexbuffer;//浮点型索引数据 public MyRenderer() { //获取浮点形缓冲数据 VerticesBuffer = Utils.getFloatBuffer(cubeVertices); //获取浮点型颜色数据 Colorbuffer= Utils.getFloatBuffer(cubeColors); //获取浮点型索引数据 indexbuffer= Utils.getShortBuffer(indices); } /** * onSurfaceCreated方法 Surface创建的时候调用 * */ @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glClearColor(0, 0, 0, 0); } /** * onSurfaceChanged方法 Surface改变的的时候调用 * */ @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // 设置3D视窗的大小及位置 gl.glViewport(0, 0, width, height); } /** * onDrawFrame方法 在Surface上绘制的时候调用 * */ @Override public void onDrawFrame(GL10 gl) { // 清除屏幕缓存和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 启用顶点座标数据 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 启用顶点颜色数据 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); // 重置当前的模型视图矩阵 gl.glLoadIdentity(); // 沿着Y轴旋转 gl.glRotatef(rotate, 0f, 1f, 0f); // 设置顶点的位置数据 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VerticesBuffer); // 设置顶点的颜色数据 gl.glColorPointer(4, GL10.GL_FLOAT, 0, Colorbuffer); //绘制三角形 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexbuffer); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); // 旋转角度增加1 rotate-=1; } } /** * onPause方法 glSurfaceView.onPause * */ @Override protected void onPause() { super.onPause(); if (glSurfaceView != null) { glSurfaceView.onPause(); } } /** * onResume方法 glSurfaceView.onResume * */ @Override protected void onResume() { super.onResume(); if (glSurfaceView != null) { glSurfaceView.onResume(); } }
}
代码2:Utils.java
public class Utils { /** * 获取浮点形缓冲数据 float 数组 */ 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; } /** * 获取字节型缓冲数据 Byte 数组 */ public static ShortBuffer getShortBuffer(short[] vertexs) { ShortBuffer buffer; ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 2); qbb.order(ByteOrder.nativeOrder()); buffer = qbb.asShortBuffer(); buffer.put(vertexs); buffer.position(0); return buffer; }
}
运行结果: