我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式
Posted 字节卷动
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式相关的知识,希望对你有一定的参考价值。
扫码下方二维码,关注微信公众号【字节卷动】!
一、介绍一下GLSurfaceView的两种renderMode
1.1 两种渲染模式
OpenGl ES关于GLSurfaceView的渲染模式 有以下两种:RENDERMODE_CONTINUOUSLY
和RENDERMODE_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
..... 不停地调用
三、总结
- OpenGl ES关于GLSurfaceView的渲染模式 有以下两种:
RENDERMODE_CONTINUOUSLY
和RENDERMODE_WHEN_DIRTY
- 一般设置为
RENDERMODE_WHEN_DIRTY
方式,当视图不需要更新时,允许GPU和CPU空闲,这样不会让CPU和GPU一直处于高速运转状态,提高电池寿命和整体系统性能 - 当需要重绘时,调用
GLSurfaceView.requestRender()
以上是关于我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式的主要内容,如果未能解决你的问题,请参考以下文章
我的OpenGL学习进阶之旅关于OpenGL ES 开启深度测试,直接黑屏的问题的解决方法
我的OpenGL学习进阶之旅关于OpenGL ES 开启深度测试,直接黑屏的问题的解决方法
我的OpenGL学习进阶之旅关于OpenGL ES 绘制纹理,因为加载纹理坐标设置错误,导致纹理无法渲染的问题
我的OpenGL学习进阶之旅关于OpenGL ES 绘制纹理,因为加载纹理坐标设置错误,导致纹理无法渲染的问题