Android GLSurfaceView介绍及示例
1. 概述
Android平台提供了一个名为GLSurfaceView的视图类,它可以用于渲染OpenGL图形。GLSurfaceView提供了一个OpenGL渲染的上下文,可以在多个线程中进行渲染。本文将介绍GLSurfaceView的基本概念、使用方法和示例代码,帮助读者快速入门。
2. GLSurfaceView的基本使用
2.1 导入依赖
首先,在你的Android项目中的build.gradle
文件中添加GLSurfaceView的依赖:
implementation 'android.opengl:glSurfaceView:1.3'
2.2 创建GLSurfaceView
在布局文件中添加GLSurfaceView控件:
<android.opengl.GLSurfaceView
android:id="@+id/glSurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2.3 实现Renderer接口
创建一个类实现GLSurfaceView.Renderer
接口,这个接口定义了OpenGL渲染所需的回调方法。在这个类中,可以编写OpenGL渲染的逻辑。
public class MyRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// OpenGL渲染环境创建时调用,进行初始化操作
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 当GLSurfaceView的大小发生变化时调用,可以更新OpenGL视口的大小
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
// 在每一帧绘制时调用,进行渲染操作
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
}
2.4 设置Renderer
在Activity中,找到GLSurfaceView控件并设置自定义Renderer:
GLSurfaceView glSurfaceView = findViewById(R.id.glSurfaceView);
glSurfaceView.setRenderer(new MyRenderer());
2.5 设置渲染模式
GLSurfaceView提供了两种渲染模式:CONTINUOUSLY和WHEN_DIRTY。CONTINUOUSLY模式下,GLSurfaceView会不断渲染画面;WHEN_DIRTY模式下,需要手动调用requestRender()
方法来触发渲染。默认情况下,GLSurfaceView使用CONTINUOUSLY模式。
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
3. 示例代码
以下是一个简单的示例代码,演示了如何在GLSurfaceView中绘制一个彩色三角形:
public class MyRenderer implements GLSurfaceView.Renderer {
private FloatBuffer vertexBuffer;
private int program;
private static final String vertexShaderCode =
"attribute vec4 vPosition;\n" +
"void main() {\n" +
" gl_Position = vPosition;\n" +
"}\n";
private static final String fragmentShaderCode =
"precision mediump float;\n" +
"void main() {\n" +
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" +
"}\n";
private static final int COORDS_PER_VERTEX = 3;
private static float triangleCoords[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
public MyRenderer() {
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
program = GLES20.glCreateProgram();
GLES20.gl