在Android应用中使用OpenGL
Android为OpenGL ES支持提供了GLSurfaceView组件,这个组件用于显示3D图形。GLSurfaceView本身并不提供绘制3D图形的功能,而是由GLSurfaceView.Renderer来完成了SurfaceView中3D图形的绘制。
归纳起来,在Android中使用OpenGL ES需要三个步骤:
1、创建GLSurfaceView组件,使用Activity来显示GLSurfaceView组件。
2、为GLSurfaceView组件创建GLSurfaceView.Renderer实例,实现GLSurfaceView.Renderer类时需要实现该接口里的三个方法:
abstract void onDrawFrame(GL10 gl):Renderer对象调用该方法绘制GLSurfaceView的当前帧。
abstract void onSurfaceChanged(GL10 gl , int width ,int height):当GLSurfaceView的大小改变时回调该方法。
abstract void onSurfaceCreated(GL10 gl , EGLConfig config):当GLSurfaceView被创建时回调该方法。
3、调用GLSurfaceView组件的setRenderer()方法指定Renderer对象,该Renderer对象将会完成GLSurfaceView里3D图像的绘制。
从上面的介绍不难看出,实际上绘制3D图形的难点不是如何使用GLSurfaceView组件,而是如何实现Renderer类。实现Renderer类时需要实现三个方法,这三个方法都有一个GL10形参,它就代表了GLOpen ES的“绘制画笔”,我们可以把它想象成Swing 2D绘图中的Graphics,也可以想象成Android 2D绘图中的Canvas组件-----当我们希望Renderer绘制3D图形时,实际上是调用GL10的方法来进行绘制的。
当SurfaceView被创建时,系统会回调Renderer对象的onSurfaceCreated()方法,该方法将可以对OpenGL ES执行一些无须任何改变的初始化,例如:
@Override
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的绘图接口,但实际上他也是GL11的实例,可通过(gl Instansof GL11)判断它是否为GL11接口的实例。
glDisable(int cap):该方法用于禁用OpenGL ES某个方面的特性,上例中代码用于关闭抗抖性,这样可以提高性能。
glHint(int target , int mode):该方法用于对OpenGL ES某方法进行修正。
clearColor(float red , float green , float blue , float alpha):该方法设置OpenGL ES“清屏”所用的颜色,四个参数分别设置红、绿、蓝、透明度值;0为最小值,1为最大值。例如设置gl.glClearColor(0 , 0 , 0 , 0):就是用黑色“清屏”。
glShadeMode(int mode):该方法用于设置OpenGL ES的阴影模式,此处设为阴影平滑模式。
glEnable(int cap):该方法与glDisable(int cap)方法相对,用于启用OpenGL ES某方面的特性,此处用于启动OpenGL ES的深度测试,所谓“深度测试”,就是让OpenGL ES负责跟踪每个物体在Z轴上的深度,这样就可避免后面的物体遮挡前面的物体。
当SurfaceView组件的大小发生改变时,系统会回调Renderer对象的onSurfaceChanged()方法,因此该方法通常用于初始化3D场景。例如如下初始化代码:
@Override
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的一些初始化方法,此处做简要说明:
glViewport(int x , int y , int width , int height):设置3D视窗的位置与大小。其中前两个参数指定该视窗的位置,后两个参数指定该视窗的宽、高。
glMatrixMode(int mode):设置视图的矩阵模型。通常可接受GL10.GL_PROJECTION、GL10.GL_MODEVIEW两个常量值。
当调用glMatrixMode(GL10.GL_PROJECTION):代码后,指定将屏幕视为透视图(要想看到逼真的三维物体,这是必要的),这意味着越远的东西看起来越小;当调用glMatrixMode(GL10.GL_MODEVIEW):代码后,即将当前矩阵模式设为模型视图矩阵,这意味着任何新的变换都会影响该矩阵中的所有物体。
glLoadIdentity():相当于reset()方法,用于初始化单位矩阵。
glFrustumf(float left , float right , float bottom , float top , float zNear , float zFar):用于设置透视投影的空间大小。前路两个参数用于设置X轴上的最小坐标值、最大坐标值;中间两个参数用于设置Y轴上的最小坐标值、最大坐标值;后面两个参数用于设置Z轴上所能绘制的场景的深度的最小值、最大值。
注:三维坐标系统与二维坐标系统并不相同,而二维坐标系统上的坐标值通常就直接使用系统的像素数量;但三维坐标系统的坐标值则取决于glFrustumf()方法的设置。
GLSurfaceView上的所有3D图形都是有Renderer的onDrawFrame(GL10 gl)方法绘制出来的,重写该方法时就要把所有3D图形都绘制出来,该方法通常以如下形式开始:
@Override
public void onDrawFrame(GL10 gl) {
// 清除屏幕缓存和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
}
在Android应用中使用OpenGL的更多相关文章
- 在Android中使用OpenGL ES开发第(四)节:相机预览
笔者之前写了三篇Android中使用OpenGL ES入门级的文章,从OpenGL ES的相关概念出发,分析了利用OpenGL ES实现3D绘图的重要的两个步骤:定义形状和绘制形状,简单的绘制了一个三 ...
- 在Android中使用OpenGL ES开发第(五)节:GLSL基础语法
一.前期基础储备笔者之前的四篇文综述了Android中使用OpenGL ES绘制基本图形和实现了简单的相机预览,初次接触OpenGL ES开发的读者可能对其中新的概念比较迷惑,尤其是其中的顶点着色器( ...
- 在Android中使用OpenGL ES进行开发第(三)节:绘制图形
一.前期基础知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGLES绘制2D ...
- 在Android中使用OpenGL ES进行开发第(二)节:定义图形
一.前期基础知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGLES绘制2D ...
- 在Android中使用OpenGL ES进行开发第(一)节:概念先行
一.前期基础是知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGL ES绘制 ...
- Android: NDK中的Android.mk和Application.mk
1. 简介 Android.mk 可用来描述要编译的某个具体模块的相关信息.比如:指定编译该模块时所需要的源文件.编译该模块时要链接的库文件.该模块编译完成后生成的库的名字等等.Applicatio ...
- Android 显示系统:OpenGL简介和Gralloc代码分析
一.OpenGL ES与EGL Android的GUI系统是基于OpenGL/EGL来实现的. 由于OpenGL是通用函数库,在不同平台系统上需要被“本土化”——把它与具体平台的窗口系统建立起关联,F ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- Stack Overflow 排错翻译 - Closing AlertDialog.Builder in Android -Android环境中关闭AlertDialog.Builder
Stack Overflow 排错翻译 - Closing AlertDialog.Builder in Android -Android环境中关闭AlertDialog.Builder 转自:ht ...
随机推荐
- jQuery.validate.js+API_cn
名称 返回类型 描述 validate(options) 返回:Validator 验证所选的FORM valid() 返回:Boolean 检查是否验证通过 rules() 返回:Options ...
- maven使用实例记录
Maven入门指南① :Maven 快速入门及简单使用Maven入门指南② :Maven 常用命令,手动创建第一个 Maven 项目Maven入门指南③:坐标和依赖Maven入门指南④:仓库 Mave ...
- 进击的Hybrid App,量身定做缓存机制
引用张图,简单粗俗的解释下 Native App.Web App 和 Hybrid App Navtie App: 使用平台系统提供的原生语言来编写的 App,如果Android用java,ios用o ...
- poj3347Kadj Squares
链接 这题其实与几何没太大关系,还不错的题目. 参考吴永辉的算法设计书. 用lefi.rigi分别表示正方形在x轴上的投影. 为了避免用小数,把边长都扩大sqrt(2)倍,这样lef1 = 0,rig ...
- (转)http接口测试——Jmeter接口测试实例讲解
http://my.oschina.net/hellotest/blog/512482
- xml配置文件详解
1:bean的基本属性配置: <!-- id是bean的标识符,必须唯一,如果没有配置id,name默认为标识符 如果配置了id,有配置了name,那么name为别名 name可以设置多个别名, ...
- Hashtable HashMap
Hashtable和HashMap类有三个重要的不同之处.第一个不同主要是历史原因.Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现. ...
- iOS开发 字符串MD5加密
/*** MD5 ***/ #define CC_MD5_DIGEST_LENGTH 16 /* digest length in bytes */ #define CC_MD ...
- dede在线留言
登录dede后台,在[核心]---[频道维护]---[自定义表单]中根据需要创建需要的表单. 点击[增加新的自定义表单],添加在线留言表单.确定即可. 注意: ①在这里只需要修改[自定义表单名称: ...
- linux笔记:权限管理命令chmod,chown,chgrp,umask
权限对文件和目录的含义是不同的:对文件来说:读:可以查看文件内容写:可以修改文件内容执行:可以执行文件对目录来说:读:可以列出目录中的内容写:可以在目录中创建.删除文件执行:可以进入目录 能够更改文件 ...