1

我刚刚进入 XNA 编程并且无法弄清楚如何从“.x”模型访问纹理。我正在使用自定义着色器来显示我的模型(只是一个贴有纹理的立方体),过滤器设置为点。为此,我需要传递需要与模型分开导入的纹理文件的效果,否则它会抱怨,因为它也包含在我的模型中。这完全符合我的要求,但是当我有许多具有自己纹理的不同模型时,这并不是一个真正令人愉快的方法。

我的问题是:

我如何能够直接从中访问模型中包含的纹理并将其发送到我的着色器?或者我可以直接使用 HLSL 访问它吗?

我试过的:

我发现帖子说它可以分配给一个纹理变量:

Texture2d texture = ((BasicEffect)model.Meshes[0].Effects[0]).Texture

当我尝试这个时,游戏运行但立方体只是黑色的。我可以看到纹理变量保存了信息并且具有正确的尺寸,但我无法判断它是否正确保存了实际图像。当我只使用BasicEffect它们时,它们的纹理渲染得很好。

更新:

经过一番摆弄,我设法让它工作。我的游戏加载了数百个相同的立方体,在创建每个立方体后,它会尝试使用上面的代码保存模型的纹理,然后遍历网格部分并将效果更改为我的自定义效果。我发现创建的第一个立方体可以保存纹理,但任何后续创建的立方体都会抱怨它们不能作为 BasicEffect 投射。这导致了一个带纹理的立方体,然后是很多黑色的。我猜想当它像这样一遍又一遍地重复使用相同的模型时,它只会使用修改后的模型以使用我在多维数据集的第一个实例上完成的自定义效果。这是正常的吗?通过将纹理变量更改为静态,我已将它们全部渲染为纹理。

4

2 回答 2

1

如果其他人对此感到疑惑,因为我正在使用以下方法保存纹理:

Texture2d texture = ((BasicEffect)model.Meshes[0].Effects[0]).Texture

这确实有效,但有一点需要注意,这就是导致我出现问题的原因。如果您将模型的效果从一个实例的默认 BasicEffect 更改为之后创建的模型的每个实例,它将被更改。因此,您只能在第一次在特定模型上更改效果之前使用上述代码。

后来我发现这本书准确描述了如何从模型中提取纹理和其他信息:Sean James 的 3D Graphics with XNA Game Studio 4.0 - 特别是第 2 章

于 2012-10-14T07:32:32.277 回答
1

请注意,您将模型的纹理分配给临时 Texture2D 变量,而不是设置当前绑定到网格的效果中存在的纹理。如果您执行以下操作:

Texture2D textureToSet = Content.Load<Texture2D>("MyTex");

//Keep in mind that this method requires a basic effect type and that only one 
//effect is present on each mesh to work properly.
foreach(Mesh mesh in model.Meshes)
{
    ((BasicEffect)(mesh.Effects[0])).Texture = textureToSet;
}

在 foreach 中发生的古怪事情只是您正在抓取效果,然后将其转换为 BasicEffect 并使用其 Texture 属性为其提供新的纹理以在使用时进行绘制。更详细的介绍请参见文档Shawn 的博客

于 2012-10-02T07:17:06.590 回答