初始化OpenGL
我們通過搭建一個簡單OpenGL的項目,然后一步步細(xì)化,了解其中的奧秘。
書籍地址PDF:OpenGL ES2.0 應(yīng)用開發(fā)實踐指南Android卷
源碼地址:https://github.com/maimingliang/OpenGLDemo
初始化GLSurfaceView
GLSurfaceView是一個視圖,繼承至SurfaceView,通過內(nèi)嵌的“surface”的特定內(nèi)存區(qū)域完成對OpenGL的渲染。
GLSurfaceView的特性:
- 管理一個surface,這個surface就是一塊特殊的內(nèi)存,能直接排版到android的視圖view上。
- 管理一個EGL display,它能讓opengl把內(nèi)容渲染到上述的surface上。
- 用戶自定義渲染器(render)。
- 讓渲染器在獨立的線程里運作,和UI線程分離。
- 支持按需渲染(on-demand)和連續(xù)渲染(continuous)。
- 一些可選工具,如調(diào)試。
創(chuàng)建GLSurfaceView實例:
mGLSurfaceView = new GLSurfaceView(this);
initGl();
setContentView(mGLSurfaceView);
private void initGl() {
//判斷是否支持OpenGL 2.0
if (!Utils.isSuppostEs2(this)) {
Toast.makeText(this,"does suppost es 2.0 ",Toast.LENGTH_SHORT).show();
return;
}
mGLSurfaceView.setEGLContextClientVersion(2);
}
判斷是否支持OpenGL 2.0
/**
*判斷是否支持OpenGL 2.0
*/
public static boolean isSuppostEs2(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo deviceConfigurationInfo = activityManager.getDeviceConfigurationInfo();
int version = deviceConfigurationInfo.reqGlEsVersion;
if(version >= 0x20000){
return true;
}
return false;
}
處理一下生命周期事件
@Override
protected void onResume() {
super.onResume();
if (rendererSet) {
mGLSurfaceView.onResume();
}
}
@Override
protected void onPause() {
super.onPause();
if (rendererSet) {
mGLSurfaceView.onPause();
}
}
創(chuàng)建Renderer類
Renderer渲染器,GLSurfaceView會在一個單獨的線程調(diào)用渲染器的方法,默認(rèn)的情況下,GLSurfaceView會以顯示設(shè)備刷新頻率不斷的渲染。
Renderer是一個接口,定義了三個方法:
onSurfaceCreated:當(dāng)Surface被創(chuàng)建的時候,GLSurfaceView會調(diào)用這個方法 ,這發(fā)生在應(yīng)用程序第一次運行的時候,并且,當(dāng)設(shè)備喚醒或者用戶從其他Activity切換回來時,這個方法也可能被調(diào)用。
onSurfaceChanged:在surface創(chuàng)建以后,每次surface尺寸的變化,這個方法都會別調(diào)用。比如橫豎屏切換。
onDrawFrame:當(dāng)繪制一幀時,這個方法就會別調(diào)用,在這個方法中,我們一定要繪制點東西,即使只是清空屏幕;因為這個方法調(diào)用后,渲染緩沖區(qū)就會交換顯示到屏幕上,如果什么都沒有繪制,屏幕可能出現(xiàn)閃爍的情況。
public class MyRender implements GLSurfaceView.Renderer {
private Context mContext;
public MyRender(Context context) {
mContext = context;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//設(shè)置清空屏幕用的顏色,分別對應(yīng)紅色、綠色和藍(lán)色,最后一個為透明度。
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//設(shè)置了視口尺寸,告訴 OpenGL 可以用來渲染的 surface 的大小。
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
//會擦除屏幕上的所有顏色,并用 glClearColor 中的顏色填充整個屏幕。
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
}
Renderer與GLSurfaceView關(guān)聯(lián)
private void initGl() {
if (!Utils.isSuppostEs2(this)) {
Toast.makeText(this,"does suppost es 2.0 ",Toast.LENGTH_SHORT).show();
return;
}
mGLSurfaceView.setEGLContextClientVersion(2);
//設(shè)置GLSurfaceView關(guān)聯(lián)的Renderer
mGLSurfaceView.setRenderer(new AirHockeyRenderer(this));
rendererSet = true;
}
將程序運行起來了,你將看到一個完全紅色的屏幕。
END