介绍GLSurfaceView

介绍GLSurfaceView - 给力生活,天天向上! - ITeye技术网站
http://googlers.iteye.com/blog/953316
基于Android的OpenGL—使用GLSurfaceView创建一个Activity - Android移动开发技术文章_手机开发 - 红黑联盟
http://www.2cto.com/kf/201205/129839.html




Android提供了两个基本的类让我们使用OpenGL ES API来创建和操纵图形:GLSurfaceView和 GLSurfaceView.Renderer。因此我们首先需要了解这两个类。
1.GLSurfaceView:
这是一个视图类,你可以调用OpenGL API在上面绘制图形和操纵物体,功能和SurfaceView相似。我们可以创建一个GLSurfaceView类的实例,并添加自己的渲染器。如果我们要自己实现一些触摸屏的操作,我们必须扩展这个类来实现触摸监听器。

2.GLSurfaceView.Renderer
这个接口定义了在一个OpenGL的GLSurfaceView中绘制图形所需要的方法。我们必须在一个单独的类中为这些接口提供实现,并使用GLSurfaceView.setRenderer()方法将它依附到GLSurfaceView实例对象上。
我们需要实现GLSurfaceView.Renderer的以下方法:
a)onSurfaceCreated():系统在创建GLSurfaceView时调用它一次。我们可以使用它来设置OpenGL的环境变量,或是初始化OpenGL的图形物体。
b)onDrawFrame():系统在每次重绘GLSurfaceView时调用这个方法。这个方法主要完成绘制图形的操作。
c)onSurfaceChanged():系统在GLSurfaceView的几何属性发生改变时调用该方法,包括大小或是设备屏幕的方向发生变化。例如,系统在屏幕从直立变为水平使调用它。这个方法主要用来对GLSurfaceView容器的变化进行响应。


android.opengl.GLSurfaceView类让你更容易地使用OpenGL ES渲染你的应用程序,其主要通过一下几点:
1、提供粘合代码把OpenGL ES连接到你的视图系统
2、提供粘合代码使得OpenGL ES按照Acticity(活动)的生命周期工作
3、使它容易选择一款合适的框架缓冲区像素格式
4、创建和管理一个独立的渲染线程,产生平滑的动画
5、提供更容易使用的调试工具来跟踪OpenGL ES 的API 并能找出错误。

GLSurfaceView是一个很好的基类对于构建一个使用OpenGL ES进行部分或全部渲染的应用程序。一个2D或3D的动作游戏就是一个很好的例子,例如一个2D或3D的可视化应用如谷歌地图。


以下是一个简单的GLSurfaceView的应用:
一个最简单的OpenGL ES应用代码如下:


package cn.hzgames.glsurfaceview; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; public class FirstDemo extends Activity { private GLSurfaceView mGLView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new GLSurfaceView(this); mGLView.setRenderer(new ClearRenderer()); setContentView(mGLView); } @Override protected void onPause() { super.onPause(); mGLView.onPause(); } @Override protected void onResume() { super.onResume(); mGLView.onResume(); } class ClearRenderer implements GLSurfaceView.Renderer {/* * 在开始渲染的时候被调用,无论什么时候OpenGL ES * 渲染不得不重新被创建。(渲染是典型的丢失并重新创建当活动被暂停或恢复。)该方法一个创建长生命周期OpenGL资源(如材质)的好地方 */ public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Do nothing special. }/* * 该方法在surface大小改变时被调用。这是设置你opengl视图端的好地方。如果相机是固定的,不会围着场景移动,你也可以在这里设置你的相机 */ public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); }/* * 每帧的时候该方法都会被调用,这个用于画场景是可靠的。你完全可以通过调用glClear方法开清楚帧缓存,接着通过其他的opengl * ES来调用画当前的场景 */ public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); } } }




这个程序并没有做太多东西:它在每帧是清除屏幕到黑色。但是它是一个完整的OpenGL应用程序,正确地按照Activity(活动)的生命周期实现。当活动暂停渲染它也暂停渲染,活动恢复它也恢复。你可以把这个例子作为一个基本的交互的示例程序。仅仅更多地调用了ClearRenderer.onDrawFrame() 方法。注意你甚至不需要子类化一个GLSurfaceView视图。

GLSurfaceView.Renderer 有三个方法:
onSurfaceCreated() :在开始渲染的时候被调用,无论什么时候OpenGL ES 渲染不得不重新被创建。(渲染是典型的丢失并重新创建当活动被暂停或恢复。)该方法一个创建长生命周期OpenGL资源(如材质)的好地方。
onSurfaceChanged():该方法在surface大小改变时被调用。这是设置你opengl视图端的好地方。如果相机是固定的,不会围着场景移动,你也可以在这里设置你的相机。
onDrawFrame():每帧的时候该方法都会被调用,这个用于画场景是可靠的。你完全可以通过调用glClear方法开清楚帧缓存,接着通过其他的opengl ES来调用画当前的场景。

用户如何输入?
假如你想做一个可以交互的程序(如游戏),通常你会实现GLSurfaceView子类,因为这是很容易获取用户输入事件。以下代码是一个清晰的长例子展示给你怎样做到这个:

package com.javaeye.googlers; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.Context; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.MotionEvent; public class ClearActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new ClearGLSurfaceView(this); setContentView(mGLView); } @Override protected void onPause() { super.onPause(); mGLView.onPause(); } @Override protected void onResume() { super.onResume(); mGLView.onResume(); } private GLSurfaceView mGLView; } class ClearGLSurfaceView extends GLSurfaceView { public ClearGLSurfaceView(Context context) { super(context); mRenderer = new ClearRenderer(); setRenderer(mRenderer); } public boolean onTouchEvent(final MotionEvent event) { queueEvent(new Runnable(){ public void run() { mRenderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); }}); return true; } ClearRenderer mRenderer; } class ClearRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Do nothing special. } public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } public void onDrawFrame(GL10 gl) { gl.glClearColor(mRed, mGreen, mBlue, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); } public void setColor(float r, float g, float b) { mRed = r; mGreen = g; mBlue = b; } private float mRed; private float mGreen; private float mBlue; }



这个应用每帧都在清楚屏幕。当你点击屏幕时,它清除颜色基于你触屏时间的X、Y坐标。注意在 ClearGLSurfaceView.onTouchEvent()中使用queueEvent()。queueEvent()方法被安全地用于在UI线程和渲染线程之间进行交流。如果你愿意,你还可以使用一些其他的java线程间交流技术,例如Renderer 类本身的同步方法。然而,queueing 事件经常是一种用于处理线程间信息交流的更简单方式。


其他的GLSurfaceView示例:
如果你厌烦了上面的示例,你还可以从android的ApiDemo中找到更经典的示例,所有的openGL ES示例都是用GLSurfaceView视图转变的:

GLSurfaceView - 一个旋转的三角形
Kube - 一个魔方例子
Translucent GLSurfaceView - 展示在一个透明的背景上显示3d动画
Textured Triangle - 显示一个带纹理的3D三角形
Sprite Text - 展示怎样用材质画出文字并混合进一个3d的场景中
Touch Rotate - 展示怎样旋转一个3D物体来响应用户的输入


demo下载地址
【介绍GLSurfaceView】GLSurfaceView入门demo - 下载频道 - CSDN.NET
http://download.csdn.net/detail/aishang5wpj/7642313

    推荐阅读