【问题标题】:Fastest way to draw sprites in opengles 2.0 on android在android上的opengles 2.0中绘制精灵的最快方法
【发布时间】:2015-06-15 04:58:32
【问题描述】:

所以我试图弄清楚如何多次绘制单个纹理四边形。我的问题是,由于这些是创建和删除的,而且它们中的每一个都有一个独特的位置和旋转。我不确定 vbo 是否是最好的解决方案,因为我听说在 android 上修改缓冲区非常慢,而且似乎我需要每帧创建一个新的缓冲区,因为不同的四边形可能会随机消失(与敌人碰撞)。如果我只是为每个画图调用,我会在 100 左右得到 20fps,这是无法使用的。有什么建议吗?

编辑:我正在尝试创建一个弹幕,但弄清楚如何绘制 500 多件东西让我很头疼。

【问题讨论】:

    标签: android performance opengl-es opengl-es-2.0


    【解决方案1】:

    我认为你在追求粒子系统。类似的问题在这里:Drawing many textured particles quickly in OpenGL ES 1.1

    使用点精灵很便宜,但是你必须在片段着色器中做额外的工作,如果你需要不同大小的粒子,我不确定 GLES2 是否支持gl_PointSizegl_PointSize Corresponding to World Space Size

    我的首选粒子系统将位置存储在双缓冲纹理中,然后使用单个绘制调用和静态四边形数组进行绘制。 This 是相关的,但我会在这里多描述一下...

    1. 创建纹理(如果可以,可以使用浮点,但这可能会限制支持的设备)。每个像素都保存着粒子位置和可能的旋转信息。
    2. [已编辑] 如果您需要对粒子进行动画处理,您需要更改每帧纹理中的值。为了让它更快,让 GPU 在着色器中完成它。使用 FBO,绘制全屏多边形并更新片段着色器中的值。问题是您不能读取和写入相同的纹理(或不应该)。常见的方法是通过创建第二个要渲染的纹理来双重缓冲纹理,同时从第一个读取,然后在它们之间进行乒乓操作。
    3. 创建用于绘制三角形的 VBO。位置都是一样的,填充一个-1到1的四边形。但是,将每个四边形的纹理坐标设置为上述纹理中的正确像素。
    4. 绘制 VBO,绑定你的位置纹理。在顶点着色器中,读取给定顶点纹理坐标的位置。将 -1 到 1 的顶点位置缩放到正确的大小,应用位置和任何旋转。使用原始的 -1 到 1 位置作为纹理坐标传递给片段着色器以添加任何常规颜色纹理。

      如果您曾经有一个带有gl_Vertex 的 GLSL 版本,我非常喜欢在顶点着色器中生成这些坐标,从而节省存储不必要的琐碎数据以绘制简单对象。 This for example.

    5. 要生成粒子,请使用glTexSubImage2D 并将一个粒子块写入位置纹理。如果您开始存储更多粒子属性,您可能需要一些纹理。

    【讨论】:

    • 所以你的意思是我创建一个纹理(一张图片)然后我使用RGBA通道来对应XYZR。将此纹理传递给顶点着色器,然后创建一个点数与纹理中像素相同的 vbo。然后,绘制一堆点精灵,它们将显示我希望它们显示的实际图片?另外,我不确定你所说的数字 2 是什么意思
    • @Metalith 是的,尽管如果点精灵受到限制,您可能希望使用三角形(6 个顶点 = 两个三角形用于四边形,纹理中的每个像素)。第 2 点用于动态更新纹理,因此您的粒子可以随时间移动。会更新的。
    • 嗯,很有趣。为什么有两个纹理?我不能只使用一个并在 onDrawFrame() 的开头更新它并使用它吗?抱歉不理解
    • @Metalith 是的,但是 CPU 在动画时会比 GPU 慢。移动设备具有共享内存 (afaik),因此传输可能不是什么大问题,但在桌面上将纹理流式传输到 GPU 每一帧都非常慢。
    • 啊...我明白了。那么非常感谢你
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多