Android开发之OpenGL绘制2D图形的方法分析

作者:pku_android 时间:2023-05-19 09:59:48 

本文实例讲述了Android开发之OpenGL绘制2D图形的方法。分享给大家供大家参考,具体如下:

Android为OpenGL ES支持提供了GLSurviceView组建,这个组建用于显示3D图形。GLSurviceView本身并不提供绘制3的图形的功能,而是由GLSurfaceView.Renderer来完成了SurviceView中3D图形的绘制。

归纳起来,在android中使用OpenGL ES需要3个步骤。

1. 创建GLSurviceView组件,使用Activity来显示GLSurfaceView组件。

2. 为GLSurviceView组件创建GLSurviceView.Renderer实例,实现GLSurviceView.Renderer类时需要实现该接口里的3个方法。

(1) abstract void onDrawFrame(GL 10 gl):Renerer对象调用该方法绘制GLSurviceView的当前帧。

(2) abstract void onSurfaceChanged(GL 10 gl,int width,int height):当GLSurfaceView的大小改变时回调该方法。

(3) abstract void onDrawFrame(GL 10 gl,EGLConfig config):当GLSurfaceView被创建时回调该方法。

3. 调用GLSurfaceView组件的setRebderer()方法指定Renderer对象,该Renderer对象将会完成GLSurfaceView里3D图像的绘制。

从上面的介绍不难看出,实际上绘制3D图像的难点不是如何使用GLSurface组件,二是如何实现Renderer类。实现Render类时需要实现3个方法。这3个方法都有一个GL形参,它就代表了GLOpenES的“绘制画笔”,我们可以把它想象成Swing 2D绘图中的Graphics,也可以想象成Android 2D绘图中的Canvas组件——当我们希望renderer绘制3D图形时,实际上是调用GL10的方法来进行绘制的。

当Survice View被创建时,系统会回调Renderer对象的onSurfaceCreated()方法,该方法将可以对OpenGL ES执行一些无需任何改变的初始化,例如如下初始化代码:


public void OnSurfaceCreated(GL10 gl,EGLConfig config)
{
 //关闭抗抖动
 gl.glDisable(GL10.GL_DITHER);
 //设置系对透视进行修正
 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
 gl.glClearColor(0, 0, 0, 0);
 //设置阴影平滑模式
 gl.glShadeModel(GL10.GL_SMOOTH);
 //启用深度测试
 gl.glEnable(GL10.GL_DEPTH_TEST);
 //设置深度测试的类型
 gl.glDepthFunc(GL10.GL_LEQUAL);
}

GL10就是OpenGL ES的绘制接口,虽然这里看到的是一个GL10,但实际上它也是GL11的实例,读者可通过(gl instanceof GL11)判断它是否为GL11接口的实例。

上面的方法中用到了GL10的一些初始化方法,关于这些方法的说明如下:

(1) GlDisable(int cap):该方法用于禁用OpenGL ES某个方面的特性。该方法中第一行代码用于关闭抗抖动,这样可以提高性能。
(2)glHint(int target,int mode):该方法用于对OpenGL ES某方面的修正。
(3)clearColor(float red,float green,float blue,float alpha):该方法设置清屏所用的颜色,四个参数分别设置红、绿、蓝、透明度值:0为最小值,1为最大值。例如设置gl.glClearColor(0,0,0,0);就是用黑色清屏。
(4)glShadeModel(int mode):该方法用于设置OpenGL ES的阴影模式。此处设为阴影平滑模式。
(5)glEnable(int cap):该方法与glDisable(int cap)方法相对,用于启用OpenGL ES某方面的特性,此处用于启动OpenGL ES的深度测试,就是让OpenGL ES负责跟踪每个物体在Z轴上的深度,这样就可以避免后面的物体遮挡前面的物体。

当SurviceView组建的大小发生变化时,系统会回调Renderer对象的onSurfaceChanged()方法,因此该方法通常用于初始化3D场景。例如如下初始化代码:


public void onSurfaceChanged(GL10 gl,int width,int height)
{
 //设置3D视窗的大小和位置
 gl.glViewport(0,0,width,height);
 //将当前矩阵模式设为投影矩阵
 gl.glMatrixMode(GL10.GL_PROJECTION);
 //初始化单位矩阵
 gl.glLoadIdentity();
 //计算透视视窗的宽度、高度比
 float ratio = (float)width/height;
 //调用此方法设置透视视窗的空间大小
 gl.glFrustumf(-ratio,ratio,-1,1,1,10);
}

上面的方法用到了GL10的一些初始化方法,关于这些方法的说明如下:

1、 glViewport(int x,int y,int width,int height):设置3D视窗的位置与大小。其中前两个参数指定该视窗的位置,后两个参数指定该视窗的宽,高。

2、glMatrixMode(int mode):设置视图的矩阵模型。通常可接受GL10.GL_PROJECTION、GL10.GL_MODELVIEW两个常量值。

当调用glMatrixMode(GL 10.GL_PROJECTION);代码后,指定将屏幕设为透视图,这意味着越远的东西看起来越小;当调用glMatrixMode(GL 10. GL_MODELVIEW);代码后,即将当前矩阵模式设为模式视图矩阵,这意味着任何新的变换都会影响该矩阵中的所有物体。

3、glLoadIdentity():相当于reset()方法,用于初始化单位矩阵。

4、glFrustumf(float left,float right,float bottom,float top,float zNear,float zFar):用于设置透视投影的空间大小。前两个参数用于设置X轴上的最小坐标值、最大坐标值;中间两个参数用于设置Y轴上的最小坐标值、最大坐标值;后两个参数用于设置Z轴上的最小坐标值、最大坐标值。

例如我们调用如下代码:


gl.glFrustumf(-0.8,0.8,-1,1,1,10);

这意味着如果有一个二维矩形,它的四个顶点的坐标分别为:(-0.8,1)、(0.8,1)、(0.8,-1),(-0.8,-1),这个矩阵将会占满整个视窗。

GLSurfaceView上的所有3D图形都是由Renderer的onDrawFrame(GL10 gl)方法绘制出来的,重写该方法时就要把所有3D图形都绘制出来,该方法通常以如下形式开始:


public void onDrawFrame(GL10 gl)
{
 //清除屏幕缓存和深度缓存
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
 ...
}

希望本文所述对大家Android程序设计有所帮助。

来源:http://blog.csdn.net/pku_android/article/details/7574604

标签:Android,OpenGL,绘制图形
0
投稿

猜你喜欢

  • 普通对象使用spring容器中的对象的实现方法

    2023-06-17 12:27:20
  • unity 文件流读取图片与www读取图片的区别介绍

    2023-08-30 09:10:37
  • java中hasNextInt判断后无限循环输出else项的解决方法

    2023-11-15 10:12:44
  • 详解Android USB转串口通信开发基本流程

    2022-01-04 10:12:15
  • C#中foreach循环对比for循环的优势和劣势

    2021-12-29 23:50:59
  • 详解Java并发编程之原子类

    2022-05-28 01:36:06
  • android 实现按钮浮动在键盘上方的实例代码

    2022-12-21 11:32:33
  • C#实现的微信网页授权操作逻辑封装示例

    2022-08-31 04:30:05
  • Python和Java的语法对比分析语法简洁上python的确完美胜出

    2023-08-10 17:06:54
  • C# 网络编程之UDP

    2021-10-02 16:06:40
  • c# WPF中的TreeView使用详解

    2021-05-24 15:17:58
  • C# 汉字与拼音互转的实现示例

    2022-03-06 06:50:20
  • Spring EL表示式的运用@Value说明

    2023-03-05 02:33:19
  • SpringBoot读取自定义配置文件方式(properties,yaml)

    2021-06-30 23:46:07
  • 详解Eclipse提交项目到GitHub以及解决代码冲突

    2022-05-15 09:04:52
  • java识别一篇文章中某单词出现个数的方法

    2022-04-24 06:18:40
  • springboot使用mybatis开启事务回滚

    2022-09-10 05:15:55
  • 一文详解无痕埋点在Android中的实现

    2022-06-30 07:53:18
  • MyBatis拦截器原理探究

    2021-07-18 23:24:19
  • Android 7.0系统webview 显示https页面空白处理方法

    2021-10-22 09:36:49
  • asp之家 软件编程 m.aspxhome.com