Metal/OpenGL: 如何只设置一次顶点缓冲区?

Metal/OpenGL: How to set vertex buffer only once?

我经历了https://www.raywenderlich.com/146414/metal-tutorial-swift-3-part-1-getting-started。对于每一帧

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0)
renderEncoder.setFragmentTexture(texture, at: 0)

完成。但是顶点和纹理数据永远不会改变。只有统一矩阵发生变化。我正在渲染的对象包含 8*4*4*4*4 个三角形(是的,它是一个球体)。我只能得到 4FPS。我对每帧都设置 vertexBuffer 持怀疑态度。

它在 OpenGL 教程中的做法类似 http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/

在 OpenGL 中,我可以从渲染循环中提取 vertex/texture 缓冲区绑定。但是在 Metal 中 MTLRenderCommandEncoder 需要 CAMetalDrawable,它是为每一帧获取的。

您通常会为每一帧使用新的渲染命令编码器。当该编码器结束并且您删除对它的任何引用时,您对之前的渲染命令编码器所做的任何事情,如设置顶点缓冲区或片段纹理,都是 "lost"。所以,是的,您需要再次设置缓冲区和纹理。

不过,那应该不贵。这两种方法都只是将缓冲区或纹理的 引用 放入 table 中。它很便宜。如果您没有在 CPU 上修改它们的内容,则无需复制任何数据。它也不应该导致任何状态编译。 (Apple 表示 Metal 的一个设计目标是避免任何隐式状态编译。它都是显式的,例如从渲染管道描述符创建渲染管道状态对象时。)

您需要分析您的应用以找出限制帧速率的因素,而不是猜测。