XNA - 如何从.x模型访问纹理?

时间:2012-10-02 07:02:56

标签: c# xna hlsl .x

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

我的问题是:

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

我尝试了什么:

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

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

当我尝试这个游戏时,游戏运行但立方体只是黑色。我可以看到纹理变量保持信息并具有正确的尺寸,但我不知道它是否正确保持实际图像。当我只使用BasicEffect时,它们的纹理效果很好。

更新

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

2 个答案:

答案 0 :(得分: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属性为其提供一个新的纹理,以便在使用时绘制。有关更详细的介绍,请参阅the documentationShawn's blog

答案 1 :(得分:1)

如果其他人想知道这个,那么我使用以下方法保存纹理:

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

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

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