我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式

Posted 字节卷动

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式相关的知识,希望对你有一定的参考价值。

扫码下方二维码,关注微信公众号【字节卷动】!

一、介绍一下GLSurfaceView的两种renderMode

1.1 两种渲染模式

OpenGl ES关于GLSurfaceView的渲染模式 有以下两种:RENDERMODE_CONTINUOUSLYRENDERMODE_WHEN_DIRTY ,如下所示:

    
    /**
     * The renderer only renders
     * when the surface is created, or when @link #requestRender is called.
     *
     * @see #getRenderMode()
     * @see #setRenderMode(int)
     * @see #requestRender()
     */
    public final static int RENDERMODE_WHEN_DIRTY = 0;
    /**
     * The renderer is called
     * continuously to re-render the scene.
     *
     * @see #getRenderMode()
     * @see #setRenderMode(int)
     */
    public final static int RENDERMODE_CONTINUOUSLY = 1;

1.2 两种渲染模式的差异

默认渲染方式为RENDERMODE_CONTINUOUSLY

1.2.1 RENDERMODE_CONTINUOUSLY模式

当设置为RENDERMODE_CONTINUOUSLY时渲染器会不停地渲染场景,

1.2.2 RENDERMODE_WHEN_DIRTY模式

当设置为RENDERMODE_WHEN_DIRTY时只有在创建和调用requestRender()时才会刷新。

一般设置为RENDERMODE_WHEN_DIRTY方式,当视图不需要更新时,允许GPU和CPU空闲,这样不会让CPU和GPU一直处于高速运转状态,提高电池寿命和整体系统性能

1.3 设置渲染模式 android.opengl.GLSurfaceView#setRenderMode


    /**
     * Set the rendering mode. When renderMode is
     * RENDERMODE_CONTINUOUSLY, the renderer is called
     * repeatedly to re-render the scene. When renderMode
     * is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface
     * is created, or when @link #requestRender is called. Defaults to RENDERMODE_CONTINUOUSLY.
     * <p>
     * Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system performance
     * by allowing the GPU and CPU to idle when the view does not need to be updated.
     * <p>
     * This method can only be called after @link #setRenderer(Renderer)
     *
     * @param renderMode one of the RENDERMODE_X constants
     * @see #RENDERMODE_CONTINUOUSLY
     * @see #RENDERMODE_WHEN_DIRTY
     */
    public void setRenderMode(int renderMode) 
        mGLThread.setRenderMode(renderMode);
    

示例:

// a.设置RENDERMODE_CONTINUOUSLY模式
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

// b.设置RENDERMODE_WHEN_DIRTY模式
.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

1.4 requestRender


    /**
     * Request that the renderer render a frame.
     * This method is typically used when the render mode has been set to
     * @link #RENDERMODE_WHEN_DIRTY, so that frames are only rendered on demand.
     * May be called
     * from any thread. Must not be called before a renderer has been set.
     */
    public void requestRender() 
        mGLThread.requestRender();
    

当需要重绘时,调用

GLSurfaceView.requestRender()

二、实际案例

2.1 不同的案例设置不同的渲染模式

创建的时候,根据不同的案例,设置不同的渲染模式

然后调用一下requestRender() 方法

有些案例需要缩放,当需要重绘时,也需要调用一下requestRender()方法


有些案例,需要进行触摸事件做一些旋转之类的效果,当需要重绘时,则需要调用一下 requestRender()

2.2 不同的案例在不同的渲染模式的对比

这样我们来看一下不同的demo在不同的渲染模式下的对比。
我们给下面的三个方法,加上日志打印,然后看对比情况。

 override fun onSurfaceCreated(gl: GL10, config: EGLConfig) 
        Log.d(TAG,"onSurfaceCreated")
        val assetManager: AssetManager = mActivity.assets
        nativeSurfaceCreate(assetManager)
    

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) 
        Log.d(TAG,"onSurfaceChanged")
        nativeSurfaceChange(width, height)
    

    override fun onDrawFrame(gl: GL10) 
        Log.d(TAG,"onDrawFrame")
        nativeDrawFrame()
    

2.2.1 RENDERMODE_WHEN_DIRTY 案例

当我们绘制如下所示的不会不断变化的例子的时候,使用RENDERMODE_WHEN_DIRTY 模式,然后看日志输出

只会运行一次,然后就不再继续调用onDrawFrame方法了

2021-12-12 15:17:17.743 12814-13056/com.oyp.openglesdemo D/MyNativeRenderer: onSurfaceCreated
2021-12-12 15:17:17.744 12814-13056/com.oyp.openglesdemo D/MyNativeRenderer: onSurfaceChanged
2021-12-12 15:17:17.744 12814-13056/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame

2.2.2 RENDERMODE_CONTINUOUSLY 案例

当我们绘制如下所示的不断变化的例子的时候,使用RENDERMODE_CONTINUOUSLY 模式,然后看日志输出

下面的三个三角形在不停的旋转


日志如下所示:

2021-12-12 15:20:59.315 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onSurfaceCreated
2021-12-12 15:20:59.316 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onSurfaceChanged
2021-12-12 15:20:59.316 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.341 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.358 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.852 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.867 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.879 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.904 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:20:59.997 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:00.013 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:00.028 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:00.048 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:01.249 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:01.270 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:03.253 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:03.270 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:03.436 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:03.452 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:04.948 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:04.965 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:05.818 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:05.833 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
2021-12-12 15:21:07.035 12814-13153/com.oyp.openglesdemo D/MyNativeRenderer: onDrawFrame
..... 不停地调用

三、总结

  1. OpenGl ES关于GLSurfaceView的渲染模式 有以下两种:RENDERMODE_CONTINUOUSLYRENDERMODE_WHEN_DIRTY
  2. 一般设置为RENDERMODE_WHEN_DIRTY方式,当视图不需要更新时,允许GPU和CPU空闲,这样不会让CPU和GPU一直处于高速运转状态,提高电池寿命和整体系统性能
  3. 当需要重绘时,调用GLSurfaceView.requestRender()

以上是关于我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式的主要内容,如果未能解决你的问题,请参考以下文章

我的OpenGL学习进阶之旅关于OpenGL ES 开启深度测试,直接黑屏的问题的解决方法

我的OpenGL学习进阶之旅关于OpenGL ES 开启深度测试,直接黑屏的问题的解决方法

我的OpenGL学习进阶之旅关于OpenGL ES 绘制纹理,因为加载纹理坐标设置错误,导致纹理无法渲染的问题

我的OpenGL学习进阶之旅关于OpenGL ES 绘制纹理,因为加载纹理坐标设置错误,导致纹理无法渲染的问题

我的OpenGL学习进阶之旅OpenGL ES 着色语言 (下)

我的OpenGL学习进阶之旅OpenGL ES 着色语言 (下)