OpenGL基础

来源:互联网 发布:华通云数据 编辑:程序博客网 时间:2024/06/06 08:45
Anroid提供了GLSurfaceView来更好的显示OpenGL视图,而GLSurfaceView中则包含了一个专门用于渲染3D的接口Renderer。
构建自己的Renderer首先要引入接口:
import android.opengl.GLSurfaceView.Renderer;
然后创建一个类实现Renderer接口
public class GameView implements Renderer {}
在类中必须实现3个抽象方法:
public void onDrawFrame(GL10 gl)public void onSurfaceChanged(GL10 gl, int width, int height)public void onSurfaceCreated(GL10 gl, EGLConfig config)
当窗口被创建时需要调用onSurfaceCreated,所以可以在这里进行一些初始化工作,例如:
// 告诉系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);// 黑色背景gl.glClearColor(0, 0, 0, 0);// 启用阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);
其中glHint用于告诉OpenGL进行最好的透视修正,这会轻微的影响性能,但会是得透视图看起来好一点。
glClearColor设置清除屏幕时所用的颜色,色彩值从0.0f~1.0f,参数分别是R、G、B、Alpha
glShadeModel用于启用smooth shading(阴影平滑)阴影平滑通过多边形精细地混色色彩,并对外部光进行平滑。
最后我们还需要做的一个最重要的步骤是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层,它不断地对物体进入屏幕内部的深度进行跟踪。几乎所有在屏幕上显示的3D场景的OpenGL程序都是用了深度缓存,他的排序决定了哪个物体先画。深度缓存是OpenGL十分重要的部分,代码如下
gl.glClearDepthf(1.0f);// 设置深度缓存gl.glEnable(GL10.GL_DEPTH_TEST);// 启用深度测试gl.glDepthFunc(GL10.GL_LEQUAL);// 所做深度测试类型

当窗口的大小发生改变时调用onSurfaceChanged方法,当然,不管窗口的大小是否已经改变它在程序开始时至少运行一次,所以我们在该方法中设置OpenGL场景的大小,这里将场景设置成它显示时所在窗口的大小:
gl.glViewport(0, 0, width, height);// 设置OpenGL场景大小
将屏幕设置为透视视图,这意味着越远的东西看起来越小。这么做创建了一个现实外观的场景。gl.glMatrixMode(GL10.GL_PROJECTION);指明接下来的代码将影响projection matrix(投影矩阵),投影矩阵负责为场景增加透视。gl.glLoadIdentity();近似于重置,它将所选的矩阵状态恢复成原始状态,调用gl.glLoadIdentity();之后场景设置透视图。gl.glMatrixMode(GL10.GL_MODELVIEW);指明任何新的变换将会影响modelview matrix(模型观察矩阵)模型观察矩阵中存放了物体的信息。重置模型观察矩阵:
gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵gl.glLoadIdentity();// 重置投影矩阵gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);// 设置窗口大小gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();
glFrustumf前面4个参数用于确定窗口大小,后面两个参数分别是在场景中所能绘制的深度和终点。
最后所有的绘图操作都是在onDrawFrame方法中进行,在绘图之前,需要将屏幕清除成前面所指定的颜色,清除深度缓存并且重置场景,让后就可以绘图了:
//清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);gl.glLoadIdentity();
最后通过调用GLSurfaceView类的setRenderer方法将自己构建的类设置为默认的Renderer,通过setContentView方法时Activity显示GLSurfaceView即可:
Renderer render = new GameView();GLSurfaceView glView = new GLSurfaceView(this);glView.setRenderer(render);setContentView(glView);