【发布时间】:2015-07-03 11:23:28
【问题描述】:
我正在使用 XNA 4.0 内容管道构建一些自定义内容类型。
我的类TerrainModelSetContent 和TerrainModelSet 分别有一个自定义ContentTypeWriter 和ContentTypeReader,它们分别是构建时间和运行时间类。
地形模型集当然包括/是用于关卡地形部分的模型集合,因此将一个或多个模型顺序序列化为单个 .xnb 内容文件。
无论如何,我能找到的几乎所有 XNA 文档或教程(来自 Microsoft 或其他)都清楚地表明 XNA 已经为模型提供了一个开箱即用的 Writer 和 Reader。
所以我的问题是,为什么它在写入和读取之间不保留任何实际模型数据?它只保留了诸如BoundingSpheres 和PrimitiveCounts 之类的琐碎的额外内容——在顶点或索引缓冲区中没有任何实际几何图形,它必须保留这些东西才能远程使用。
在构建时,TerrainModelSet 通过此类的 Write(...) 函数序列化为 .xnb 文件:
[ContentTypeWriter]
public class TerrainModelSetWriter : ContentTypeWriter<TerrainModelSetContent>
{
protected override void Write(ContentWriter output, TerrainModelSetContent value) {
//Write starting TerrainModelSet data...
output.Write(value.GraphicsMeshes.Count); //value.GraphicsMeshes is a dictionary of string-keys and ModelContent-values.
foreach (KeyValuePair<string, ModelContent> item in value.GraphicsMeshes) {
output.Write(item.Key);
//At this point, all geometry data is present in the Vertex and
//Index buffers of the Model item.Value's ModelMesh's
//ModelMeshParts, nice and neat how we would expect it. I made
//sure if this with the debugger.
output.WriteObject<ModelContent>(item.Value);
}
}
//GetRuntimeReader(...) and GetRuntimeType(...) functions are overridden here as well.
}
TerrainModelSet 当然会在运行时在相应类的 Read(...) 方法中反序列化:
public class TerrainModelSetReader : ContentTypeReader<TerrainModelSet>
{
protected override TerrainModelSet Read(ContentReader input, TerrainModelSet existingInstance) {
if (existingInstance == null)
existingInstance = new TerrainModelSet();
//Read starting TerrainModelSet data...
int numItems = input.ReadInt32();
for (int i = 0; i < numItems; i++) {
string itemName = input.ReadString();
Model m = input.ReadObject<Model>();
//Here, we use the debugger again to check the state of m, and
//find that the XNA Framework Content Pipeline has UTTERLY
//FAILED to preserve ANY of the geomentry data.
//All Vertex and Index buffers in any ModelMeshParts of any
//ModelMeshes of m are null. Not even empty, just null. WTF?
existingInstance.GraphicsMeshes.Add(itemName, m.Meshes[0]);
existingInstance.CollisionMeshes.Add(itemName, CollisionMesh.FromModelMesh(m.Meshes[0]));
}
}
}
在 Write 调用之前,所有几何图形都已存在——在其适当的缓冲区中很好且整洁。我已经用调试器检查过了。但是,在 Read 调用之后,m 的网格中的所有缓冲区都为空。它们甚至不是空的——只是空的。这里发生了什么?谁能赐教?
【问题讨论】: