-
-
Typically you will set your viewport here. If your camera
-
is fixed then you could also set your projection matrix here:
-
void onSurfaceChanged(GL10 gl, int width, int height) {
-
gl.glViewport(0, 0, width, height);
-
// for a fixed camera, set the projection too
-
float ratio = (float) width / height;
-
gl.glMatrixMode(GL10.GL_PROJECTION);
-
gl.glLoadIdentity();
-
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
-
}
-
@param gl the GL interface. Use
instanceof
to -
test if the interface supports GL11 or higher interfaces.
-
@param width
-
@param height
*/
void onSurfaceChanged(GL10 gl, int width, int height);
/**
-
Called to draw the current frame.
-
-
This method is responsible for drawing the current frame.
-
-
The implementation of this method typically looks like this:
-
void onDrawFrame(GL10 gl) {
-
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-
//... other gl calls to render the scene ...
-
}
-
@param gl the GL interface. Use
instanceof
to -
test if the interface supports GL11 or higher interfaces.
*/
void onDrawFrame(GL10 gl);
}
void onSurfaceCreated(GL10 gl, EGLConfig config)
在Surface创建或重建的情况下回调
void onSurfaceChanged(GL10 gl, int width, int height)
在Surface的大小发生变化的情况下回调
void onDrawFrame(GL10 gl)
在这里实现绘制操作。当我们设置的renderMode
为RENDERMODE_CONTINUOUSLY
时,该函数将不断地执行;
当我们设置的renderMode
为RENDERMODE_WHEN_DIRTY
时,将只在创建完成和调用requestRender
后才执行。一般我们选择RENDERMODE_WHEN_DIRTY
渲染模式,避免过度绘制。
一般情况下,我们会自己实现一个Renderer,然后为GLSurfaceView设置Renderer,可以说,Renderer的编写是整个流程的核心步骤。以下是在void onSurfaceCreated(GL10 gl, EGLConfig config)
进行的初始化操作和在void onDrawFrame(GL10 gl)
进行的绘制操作的流程图:
2. 具体实现
- 坐标系介绍
如图所示,和Android的View坐标系不同,OpenGL的坐标系是笛卡尔坐标系。
Android View的坐标系以左上角为原点,向右x递增,向下y递增;
而OpenGL坐标系以中心为原点,向右x递增,向上y递增。
- 着色器编写
/**
- 顶点着色器
*/
private static String VERTEX_SHADER =
" attribute vec4 attr_position;\n" +
" attribute vec2 attr_tc;\n" +
" varying vec2 tc;\n" +
" void main() {\n" +
" gl_Position = attr_position;\n" +
" tc = attr_tc;\n" +
" }";
/**