Directx11 如何管理多个 vertex/index 缓冲区?
Directx11 How to manage multiple vertex/index buffers?
我在学习 DirectX11 的同时正在开发一个小型游戏框架。
使用 BufferManager
class(可能是静态的)来处理实时或之前创建的模型的所有顶点和索引数据的最佳方法可能是什么。 class 应该负责根据模型信息创建动态或静态缓冲区,然后绘制它们。
- 我是否应该有一个顶点和索引向量列表并将所有新模型附加到它...然后重新创建缓冲区,每当附加新数据并在绘制之前设置新缓冲区。
- 我是否应该为模型设置单独的顶点和索引缓冲区,访问相应模型的缓冲区并在每次绘制调用之前设置为
IASetVertexBuffer(model[i].getVertBuff())
;
- 还有一些模型可以是动态的而另一些是静态的,我如何在这里进行批处理?
此处未显示任何代码,但您请求的构造如下:
- 为纹理、模型网格、顶点数据、法线、音频等创建文件加载器
- 拥有一个可重复使用的结构,用于存储模型的特定网格的所有这些数据。
- 创建它时,您还需要一个单独的纹理 class 来保存有关不同纹理的信息。这样可以为不同的模型或网格引用相同的纹理,并且您不必每次都将它们加载到内存中。
- 对于不同的网格也可以这样做;您可以引用一个可能属于不同模型对象的网格。
- 为此,您需要一个 Asset Storage class 来管理您的所有资产。这样,如果资产已经在内存中,则不会再次加载它;例如字体、纹理、模型、音频文件等
- 然后您需要的下一部分是批处理 class 和批处理管理器 class
- 批处理 class 将根据几个参数定义批处理所基于的容器:原始类型,是否具有透明度(优先队列)等。
- 批次管理器class 将进行组织并将批次发送到渲染阶段。这个 class 也将用于说明一个批次可以容纳多少个顶点以及你有多少个批次(桶)。该比例将取决于游戏内容。对于基本的 2D 精灵类型应用程序,一个好的比例是大约 10 个批次,其中每个批次包含不少于 10,000 个顶点。下一步是根据基元类型及其优先级(alpha 通道 - 对于 Z 深度)填充类似类型的桶,如果一个桶不能容纳数据,它将寻找另一个桶来填充。如果没有可用的桶来保存数据,那么批处理管理器将寻找最高优先级队列中填充最多的桶,它将将该批发送到要渲染的视频卡,然后它将重新使用该桶。
- 最后一部分是 ShaderManager class 来管理您的程序将使用的不同类型的着色器。所以所有这些 classes 或结构都将捆绑在一起。
如果您设计得当,您可以将所有引擎行为和责任从实际的游戏内容、属性和逻辑或规则集中抽象出来。这样您的游戏引擎就可以重复用于多个游戏。这样你的引擎就不会依赖于特定的游戏,当你准备好重用它时,你所要做的就是创建一个从这个静态或动态库继承的主项目,所有的引擎组件都将被合并进入下一场比赛。这种代码分离是通用可重用代码的绝佳方法。
为了更好地展示这种方法,我建议您查看此网站 www.MarekKnows.com 并按照着色器引擎系列视频教程进行操作。虽然这个特定的网站专注于 C++ 中的 Win32,但使用 OpenGL 而不是 DirectX。然而,整体设计模式具有相同的概念。唯一的区别是去除 OpenGL 部分并用 DirectX 替换它们 API.
编辑 - 其他参考资料:
- Geometric Tools
- Rastertek
- 3D Buzz
- Learn OpenGL
- GPU Gems by NVidia
- Batches PDF by NVidia
- Hieroglyph3 @ Codeplex
我还发现了 Marek Krzeminski 撰写的关于批处理渲染过程的文章,该文章来自他的视频教程,但可以在此处找到 Batch Rendering by Marek at Gamedev
我在学习 DirectX11 的同时正在开发一个小型游戏框架。
使用 BufferManager
class(可能是静态的)来处理实时或之前创建的模型的所有顶点和索引数据的最佳方法可能是什么。 class 应该负责根据模型信息创建动态或静态缓冲区,然后绘制它们。
- 我是否应该有一个顶点和索引向量列表并将所有新模型附加到它...然后重新创建缓冲区,每当附加新数据并在绘制之前设置新缓冲区。
- 我是否应该为模型设置单独的顶点和索引缓冲区,访问相应模型的缓冲区并在每次绘制调用之前设置为
IASetVertexBuffer(model[i].getVertBuff())
; - 还有一些模型可以是动态的而另一些是静态的,我如何在这里进行批处理?
此处未显示任何代码,但您请求的构造如下:
- 为纹理、模型网格、顶点数据、法线、音频等创建文件加载器
- 拥有一个可重复使用的结构,用于存储模型的特定网格的所有这些数据。
- 创建它时,您还需要一个单独的纹理 class 来保存有关不同纹理的信息。这样可以为不同的模型或网格引用相同的纹理,并且您不必每次都将它们加载到内存中。
- 对于不同的网格也可以这样做;您可以引用一个可能属于不同模型对象的网格。
- 为此,您需要一个 Asset Storage class 来管理您的所有资产。这样,如果资产已经在内存中,则不会再次加载它;例如字体、纹理、模型、音频文件等
- 然后您需要的下一部分是批处理 class 和批处理管理器 class
- 批处理 class 将根据几个参数定义批处理所基于的容器:原始类型,是否具有透明度(优先队列)等。
- 批次管理器class 将进行组织并将批次发送到渲染阶段。这个 class 也将用于说明一个批次可以容纳多少个顶点以及你有多少个批次(桶)。该比例将取决于游戏内容。对于基本的 2D 精灵类型应用程序,一个好的比例是大约 10 个批次,其中每个批次包含不少于 10,000 个顶点。下一步是根据基元类型及其优先级(alpha 通道 - 对于 Z 深度)填充类似类型的桶,如果一个桶不能容纳数据,它将寻找另一个桶来填充。如果没有可用的桶来保存数据,那么批处理管理器将寻找最高优先级队列中填充最多的桶,它将将该批发送到要渲染的视频卡,然后它将重新使用该桶。
- 最后一部分是 ShaderManager class 来管理您的程序将使用的不同类型的着色器。所以所有这些 classes 或结构都将捆绑在一起。
如果您设计得当,您可以将所有引擎行为和责任从实际的游戏内容、属性和逻辑或规则集中抽象出来。这样您的游戏引擎就可以重复用于多个游戏。这样你的引擎就不会依赖于特定的游戏,当你准备好重用它时,你所要做的就是创建一个从这个静态或动态库继承的主项目,所有的引擎组件都将被合并进入下一场比赛。这种代码分离是通用可重用代码的绝佳方法。
为了更好地展示这种方法,我建议您查看此网站 www.MarekKnows.com 并按照着色器引擎系列视频教程进行操作。虽然这个特定的网站专注于 C++ 中的 Win32,但使用 OpenGL 而不是 DirectX。然而,整体设计模式具有相同的概念。唯一的区别是去除 OpenGL 部分并用 DirectX 替换它们 API.
编辑 - 其他参考资料:
- Geometric Tools
- Rastertek
- 3D Buzz
- Learn OpenGL
- GPU Gems by NVidia
- Batches PDF by NVidia
- Hieroglyph3 @ Codeplex
我还发现了 Marek Krzeminski 撰写的关于批处理渲染过程的文章,该文章来自他的视频教程,但可以在此处找到 Batch Rendering by Marek at Gamedev