阅读本文前如果是初次接触opengl可以先阅读前文:
openGL 3D图形和openGL简介:
http://blog.csdn.net/pangrui201/article/details/75091501

android上opengl es基础知识

           Google在Android2.2 以后支持 opengl es 2.2,在Android 4.3以后引入opengl es 3.0。Android中使用openGL会用到GLSurfaceView控件, GLSurfaceView.Renderer,在Android studio的debug模式下我们可以清楚的看到Renderer的各个回调函数发生在非UI主线程,即渲染线程,具体渲染是在一块称为”surface”(在openGL里面称为ViewPort视口)的地方完成,渲染绘制完成后在将渲染结果直接在主线程显示,实际上GLSurfaceView在View Hierarchy上”穿洞”,让底层open gl surface显示出来。同时,需要考虑GLSurfaceView和Activity的各个生命周期的问题。
另一方面,在Android 4.0以后提供了一个纹理视图(TextureView)可以也可以渲染opengl,TextureView像普通view一样不在需要”穿洞”了,但是TextureView没有内置opengl的初始化操作。

第一个opengl es程序

如下代码是在Android studio上创建的第一个opengl es项目:

public class MainActivity extends AppCompatActivity {    private GLSurfaceView glSurfaceView;    private boolean rendererSet;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        glSurfaceView = new GLSurfaceView(this);        // Check if the system supports OpenGL ES 2.0.        final ActivityManager activityManager =                (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);        final ConfigurationInfo configurationInfo =                activityManager.getDeviceConfigurationInfo();        /*        final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;         */        // Even though the latest emulator supports OpenGL ES 2.0,        // it has a bug where it doesn't set the reqGlEsVersion so        // the above check doesn't work. The below will detect if the        // app is running on an emulator, and assume that it supports        // OpenGL ES 2.0.        final boolean supportsEs2 =                configurationInfo.reqGlEsVersion >= 0x20000                        || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1                        && (Build.FINGERPRINT.startsWith("generic")                        || Build.FINGERPRINT.startsWith("unknown")                        || Build.MODEL.contains("google_sdk")                        || Build.MODEL.contains("Emulator")                        || Build.MODEL.contains("Android SDK built for x86")));        if (supportsEs2) {            // Request an OpenGL ES 2.0 compatible context.            glSurfaceView.setEGLContextClientVersion(2);            // Assign our renderer.            glSurfaceView.setRenderer(new FirstOpenGLProjectRenderer());            rendererSet = true;        } else {            /*             * This is where you could create an OpenGL ES 1.x compatible             * renderer if you wanted to support both ES 1 and ES 2. Since we're             * not doing anything, the app will crash if the device doesn't             * support OpenGL ES 2.0. If we publish on the market, we should             * also add the following to AndroidManifest.xml:             *              *              *              * This hides our app from those devices which don't support OpenGL             * ES 2.0.             */            Toast.makeText(this, "This device does not support OpenGL ES 2.0.",                    Toast.LENGTH_LONG).show();            return;        }        setContentView(glSurfaceView);    }    @Override    protected void onPause() {        super.onPause();        if (rendererSet) {            glSurfaceView.onPause();        }    }    @Override    protected void onResume() {        super.onResume();        if (rendererSet) {            glSurfaceView.onResume();        }    }}

supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;是用来判断是否支持opengl es2.0,同时在模拟器的话可能支持不是多好,所以代码进行了判断。 glSurfaceView.setEGLContextClientVersion(2);是来具体设置opengl版本,配置surface视图。同时需要注意Activity的生命周期需要回调glSurfaceView对应的生命周期,这样surface视图才能正确处理渲染线程暂停和继续,同时释放和续用opengl的上下文。

下面是FirstOpenGLProjectRenderer 的代码:

public class FirstOpenGLProjectRenderer implements Renderer {    @Override    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {        // Set the background clear color to red. The first component is        // red, the second is green, the third is blue, and the last        // component is alpha, which we don't use in this lesson.        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);    }    /**     * onSurfaceChanged is called whenever the surface has changed. This is     * called at least once when the surface is initialized. Keep in mind that     * Android normally restarts an Activity on rotation, and in that case, the     * renderer will be destroyed and a new one created.     *      * @param width     *            The new width, in pixels.     * @param height     *            The new height, in pixels.     */    @Override    public void onSurfaceChanged(GL10 glUnused, int width, int height) {        // Set the OpenGL viewport to fill the entire surface.        glViewport(0, 0, width, height);    }    /**     * OnDrawFrame is called whenever a new frame needs to be drawn. Normally,     * this is done at the refresh rate of the screen.     */    @Override    public void onDrawFrame(GL10 glUnused) {        // Clear the rendering surface.        glClear(GL_COLOR_BUFFER_BIT);    }}

主要有三个回调方法,onSurfaceCreated,onSurfaceChanged,onDrawFrame。之前已经说过了,这些方法回调发生在渲染线程。onSurfaceCreated是在surface被创建时,GLSurfaceView会回调这个方法。onSurfaceChanged是在surface被创建后每次在surface尺寸发生变化的时候GLSurfaceView会回调,比如横竖屏切换会回调这个方法。onDrawFrame是当每绘制一帧就会被GLSurfaceView回调,通常一定要在这个方法里做点事情哪怕是设置清屏颜色,因为这个方法调用之后会把渲染结果surface给屏幕显示,不能说什么都没有,这样的话可能会显示花屏。另外,通常GLSurfaceView会以显示屏的的刷新频率来回调onDrawFrame进行渲染,当然我们可以设置GLSurfaceView的渲染模式来修改,调用
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
//GLSurfaceView.RENDERMODE_CONTINUOUSLY:持续渲染(默认)
//GLSurfaceView.RENDERMODE_WHEN_DIRTY:脏渲染,命令渲染;即有两种渲染模式脏渲染和持续渲染(默认)。使用脏渲染需要和glSurfaceView.requestRender配合使用。
           综上分析,在onSurfaceCreated里需要设置清屏色,本文为红色 glClearColor(1.0f, 0.0f, 0.0f, 0.0f);在onSurfaceChanged里设置视口viewport大小即通知opengl需要渲染视口大小即surface大小。注意:视口viewport是opengl里面的概念,surface是GLSurfaceView里提供给底层渲染显示的区域,故可以理解为同一个。在onDrawFrame里面 glClear(GL_COLOR_BUFFER_BIT);是清楚所有颜色缓冲器,这样就会显示清屏色即 glClearColor(1.0f, 0.0f, 0.0f, 0.0f)设置的红色。
           到此,本文章结束。主要讲解基础概念,基础原理。本文代码地址:
https://github.com/pangrui201/OpenGlesProject/tree/master/OpenGlesProject_lesson1

更多相关文章

  1. opengl es demo(有附件)
  2. Android(安卓)Local Service
  3. Android(安卓)KeyEvent分发机制
  4. Android(安卓)Inflate方法
  5. android Launcher之获取安装的app列表的两种方法
  6. Android(安卓)自定义RecyclerView 实现真正的Gallery效果
  7. android 控制震动强度
  8. android studio 设置模板
  9. Android使用广播(BroadCast)实现强制下线的方法

随机推荐

  1. Android跨进程通信IPC之5——Binder的三
  2. Android(安卓)核心分析(13) -----Android
  3. Android工具箱之迁移到AppCompat
  4. Android(安卓)Binder原理(四)ServiceManage
  5. android:id="@android:id/tabhost" 、and
  6. Android真响应式架构——MvRx
  7. Android(安卓)多进程通信之几个基本问题
  8. Android百度地图开发(五):图层
  9. Android(安卓)Binder原理(三)系统服务的注
  10. Android跨进程通信IPC之3——关于"JNI"的