`

Android 中OpenGL的使用

阅读更多
android为openGL ES支持提供了GLSurfaceView组件, 这个组件用于显示3D图形。GLSufaceView本身并不提供绘制3D图形的功能,而是由GLSurfaceView.Renderer来完成了SurfaceView中3D图形的绘制。
归纳起来,在android中使用openGl ES需要三个步骤:

1,创建GLSurfaceView组件,使用activity来显示GlSufaceView组件
2. 为GLSufaceView组件创建GLSufaceView.Renderer实例,实现GLSurfaceView.Renderer类时需要实现接口里的三个方法。
    (1) abstract void onDrawFrame(GL10 gl): Renderer对象调用该方法绘制GLSurfaceView的当前帧。
    (2)abstract void onSurfaceChanged(GL10 gl, int width, int height):当GLSurfaceView的大小改变时回调该方法。
    (3)abstract void onSufaceCreated(GL10 gl, EGLConfig config):当GLSurfaceView被创建时回调该方法。
3.调用GLSurfaceView组件的setRender()方法指定Renderer对象。该Renderer对象完成GLSurfaceView里3D图形的绘制。


从上面的介绍不难看出,实际上绘制3D图像的难点不是如何使用GLSurface组件,而是如何实现Renderer类。是想Renderer类时需要三个方法。这三个方法都有一个GL10形参,他就代表了GLOpen ES的“绘制画笔”, 读者可以把它想象成Swing 2D绘图中的Graphics,也就是想象成android2D绘图中的Canvas组件-当我们希望Renderer绘制3D图像时,实际上是调用GL10的方法来进行绘制的。
  当SurfaceView被创建时,系统会回调Rnderer对象的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的绘图接口,虽然这里看到的是一个GL10,但实际上它也是GL11的实例,读者可通过(gl instandeof GL11)判断他是否为GL11接口的实例。
上面的方法中用到了一些初始化方法,关于这些方法的说明如下:
(1)glDisable(int cap) : 该方法用于禁用OpenGL ES某个方面的特性。 该方法中第一行代码用于关闭抗抖动,这样可以提高性能。
(2)glHint(int target, int mode):该方法用于对OpenGL ES某方面进行校正。
(3)clearColor(float red, float green, float alpha):该方法设置OpenGl ES"清屏"所用的颜色,四个参数分别设置红、绿、蓝、透明值: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轴的深度,这样就可避免后面的物体遮挡前面的物体。


当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, 0, 1, 10);
	}

上面的方法中用到了GL10的一些初始化方法,关于这些方法的说明如下。
(1) glViewport(int x, int y, int width, int height): 设置3D视窗的位置与大小,其中前两个参数指定该视窗的位置,后面两个参数指定该视窗的宽、高。
(2) glMatrixMode(int mode): 设置视窗的矩阵模型,通常可接受GL10.GL_PROJECTION、 GL10.GL_MODELVIEW两个常量值。
当调用gl.glMatrixMode(GL10.GL_PROJECTION);代码后,指定将屏幕设为透视图(要想看到逼真的三维物体,这是必要的), 这意味着越远的东西看起来越小;当调用gl.glMatrixMode(GL10.GL_MODELVIEW);代码后,即将当前矩阵模式设为模型视图矩阵,这意味着任何新的变换都会影响该矩阵的所有物体。
  (3)glLoaddentity():相当于reset()方法,用于初始化单位矩阵。
  (4)glFrustumfglFrustumf(float left, float right, float bottom, float top, float zNear, float zFar): 用于设置透视投影的空间大小,前面两个参数用于设置X轴上的最小坐标值、最大坐标值,中间的两个参数用于设置Y轴的最小坐标值、最大坐标值; 后面两个参数用于设置Z轴上所能绘制的场景的深度的最小值、最大值。
例如我们调用如下代码:
gl.glFrustumf(-0.8f, 0.8f, -1f, 1f, 1f, 10f);

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

提示:前面已经指出:三维坐标系统与二维坐标系统并不相同,二维坐标系统上的坐标值通常就直接使用系统的像素数量;但三维坐标系统的坐标值则取决于glFrustumf()方法的设置,当我们调用gl.glFrustumf(-0.8f, 0.8f, -1f, 1f, 1f, 10f);方法时,意味着该三维坐标系统的最左边的坐标值为-0.8,最右边的坐标值为0.8;Y轴最上面的坐标值为1.0,最下面的坐标值为-1.0


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

接下来在onDrawFrame方法中就可以调用GL10的方法开始绘制了。

绘制平面上的多边形
调用GL10图形绘制2D图形的步骤如下:

(1)调用GL10的glEnableClientState(GL10.GL_VERTEX_ARRAY);方法启用顶点坐标数组。
(2)调用GL10的glEnableClientState(GL10.GL_COLOR_ARRAY);方法启用顶点颜色数组。
(3)调用GL10的glVertexPointer(int size, int type, int stride, Buffer pointer)方法

设置顶点的位置数据。这个方法中pointer参数用于指定顶点坐标值,但这里并未使用三维数组来指定每个顶点X、Y、Z坐标值,point依然是一个一维数组,也就是该数组将会包含3N个数值,每三个值指定一个顶点的X、Y、Z坐标值。 第一个参数size指定多少个元素指定一个顶点位置,该size参数通常总是3;type参数指定顶点值的类型,如果顶点坐标值为float类型,则指定为GL10.GL_FLOAT;如果顶点坐标值为整数,则指定为GL10.GL_FIXED.
(4)调用GL10的glColorPoint(int size, int type, int stride, Buffer pointer)方法设置顶点的颜色数据。 point依然是一维数组,每四个值指定一个顶点的红、绿、蓝、透明度的颜色值。第一个参数size指定多少个元素指定一个顶点位置,该size参数通常总是4, type参数指定顶点坐标值的类型,如果顶点坐标值为float类型,则指定为GL10.GL_FLOAT;如果顶点坐标值为整数,则指定为GL10.GL_FIXED.
(5),调用GL10的glDrawArrays(int mode, int first, int count)方法绘制平面,该方法第一个参数用于指定绘制图形的类型,第二个参数指定从哪个顶点开始绘制,第三个参数指定总共绘制的顶点数量。
(6),绘制完成后,调用GL10的glFinish()方法结束绘制;并调用glDisableClientState(int)方法来停用顶点坐标数据、顶点颜色数据。
0
0
分享到:
评论

相关推荐

    在Android中的jni里使用OpenGL ES和OpenCV渲染一幅图片

    在Android平台上,JNI(Java Native Interface)允许开发者使用C++代码来增强应用程序的功能,尤其是在处理图形和计算密集型任务时,如使用OpenGL ES和OpenCV。这个特定的项目旨在通过JNI调用来结合这两个强大的库...

    在屏幕绘制各种图形,了解Android中OpenGL的使用。

    在Android中,我们可以使用`GLSurfaceView`组件来创建一个适合于OpenGL渲染的视图,并通过`GLSurfaceView.Renderer`接口实现图形的绘制逻辑。 1. 创建GLSurfaceView 在布局XML文件中,添加`GLSurfaceView`并指定...

    android-opengl图片3d旋转

    使用`glRotatef()`函数(或者在现代OpenGL中使用矩阵操作)来指定旋转的角度和轴。 3D旋转涉及到向量和矩阵操作。在OpenGL中,旋转可以通过乘以一个旋转矩阵来实现。例如,你可以使用`glRotatef(rotateAngle, x, y,...

    Android中opengl es要实现Obj格式的3D导入

    总之,要在Android中使用OpenGL ES实现Obj格式3D模型的导入,需要熟悉OpenGL ES编程,理解Obj文件格式,编写或使用现成的Obj解析器,以及正确处理数据加载和绘制流程。这是一项涉及多方面知识的任务,但完成之后,...

    Android平台使用OpenGLES2.0显示YUV数据

    通过分析和理解这个类,你可以更好地掌握如何在Android中使用OpenGLES2.0处理和显示YUV数据。 此外,`GLSurfaceView`是Android系统提供的一种专门用于OpenGL渲染的视图组件。它内部封装了EGL上下文的创建、销毁以及...

    Android平台OpenGLES生成使用Mipmap纹理

    该案例代码为Android 平台OpenGL ES实现...1、在Android平台,使用OpenGL ES通过加载灰度图,构建山地图形渲染效果; 2、使用 OpenGLES 生成与使用Mipmap纹理,构建远处模糊,近处清晰的效果。 具体案例文章讲解请见: ...

    Android通过opengl 读取并显示obj模型

    Android通过opengl显示obj模型

    android opengl 点线面 first

    first demo for android opengl

    android openGL ES使用小例子

    android openGL 里面提供了illegalArgumentException异常的解决方法

    Android 使用opengl写动态壁纸的类库-IT计算机-毕业设计.zip

    通过分析和研究这些文件,你可以了解到如何在Android动态壁纸中使用OpenGL ES来创建复杂的动画效果。同时,这也是一个很好的机会去学习Android的生命周期管理,理解服务(Service)的工作原理,以及如何将OpenGL与...

    Android下 OpenGL ES 2.0 混合半透明效果demo

    在这个"Android下 OpenGL ES 2.0 混合半透明效果demo"中,我们将探讨如何在Android应用中实现半透明效果的混合。 首先,理解OpenGL ES 2.0的核心概念至关重要。它基于着色器模型,这意味着开发者可以编写顶点着色器...

    Android Native层使用opengl es渲染yuv420

    Android Native层使用opengl es渲染yuv420,通过egl绑定android的surface,直接在native层进行渲染 具体使用见http://blog.csdn.net/lidec/article/details/73732369#comments

    Android上opengl es3.0实现一个旋转的三角形(Android studio2.1.3)

    在 Android Studio 2.1.3 中,要实现一个使用 OpenGL ES 3.0 的旋转三角形,你需要遵循以下步骤: 1. **设置项目配置**:首先确保你的 Android Studio 支持 OpenGL ES 3.0。在 `build.gradle` 文件的 `default...

    Android段opengl图片播放器

    在OpenGL中,每一帧的渲染都是通过调用`glDrawArrays`或`glDrawElements`等函数来完成的。通过调整渲染间隔,可以实现播放速度的控制。暂停时,渲染间隔会被设置为无穷大,停止画面更新;快进和后退则需要改变帧的...

    android_opengl.rar_Android opengl_android_opengl例子

    2. **顶点和坐标系统**: 在OpenGL中,图形由顶点组成。开发者需要定义顶点的位置,并使用坐标系统来定位它们。OpenGL使用右手坐标系,Z轴正方向指向屏幕内部。 3. **着色器**: OpenGL ES 2.0及以上版本引入了着色器...

    OpenGLES.zip Android官方OpenGL例子

    The example code in this class uses the OpenGL ES 2.0 APIs, which is the recommended API version to use with current Android devices. For more information about versions of OpenGL ES, see the OpenGL ...

    Android OpenGL ES 2.0学习书籍.rar

    在Android上使用OpenGL ES 2.0,首先需要理解Android SDK中的GLSurfaceView类,它是为OpenGL ES渲染提供一个专用的SurfaceView,确保渲染在独立的线程中进行,避免阻塞UI主线程。开发者还需要创建一个GLSurfaceView....

    如何查看android系统的openGL版本(内含源码和apk)

    在Android上,我们主要使用的是OpenGL ES而非桌面版的OpenGL。 以下是一个简单的Android应用示例,用于查询并显示设备的OpenGL ES版本: ```java import android.app.Activity; import android.content.pm....

    如何使用Android中的OpenGL ES媒体效果

    如何使用Android中的OpenGL ES媒体效果,应用Android的media effect framework到OpenGL中

    android OpenGL绘制立体图形

    android OpenGL技术绘制一个旋转的3d立方体

Global site tag (gtag.js) - Google Analytics