为什么我的opengl输出因各种设备而异?

时间:2013-06-19 08:57:29

标签: android opengl-es

我创建了一个用于绘制线条,圆圈的Android应用程序......在OpenGLES 2.0中使用GLSurfaceView,就像一个Auto cad app。

该应用适用于Google Nexus 7,因为如果我们画一条线和然后一个圆圈线不会在表面视图中被删除。但是使用三星Galaxy Note II,它完全不同。

先前在绘制圆圈之前绘制的线会被删除。也就是说,每当我们绘制一个新的线或圆时,前一个被擦除。我一次只能绘制一个图像。我需要的是与三星Galaxy Note II中的谷歌Nexus 7相同的输出。我想一次在GLSurfaceView中绘制多个图像。

注意: 谷歌Nexus 7和三星Galaxy Note II的Android操作系统都是Jelly Bean 4.2。但这两种设备都是不同的GPU。谷歌Nexus 7 GPU是ULP GeForce&三星Galaxy Note II是Mali400MP。

这会在Surfaceview的输出渲染中出现问题吗?

编码时我们应该考虑GPU吗?

有谁能告诉我为什么不同设备中不同输出的问题?

2 个答案:

答案 0 :(得分:4)

  

编码时我们应该考虑GPU吗?没办法,OpenGL API是应用程序和硬件之间的一层。

这对桌面图形来说非常正确,因为所有GPU都是即时渲染器,但是,移动图形并非如此。

Mali GPU使用基于图块的立即模式渲染。 对于这种类型的渲染,帧缓冲区被划分为大小为16乘16像素的区块。 Polygon List Builder(PLB)将应用程序的输入数据组织到多边形列表中。每个图块都有一个多边形列表。当图元覆盖图块的一部分时,称为多边形列表命令的条目被添加到图块的多边形列表中。 像素处理器获取一个图块的多边形列表,并在开始处理下一个图块之前计算该图块中所有像素的值。因为这种基于区块的方法使用快速的片上瓦片缓冲区,所以GPU仅将区块缓冲区内容写入每个区块末尾的主存储器中的帧缓冲区。基于非平铺的立即模式渲染器通常需要更多的帧缓冲访问。因此,基于磁贴的方法消耗更少的内存带宽,并且有效地支持深度测试,混合和抗锯齿等操作。

另一个区别是渲染缓冲区的处理。立即渲染器将“保存”缓冲区的内容,有效地允许您仅在先前存在的情况下绘制渲染场景中的差异。但是,这在马里可用,默认情况下不启用,因为如果使用不当会导致不良影响。

关于如何在GLES2 SDK here

中正确使用“EGL Preserve”的Mali GLES2 SDK示例

基于Geforce ULP的nexus 7按预期工作的原因是,作为基于立即的渲染器,它默认保留缓冲区,而Mali不支持。

来自Khronos EGL规范:

  

EGL_SWAP_BEHAVIOR

     

指定使用eglSwapBuffers发布曲面的颜色缓冲区的效果。值EGL_BUFFER_PRESERVED表示颜色缓冲区内容不受影响,而EGL_BUFFER_DESTROYED表示操作可能会破坏或更改颜色缓冲区内容。

     

* 实施选择EGL_SWAP_BEHAVIOR的初始值。*

Mali平台上EGL_SWAP_BEHAVIOUR的默认值为EGL_BUFFER_DESTROYED。这是由于在渲染新帧之前必须从内存中获取前一个缓冲区并将其存储在最后以及带宽消耗(这对于移动设备上的电池寿命也非常糟糕)而导致的性能损失。我无法肯定地评论Tegra SoC的默认行为,但是很明显,我的默认值是EGL_BUFFER_PRESERVED。

澄清马里在Khronos GLES规格方面的立场 - 马里完全合规。

答案 1 :(得分:0)

我还没有看到你的代码,但你可能做错了什么。 也许你交换缓冲区,擦除它等等你不能在那里。

  

编码时我们应该考虑GPU吗?   没办法,OpenGL API是应用程序和硬件之间的一层。