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


猜你喜欢
- 应用开发的时候,有时我们需要将一些图片进行预览,例如:相片管理的应用。这个时候用ListView的话就显得不是太合适了,因为Li
- 基本数据类型变量就是用来储存值而保留的内存位置。这就意味着当你创建一个变量时就会在内存中占用一定的空间。基于变量的数据类型,操作系统会进行内
- Java * 要想了解Java * ,首先要了解什么叫做代理,熟悉设计模式的朋友一定知道在Gof总结的23种设计模式中,有
- 本文实例讲述了C#编程实现查看剪切板内容的方法。分享给大家供大家参考,具体如下:using System;using System.Coll
- 功能要求: (1)比如每页显示2X2,总共2XN,每个item显示图片+文字(点击有链接)。 如果单行水平滚动,可以用Horizontals
- 在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked ex
- xml中: <ImageView &nb
- 这里介绍两种方法,一种是Spannable,一种是Html.fromHtml(通过html标签来改变),实际中看您使用哪种方便选择使用即可1
- 1、什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁
- 本文实例讲述了Android应用启动另外一个apk应用的方法。分享给大家供大家参考,具体如下:在开发的过程中,经常会遇到在一个应用中启动另外
- 网上很多人对设置控件的位置都使用view.setPadding(left, top, right, bottom) ,其实这玩意很差劲,它是
- Object是类层次结构的根,每个类都可以将Object作为超类。所有类都直接或者间接的继承自该类构造方法:public Object()回
- 本文实例讲述了Java使用反射调用方法。分享给大家供大家参考,具体如下:一 代码import java.util.*;import java
- Struts2是流行和成熟的基于MVC设计模式的Web应用程序框架。 Struts2不只是Struts1下一个版本,它是一个完全重写的Str
- 本文实例讲述了Java实现的Base64加密算法。分享给大家供大家参考,具体如下:一 算法实现1、JDK2、Commonc Codec3、B
- 本文实例讲述了WinForm生成验证码图片的方法。分享给大家供大家参考,具体如下:1、创建ValidCode类:public class V
- 在前一期中,我们做了悬浮头部的两个tab切换和下拉刷新效果,后来项目中要求改成三个tab,当时就能估量了一下,如果从之前的改,也不是不可以,
- java实现五子棋小游戏package Gomoku;import java.awt.Toolkit;import javax.swing.
- 目录一 为什么要用锁二 synchronized怎么实现的三 CAS来者何人四synchronized和CAS孰优孰劣轻量级锁重量级锁总结提
- 目录问题为每个request设置超时值Http Handler给Request加上超时处理抛出正确的异常使用Handler总结HttpCli