Android上对OpenGl的支持是无缝的,所以才有众多3D效果如此逼真的游戏,在Camera的一些流程中也有用到GLSurfaceView的情况。本文记录OpenGL在Android上的入门级示例,绘制一个三角形和正方形。尽管功能简单,可是我捣腾了好几个晚上,大量网上文章上的代码都有点问题,不是绘制不出来就是挂了。

第一个文件:MainActivity.java

  1. package com.example.opentest;
  2.  
  3. import android.opengl.GLSurfaceView;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.view.Menu;
  7.  
  8. public class MainActivity extends Activity {
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. GLSurfaceView glSurfaceView = new GLSurfaceView(this);
  14. glSurfaceView.setRenderer(new OpenGLRender());
  15. setContentView(glSurfaceView);
  16. //setContentView(R.layout.activity_main);
  17.  
  18. }
  19.  
  20. @Override
  21. public boolean onCreateOptionsMenu(Menu menu) {
  22. // Inflate the menu; this adds items to the action bar if it is present.
  23. getMenuInflater().inflate(R.menu.main, menu);
  24. return true;
  25. }
  26.  
  27. }

第二个文件:BufferUtil.java 负责将数组转成buffer

  1. package com.example.opentest;
  2.  
  3. import java.nio.ByteBuffer;
  4. import java.nio.ByteOrder;
  5. import java.nio.FloatBuffer;
  6. import java.nio.IntBuffer;
  7.  
  8. public class BufferUtil {
  9. public static FloatBuffer mBuffer;
  10. public static FloatBuffer floatToBuffer(float[] a){
  11. //先初始化buffer,数组的长度*4,因为一个float占4个字节
  12. ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*);
  13. //数组排序用nativeOrder
  14. mbb.order(ByteOrder.nativeOrder());
  15. mBuffer = mbb.asFloatBuffer();
  16. mBuffer.put(a);
  17. mBuffer.position();
  18. return mBuffer;
  19. }
  20.  
  21. public static IntBuffer intToBuffer(int[] a){
  22.  
  23. IntBuffer intBuffer;
  24. //先初始化buffer,数组的长度*4,因为一个float占4个字节
  25. ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*);
  26. //数组排序用nativeOrder
  27. mbb.order(ByteOrder.nativeOrder());
  28. intBuffer = mbb.asIntBuffer();
  29. intBuffer.put(a);
  30. intBuffer.position();
  31. return intBuffer;
  32. }
  33. }

第三个文件:OpenGLRender.java 这是最为核心的,负责给配套的GLSurfaceView绘制东西

  1. package com.example.opentest;
  2.  
  3. import java.nio.FloatBuffer;
  4. import javax.microedition.khronos.egl.EGLConfig;
  5. import javax.microedition.khronos.opengles.GL10;
  6. import android.opengl.GLSurfaceView.Renderer;
  7.  
  8. public class OpenGLRender implements Renderer {
  9.  
  10. private float[] mTriangleArray = {
  11. 0f,1f,0f,
  12. -1f,-1f,0f,
  13. 1f,-1f,0f
  14. };
  15. private FloatBuffer mTriangleBuffer;
  16.  
  17. private float[] mColorArray={
  18. 1f,0f,0f,1f, //红
  19. 0f,1f,0f,1f, //绿
  20. 0f,0f,1f,1f //蓝
  21. };
  22. private FloatBuffer mColorBuffer;
  23.  
  24. //正方形的四个顶点
  25. private FloatBuffer quateBuffer ;
  26. private float[] mQuateArray = {
  27. -1f, -1f, 0f,
  28. 1f, -1f, 0f,
  29. -1f, 1f, 0f,
  30. 1f, 1f, 0f,
  31. };
  32.  
  33. @Override
  34. public void onDrawFrame(GL10 gl) {
  35. // TODO Auto-generated method stub
  36. gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
  37. //使用数组作为颜色
  38. gl.glColorPointer(, GL10.GL_FLOAT, , mColorBuffer);
  39.  
  40. //绘制小三角形
  41. gl.glLoadIdentity();
  42. gl.glTranslatef(-1.5f, 0.0f, -6.0f);
  43. gl.glVertexPointer(, GL10.GL_FLOAT, , mTriangleBuffer);//数组指向三角形顶点buffer
  44. gl.glDrawArrays(GL10.GL_TRIANGLES, , );
  45. // gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
  46. gl.glFinish();
  47.  
  48. //绘制正方形
  49. gl.glLoadIdentity();
  50. gl.glTranslatef(1.5f, 0.0f, -6.0f);
  51. // gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  52. gl.glVertexPointer(, GL10.GL_FLOAT, , quateBuffer);
  53. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, , );
  54. gl.glFinish();
  55.  
  56. }
  57.  
  58. @Override
  59. public void onSurfaceChanged(GL10 gl, int w, int h) {
  60. // TODO Auto-generated method stub
  61. gl.glViewport(, , w, h);
  62.  
  63. float ratio = (float) w / h;
  64. gl.glMatrixMode(GL10.GL_PROJECTION);
  65. gl.glLoadIdentity();
  66. gl.glFrustumf(-ratio, ratio, -, , , );
  67. gl.glMatrixMode(GL10.GL_MODELVIEW);
  68. gl.glLoadIdentity();
  69. }
  70.  
  71. @Override
  72. public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  73. // TODO Auto-generated method stub
  74. gl.glShadeModel(GL10.GL_SMOOTH);
  75. gl.glClearColor(1.0f, 1.0f, 1.0f, 0f);
  76. gl.glClearDepthf(1.0f);
  77. gl.glEnable(GL10.GL_DEPTH_TEST);
  78. gl.glDepthFunc(GL10.GL_LEQUAL);
  79. gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
  80. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  81. gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
  82.  
  83. mTriangleBuffer = BufferUtil.floatToBuffer(mTriangleArray);
  84. mColorBuffer = BufferUtil.floatToBuffer(mColorArray);
  85. quateBuffer = BufferUtil.floatToBuffer(mQuateArray);
  86.  
  87. }
  88.  
  89. }

开发要点:

1、GLSurfaceView可以直接new,也可以放到布局里,本例用的是第一种方法。

2、一个GLSurfaceView要配套一个Renderer,这个Renderer是一个接口,里面有三个函数。这点跟Surfaceview很像。尤其是其中的onDrawFrame()可以类比为Android里View的onDraw()函数。

3、绘制的主题在onDrawFrame()函数里,使用以下代码绘制三角形:

  1. //绘制小三角形
  2. gl.glLoadIdentity();
  3. gl.glTranslatef(-1.5f, 0.0f, -6.0f);
  4. gl.glVertexPointer(, GL10.GL_FLOAT, , mTriangleBuffer);//数组指向三角形顶点
  5. buffergl.glDrawArrays(GL10.GL_TRIANGLES, , );
  6. // gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
  7. gl.glFinish();

需要注意的是,在一些教程上写着绘制完后要gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 清除所设的顶点,这是个错误!一旦调用此句,则什么画不出来了!!!

然后再绘制正方形:

  1. //绘制正方形
  2. gl.glLoadIdentity();
  3. gl.glTranslatef(1.5f, 0.0f, -6.0f);
  4. // gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  5. gl.glVertexPointer(, GL10.GL_FLOAT, , quateBuffer);
  6. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, , );
  7. gl.glFinish();

注意绘制三角形之前已经加载了Color:gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);

如果在绘制完后调用gl.glDisableClientState(GL10.GL_COLOR_ARRAY);的话可以看到三角形一闪而过,正方形都看不到了。这块也是个误解!如果后面通过gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);再次指定颜色,可以看到会以此颜色绘制三角形和正方形。 总而言之,这个onDrawFrame()和View的onDraw()很像,在onDraw里不给paint设颜色,就画。或者画完后,又给颜色设成透明了,结果肯定也是啥都看不到。不明白为啥这么多教程上在绘制完小三角形后非要带:

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

这两句bug!!!

关于代码本身涉及的流程就不解释了,参考链接里说的很清楚。

4、如果正方形四个顶点坐标顺序更换后,画出来的将不是正方形。

源码链接:http://download.csdn.net/detail/yanzi1225627/7484793

参考: 链接1 链接2

效果图如下所示:

Android OpenGL 入门示例----绘制三角形和正方形的更多相关文章

  1. Linux OpenGL 实践篇-3 绘制三角形

    本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...

  2. iOS OpenGL ES简单绘制三角形

    OpenGL 是用于2D/3D图形编程的一套基于C语言的统一接口. windows,Linux,Unix上均可兼容. OpenGL ES 是在OpenGL嵌入式设备上的版本, android/iOS ...

  3. Android OpenGL ES(七)基本几何图形定义 .

    在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...

  4. Android OpenGL ES(十)绘制三角形Triangle .

    三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, - ...

  5. Android OpenGL ES 开发教程 从入门到精通

    感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...

  6. Android OpenGL ES(八)绘制点Point ..

    上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...

  7. Android OpenGL ES(十一)绘制一个20面体 .

    前面介绍了OpenGL ES所有能够绘制的基本图形,点,线段和三角形.其它所有复杂的2D或3D图形都是由这些基本图形构成. 本例介绍如何使用三角形构造一个正20面体.一个正20面体,有12个顶点,20 ...

  8. android openGL ES2 一切从绘制纹理開始

    纹理.在openGL中,能够理解为载入到显卡显存中的图片.Android设备在2.2開始支持openGL ES2.0.从前都是ES1.0 和 ES1.1的版本号.简单来说,openGL ES是为了嵌入 ...

  9. Android OpenGL ES 开发:绘制图形

    OpenGL 绘制图形步骤 上一篇介绍了 OpenGL 的相关概念,今天来实际操作,使用 OpenGL 绘制出图形,对其过程有一个初步的了解. OpenGL 绘制图形主要概括成以下几个步骤: 创建程序 ...

随机推荐

  1. NSURLConnection基本使用

    一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSURL对象,请求方法.请求头.请求体.... ...

  2. 3、Hibernate三态间的转换

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  3. 自己写deque

    //deque /* what is a deque? In Chinese, it's called "双端队列". It's different from a queue. I ...

  4. delphi 集合的用法

    http://blog.sina.com.cn/s/blog_9e2e8405010180jy.html delphi基础补充     1 开域语句     在面向对象的程序代码中,嵌套对象的现象十分 ...

  5. 一步一步学EF系列【6、IOC 之AutoFac】

    前言 之前的前5篇作为EF方面的基础篇,后面我们将使用MVC+EF 并且使用IOC ,Repository,UnitOfWork,DbContext来整体来学习.因为后面要用到IOC,所以本篇先单独先 ...

  6. javascript焦点图(根据图片下方的小框自动播放)

    html和css就不详细说明了,也是简单布局,通过定位把跟随图片的小框,定位到图片下方 <!DOCTYPE html> <html> <head> <meta ...

  7. 关于echarts使用的各种问题

    此文为作者辛苦编写,如有转发,请注明出处,谢谢 首先引入js文件,这是动态引入 <script src="http://echarts.baidu.com/build/dist/ech ...

  8. 总结一下C++各个版本之间的功能扩充

    活到老,学到老.   C++ 98 我们学习和教材中常见的. C++ 03 主要是对98版本进行了bug修复. C++ 11 引入的新功能请参见:         http://www.cpluspl ...

  9. js移动端tap事件封装

    这几天做项目,发现移动端需要触摸事件,而click肯定是不行的,于是我对tap事件封装进行了搜索,找到了一篇文章,原文地址如下:http://www.jb51.net/article/50663.ht ...

  10. 使用HttpClient工具类测试Http接口

    一.httpClient模拟客户端 import java.util.ArrayList;import java.util.Iterator;import java.util.List;import ...