关键字: android OpenGL 移动开发 教程
最近学习Android系统中3D编程,发现网络上资料虽多,但是都比较散,不成体系。网上有一些移植著名的OpenGL学习教程NeHe的资料,但是都不完整。因此趁此学习的机会, NeHe教程尽量完整移植,在移植过程中尽量利用了网络上已有的资源,整理成一个系统的学习材料, 也许对学习在Android上做3D开发的朋友有一些帮助。
Android中的OpenGL图形系统分为java框架和本地代码两部分。本地代码主要实现的 OpenGL接口的库,在 Java框架层,javax.microedition.khronos.opengles是 java标准的 OpenGL包,android.opengl包提供了 OpenGL系统和 Android GUI系统之间的联系。
这一课,演示如何在Android中创建一个OpenGL窗口,它是我们以后应用程序的框架。
在Andriod系统中, 使用GLSurfaceView来显示OpenGL视图,该类位于android.opengl里,GLSurfaceView的典型用法如下:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 创建一个GLSurfaceView
GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(new MyGLRenderer(this)); // 使用定制的渲染器
setContentView(glView);
}
GLSurfaceView提供了一个专门用于渲染的接口Renderer。因此需要实现一个类这里是MyGLRenderer来实现Renderer接口。并且必须重写以下三个方法:
public void onSurfaceCreate(GL10 gl, EGLConfig config)
public void onSurfaceChanged(GL10 gl, int width, int height)
public void onDrawFrame(GL10 gl)
当OpenGL视图窗口被创建时,调用onSurfaceCreate,因此我们可以再这里对OpenGL做一些初始化工作,如在MyGLRender中onSurfaceCreate的实现代码为:
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 设置背景颜色
gl.glClearColor(0.2f, 0.4f, 0.52f, 1.0f);
// 设置深度缓存
gl.glClearDepthf(1.0f);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所作深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
当渲染窗口发生变化时,系统将调用onSurfaceChange方法,因此在该方法中,我们可以设置OpenGL视图窗口的大小,代码如下:
public void onSurfaceChanged(GL10 gl, int width, int height)
{
if(height == 0) // 防止被零除
{
height = 1;
}
// 重置当前的视图区域
gl.glViewport(0, 0, width, height);
// 选择投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵
gl.glLoadIdentity();
// 设置视图区域的大小
GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f);
// 选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型观察矩阵
gl.glLoadIdentity();
}
实际画场景在方法onDrawFrame里实现,在这一课,我们只是绘制一个OpenGL窗口,因为里面只有清除屏幕和深度缓存和重置当前的模型观察矩阵,并没有回实际的图形。
onDrawFrame代码如下:
public void onDrawFrame(GL10 gl)
{
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
}
源代码文件:
GLLesson01Activity.java
package wintop.gllesson01;
import android.app.Activity;
import android.os.Bundle;
import android.opengl.GLSurfaceView; //导入OpenGL渲染面
//import android.view.Window;
//import android.view.WindowManager;
public class GLLesson01Activity extends Activity {
private GLSurfaceView glView; // 使用GLSurfaceView
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 全屏设置
//requestWindowFeature(Window.FEATURE_NO_TITLE);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
glView = new GLSurfaceView(this); // 创建一个GLSurfaceView
glView.setRenderer(new MyGLRenderer(this)); // 使用定制的渲染器
setContentView(glView);
}
// 当应用进入到后台方式时调用
@Override
protected void onPause(){
super.onPause();
glView.onPause();
}
// onPause之后调用
@Override
protected void onResume()
{
super.onResume();
glView.onResume();
}
}
MyGLRenderer.java
package wintop.gllesson01;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
public class MyGLRenderer implements GLSurfaceView.Renderer {
Context context; // 应用的上下文句柄
// Constructor with global application context
public MyGLRenderer(Context context) {
this.context = context;
}
// Call back when the surface is first created or re-created
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 设置背景颜色
gl.glClearColor(0.2f, 0.4f, 0.52f, 1.0f);
// 设置深度缓存
gl.glClearDepthf(1.0f);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所作深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
// Call back after onSurfaceCreated() or whenever the window's size changes
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
if(height == 0) // 防止被零除
{
height = 1;
}
// 重置当前的视图区域
gl.glViewport(0, 0, width, height);
// 选择投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵
gl.glLoadIdentity();
// 设置视图区域的大小
GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f);
// 选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型观察矩阵
gl.glLoadIdentity();
}
// Call back to draw the current frame.
@Override
public void onDrawFrame(GL10 gl)
{
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
}
}
最终的运行结果下图所示:
源代码下载地址:http://download.youkuaiyun.com/detail/seniorwizard/4460814