android OpenGL(一) 开始准备

写几篇文章记录一下我学习OpenGL的过程,这是第一篇。本片文章通过实现一个清屏操作,先了解一些基本知识。

1.创建一个activity,作为展示页面:

/**
 * 视图展示页面,只实现了清屏的操作<br/>
 * 1.创建GLSurfaceView<br/>
 * 2.调用GLSurfaceView的setRenderer方法,设置Renderer<br/>
 * 3.实现Renderer<br/>
 * 4.处理Activity的生命周期事件<br/>
 */
public class FirstOpenGLActivity extends AppCompatActivity {
    private static final String TAG = FirstOpenGLActivity.class.getSimpleName();

    private GLSurfaceView mGLSurfaceView;
    /**
     * is render seted
     */
    private boolean isRendererSet = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLSurfaceView = new GLSurfaceView(this);

        //检察系统是否支持OpenGL ES 2.0
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
        boolean isSupportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
        Log.d(TAG, "isSupportsEs2 =" + isSupportsEs2);

        if (isSupportsEs2) {
            //Request an OpenGL ES 2.0 compatible context
            mGLSurfaceView.setEGLContextClientVersion(2);

            //Assign our renderer
            //当surface创建或者发生变化的时候,以及要绘制一副新帧时,渲染器都会被GLSurfaceView调用
            mGLSurfaceView.setRenderer(new FirstOpenGLRenderer());
            isRendererSet = true;
        } else {
            Toast.makeText(this, "this device dose not support OpenGL ES 2.0", Toast.LENGTH_SHORT);
        }

        setContentView(mGLSurfaceView);
    }


    //页面恢复,继续后台渲染线程,续用OpenGL上下文
    @Override
    protected void onResume() {
        super.onResume();
        if (isRendererSet) {
            mGLSurfaceView.onResume();
        }
    }

    //页面不可见,暂停后台渲染线程,释放OpenGL上下文
    @Override
    protected void onPause() {
        super.onPause();
        if (isRendererSet) {
            mGLSurfaceView.onPause();
        }
    }
}

 2.创建一个渲染器类实现Renderer接口:

/**
 * 渲染器类 实现了Renderer接口
 * Created by hsji on 16/1/10.
 */
public class FirstOpenGLRenderer implements GLSurfaceView.Renderer {
    /**
     * 当surface被创建的时候,GLSurfaceView会调用这个方法;
     * 这发生在应用程序第一次运行的时候,并且,当设备被唤醒或者用户从其他activity切换回来的时,这个方法也可能会被调用。
     * 在实践中,这意味着当程序运行时这个方法可能会被调用多次。
     *
     * @param gl10
     * @param eglConfig
     */
    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        //设置清空屏幕所使用的颜色RGBA
        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    }

    /**
     * 在surface被创建之后,每次surface尺寸发生变化时,这个方法都会被GLSurfaceView调用到。
     * 在横屏、竖屏之间来回切换的时候,Surface的尺寸会发生变化。
     *
     * @param gl10
     * @param width
     * @param height
     */
    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        //set the OpenGL viewport to to fill the entire surface
        GLES20.glViewport(0, 0, width, height);
    }

    /**
     * 当绘制一帧时,这个方法会被GLSurfaceView调用。
     * 在这个方法中我们一定要绘制一些东西,即使只是清空屏幕;
     * 因为,在这个方法返回之后,渲染缓冲区会被交换并显示在屏幕上,
     * 如果什么都没画,可能会看到闪烁效果
     *
     * @param gl10
     */
    @Override
    public void onDrawFrame(GL10 gl10) {
        //clear the rendering surface
        //清空屏幕,擦出屏幕上的所有颜色,并调用之前glClearColor()定义的颜色填充整个屏幕
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    }
}

 一点解释:怎么会有一个未被使用的参数类型GL10呢?

* 他是OpenGL ES 1.0的API遗留下来的;
* 如果要编写使用OpenGL ES 1.0的渲染器,就要使用这个参数,
* 但是对于OpenGL ES 2.0,GLES20类提供了静态方法来存取。

 3.渲染线程和主线程之间的交互(之后还会详细涉及,这里只是一个概要)

    GLSurfaceView会在一个单独的线程中调用渲染器的方法。默认情况下,GLSurfaceView会以显示设备的刷新频率不断的渲染,当然,它也可以配置为按请求渲染,只需要用GLSurfaceView.RENDERMODE_WHEN_DIRTY作为参数调用GLSurfaceView.setRenderMode()即可。
既然android的GLSurfaceView在后台县城中执行渲染,就必须要小心,只能在这个渲染线程中调用OpenGL,在android主线程中使用UI相关的调用;两个线程之间的通信可以使用如下方法:在主线程中的GLSurfaceView实例可以调用queueEvent()方法传递一个Runnable给后台渲染线程,渲染线程就可以调用Activity的runOnUIThread()来传递事件(event)给主线程。

4.运行程序即可看到一个纯红色的屏幕。

posted @ 2016-01-10 19:13  听懂·动听  阅读(4001)  评论(0编辑  收藏  举报