Android 深入系统完全讲解(20)
上文说过 surfaceView 的核心在于 holder,OpenGL 也是用的这个,我们看下操作:
我们使用 surface 可以使用 mSurface.lockCanvas(null); 获取一个 canvas 进行绘制。
同时也可以把这个 surface 封装成 OpenGL 的包裹,使用 OpenGL 绘制,具体为:(大家在学
习的时候,可以去看看 SDL2.0)
官网链接:http://www.libsdl.org/
我们在 SurfaceView 里面,
//内部类
class MyView extends SurfaceView implements SurfaceHolder.Callback{SurfaceHolder holder;
public MyView(Context context) {
super(context);
holder = this.getHolder();//获取 holder
holder.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
t = new Thread(this);
t.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void run() {
// Much of this code is from GLSurfaceView in the Google API Demos. // I encourage those interested to look there for documentation. //创建一个 EGL 实例
EGL10 egl = (EGL10)EGLContext.getEGL();
//
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
//初始化 EGLDisplay
int[] version = new int[2];
egl.eglInitialize(dpy, version);
int[] configSpec = {
EGL10.EGL_RED_SIZE, 5, EGL10.EGL_GREEN_SIZE, 6, EGL10.EGL_BLUE_SIZE, 5, EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
//选择 config 创建 opengl 运行环境egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
EGLConfig config = configs[0];
EGLContext context = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null);
//创建新的 surface
EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, holder, null);
//将 opengles 环境设置为当前
egl.eglMakeCurrent(dpy, surface, surface, context);
//获取当前 opengles 画布
GL10 gl = (GL10)context.getGL();
init(gl);
int delta = -1;
if (fps > 0) {
delta = 1000/fps;
}
long time = System.currentTimeMillis();
running = true;
while (running) {
int w, h;
synchronized(this) {
w = width;
h = height;
}
if (System.currentTimeMillis()-time < delta) {
try {
Thread.sleep(System.currentTimeMillis()-time);
}
catch (InterruptedException ex) {}
}
drawFrame(gl, w, h);
//显示绘制结果到屏幕上
egl.eglSwapBuffers(dpy, surface);
if (egl.eglGetError() == EGL11.EGL_CONTEXT_LOST) {
Context c = getContext();
if (c instanceof Activity) {
((Activity)c).finish();
}
}
time = System.currentTimeMillis();
}
egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(dpy, surface);
egl.eglDestroyContext(dpy, context);
egl.eglTerminate(dpy);
}
private void drawFrame(GL10 gl, int w, int h) {
if (resize) {
resize(gl, w, h);
resize = false;
}
drawFrame(gl);
}
protected void resize(GL10 gl, int w, int h) {
gl.glMatrixMode(GL10.GL_PROJECTION);//GL_PROJECTION,对投影矩阵应用随后
的矩阵操作. gl.glLoadIdentity();//重置当前指定的矩阵为单位矩阵
gl.glViewport(0,0,w,h);
GLU.gluPerspective(gl, 45.0f, ((float)w)/h, 1f, 100f);
}
}
这里面我们主要关注什么?
其实是 hodler 这个是怎么关联住的。我们看下这个就晓得了,在分析的时候,一定是要去
思考,关联。
在掌握的时候,一定记住一个关键因素,输入,控制,输出。忽略掉细枝末节,形成框架思
维