Android OpenGL 入门示例----绘制三角形和正方形
Android上对OpenGl的支持是无缝的,所以才有众多3D效果如此逼真的游戏,在Camera的一些流程中也有用到GLSurfaceView的情况。本文记录OpenGL在Android上的入门级示例,绘制一个三角形和正方形。尽管功能简单,可是我捣腾了好几个晚上,大量网上文章上的代码都有点问题,不是绘制不出来就是挂了。
第一个文件:MainActivity.java
- package com.example.opentest;
- import android.opengl.GLSurfaceView;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- GLSurfaceView glSurfaceView = new GLSurfaceView(this);
- glSurfaceView.setRenderer(new OpenGLRender());
- setContentView(glSurfaceView);
- //setContentView(R.layout.activity_main);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
第二个文件:BufferUtil.java 负责将数组转成buffer
- package com.example.opentest;
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.FloatBuffer;
- import java.nio.IntBuffer;
- public class BufferUtil {
- public static FloatBuffer mBuffer;
- public static FloatBuffer floatToBuffer(float[] a){
- //先初始化buffer,数组的长度*4,因为一个float占4个字节
- ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*);
- //数组排序用nativeOrder
- mbb.order(ByteOrder.nativeOrder());
- mBuffer = mbb.asFloatBuffer();
- mBuffer.put(a);
- mBuffer.position();
- return mBuffer;
- }
- public static IntBuffer intToBuffer(int[] a){
- IntBuffer intBuffer;
- //先初始化buffer,数组的长度*4,因为一个float占4个字节
- ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*);
- //数组排序用nativeOrder
- mbb.order(ByteOrder.nativeOrder());
- intBuffer = mbb.asIntBuffer();
- intBuffer.put(a);
- intBuffer.position();
- return intBuffer;
- }
- }
第三个文件:OpenGLRender.java 这是最为核心的,负责给配套的GLSurfaceView绘制东西
- package com.example.opentest;
- import java.nio.FloatBuffer;
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
- import android.opengl.GLSurfaceView.Renderer;
- public class OpenGLRender implements Renderer {
- private float[] mTriangleArray = {
- 0f,1f,0f,
- -1f,-1f,0f,
- 1f,-1f,0f
- };
- private FloatBuffer mTriangleBuffer;
- private float[] mColorArray={
- 1f,0f,0f,1f, //红
- 0f,1f,0f,1f, //绿
- 0f,0f,1f,1f //蓝
- };
- private FloatBuffer mColorBuffer;
- //正方形的四个顶点
- private FloatBuffer quateBuffer ;
- private float[] mQuateArray = {
- -1f, -1f, 0f,
- 1f, -1f, 0f,
- -1f, 1f, 0f,
- 1f, 1f, 0f,
- };
- @Override
- public void onDrawFrame(GL10 gl) {
- // TODO Auto-generated method stub
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
- //使用数组作为颜色
- gl.glColorPointer(, GL10.GL_FLOAT, , mColorBuffer);
- //绘制小三角形
- gl.glLoadIdentity();
- gl.glTranslatef(-1.5f, 0.0f, -6.0f);
- gl.glVertexPointer(, GL10.GL_FLOAT, , mTriangleBuffer);//数组指向三角形顶点buffer
- gl.glDrawArrays(GL10.GL_TRIANGLES, , );
- // gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
- gl.glFinish();
- //绘制正方形
- gl.glLoadIdentity();
- gl.glTranslatef(1.5f, 0.0f, -6.0f);
- // gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
- gl.glVertexPointer(, GL10.GL_FLOAT, , quateBuffer);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, , );
- gl.glFinish();
- }
- @Override
- public void onSurfaceChanged(GL10 gl, int w, int h) {
- // TODO Auto-generated method stub
- gl.glViewport(, , w, h);
- float ratio = (float) w / h;
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- gl.glFrustumf(-ratio, ratio, -, , , );
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
- }
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- // TODO Auto-generated method stub
- gl.glShadeModel(GL10.GL_SMOOTH);
- gl.glClearColor(1.0f, 1.0f, 1.0f, 0f);
- gl.glClearDepthf(1.0f);
- gl.glEnable(GL10.GL_DEPTH_TEST);
- gl.glDepthFunc(GL10.GL_LEQUAL);
- gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
- mTriangleBuffer = BufferUtil.floatToBuffer(mTriangleArray);
- mColorBuffer = BufferUtil.floatToBuffer(mColorArray);
- quateBuffer = BufferUtil.floatToBuffer(mQuateArray);
- }
- }
开发要点:
1、GLSurfaceView可以直接new,也可以放到布局里,本例用的是第一种方法。
2、一个GLSurfaceView要配套一个Renderer,这个Renderer是一个接口,里面有三个函数。这点跟Surfaceview很像。尤其是其中的onDrawFrame()可以类比为Android里View的onDraw()函数。
3、绘制的主题在onDrawFrame()函数里,使用以下代码绘制三角形:
- //绘制小三角形
- gl.glLoadIdentity();
- gl.glTranslatef(-1.5f, 0.0f, -6.0f);
- gl.glVertexPointer(, GL10.GL_FLOAT, , mTriangleBuffer);//数组指向三角形顶点
- buffergl.glDrawArrays(GL10.GL_TRIANGLES, , );
- // gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
- gl.glFinish();
需要注意的是,在一些教程上写着绘制完后要gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 清除所设的顶点,这是个错误!一旦调用此句,则什么画不出来了!!!
然后再绘制正方形:
- //绘制正方形
- gl.glLoadIdentity();
- gl.glTranslatef(1.5f, 0.0f, -6.0f);
- // gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
- gl.glVertexPointer(, GL10.GL_FLOAT, , quateBuffer);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, , );
- 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
效果图如下所示:
Android OpenGL 入门示例----绘制三角形和正方形的更多相关文章
- Linux OpenGL 实践篇-3 绘制三角形
本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...
- iOS OpenGL ES简单绘制三角形
OpenGL 是用于2D/3D图形编程的一套基于C语言的统一接口. windows,Linux,Unix上均可兼容. OpenGL ES 是在OpenGL嵌入式设备上的版本, android/iOS ...
- Android OpenGL ES(七)基本几何图形定义 .
在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...
- Android OpenGL ES(十)绘制三角形Triangle .
三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, - ...
- Android OpenGL ES 开发教程 从入门到精通
感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...
- Android OpenGL ES(八)绘制点Point ..
上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...
- Android OpenGL ES(十一)绘制一个20面体 .
前面介绍了OpenGL ES所有能够绘制的基本图形,点,线段和三角形.其它所有复杂的2D或3D图形都是由这些基本图形构成. 本例介绍如何使用三角形构造一个正20面体.一个正20面体,有12个顶点,20 ...
- android openGL ES2 一切从绘制纹理開始
纹理.在openGL中,能够理解为载入到显卡显存中的图片.Android设备在2.2開始支持openGL ES2.0.从前都是ES1.0 和 ES1.1的版本号.简单来说,openGL ES是为了嵌入 ...
- Android OpenGL ES 开发:绘制图形
OpenGL 绘制图形步骤 上一篇介绍了 OpenGL 的相关概念,今天来实际操作,使用 OpenGL 绘制出图形,对其过程有一个初步的了解. OpenGL 绘制图形主要概括成以下几个步骤: 创建程序 ...
随机推荐
- NSURLConnection基本使用
一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSURL对象,请求方法.请求头.请求体.... ...
- 3、Hibernate三态间的转换
学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...
- 自己写deque
//deque /* what is a deque? In Chinese, it's called "双端队列". It's different from a queue. I ...
- delphi 集合的用法
http://blog.sina.com.cn/s/blog_9e2e8405010180jy.html delphi基础补充 1 开域语句 在面向对象的程序代码中,嵌套对象的现象十分 ...
- 一步一步学EF系列【6、IOC 之AutoFac】
前言 之前的前5篇作为EF方面的基础篇,后面我们将使用MVC+EF 并且使用IOC ,Repository,UnitOfWork,DbContext来整体来学习.因为后面要用到IOC,所以本篇先单独先 ...
- javascript焦点图(根据图片下方的小框自动播放)
html和css就不详细说明了,也是简单布局,通过定位把跟随图片的小框,定位到图片下方 <!DOCTYPE html> <html> <head> <meta ...
- 关于echarts使用的各种问题
此文为作者辛苦编写,如有转发,请注明出处,谢谢 首先引入js文件,这是动态引入 <script src="http://echarts.baidu.com/build/dist/ech ...
- 总结一下C++各个版本之间的功能扩充
活到老,学到老. C++ 98 我们学习和教材中常见的. C++ 03 主要是对98版本进行了bug修复. C++ 11 引入的新功能请参见: http://www.cpluspl ...
- js移动端tap事件封装
这几天做项目,发现移动端需要触摸事件,而click肯定是不行的,于是我对tap事件封装进行了搜索,找到了一篇文章,原文地址如下:http://www.jb51.net/article/50663.ht ...
- 使用HttpClient工具类测试Http接口
一.httpClient模拟客户端 import java.util.ArrayList;import java.util.Iterator;import java.util.List;import ...