gpt4 book ai didi

c# - 在 XNA 中以编程方式序列化 Texture2D

转载 作者:行者123 更新时间:2023-11-30 18:01:40 25 4
gpt4 key购买 nike

我正在为我正在构建的 XNA 游戏构建一个游戏编辑器,它可以接受 JPEG/PNG,并输出一个包含 Texture2D 内容的 XNB 文件。

我有我的自定义序列化器等,我将所有内容都挖掘到使用反射等调用 ContentCompiler,进入真正的脏位,我可以实际上让那个部分为我工作自己的格式。但我现在需要序列化为 XNA 知道如何编译(在构建项目时在 Visual Studio 中)和加载(在游戏中使用最常用的 Content.Load 方法)的常规 Texture2D 格式。我不想制作自己的图像这显然是文件格式。当我尝试编译 Texture2D 时,它没有给我一个错误,它创建了 XNB 文件,但文件内容不是图像数据,它只是一些 3-4 KB 的开销(我认为是 Texture2D 对象的其他非图像属性)。

这是我用来编译的代码:

    protected void InitializeWriter()
{
Type compilerType = typeof(ContentCompiler);
cc = compilerType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0].Invoke(null) as ContentCompiler;
compileMethod = compilerType.GetMethod("Compile", BindingFlags.NonPublic | BindingFlags.Instance);
}

internal void Write(string objectName, string path, object objectToWrite)
{
if (basePath == null)
{
throw new InvalidOperationException("The base path to write has not been set.");
}
if (cc == null) { InitializeWriter(); }
string fullPath = Path.Combine(basePath, path, objectName + ".xnb");
using (FileStream fs = File.Create(fullPath))
{
compileMethod.Invoke(cc, new object[]{
fs, objectToWrite, TargetPlatform.Windows, GraphicsProfile.Reach, false/*true*/, fullPath, fullPath
});
}
}

我有自己的内容处理器,这段代码可以完美地与它们一起工作。这只是调用了 ContentCompiler 的 Compile 方法,但使用了反射(因为它是一个内部类)。

我不明白为什么 Texture2D 序列化,但没有实际的位图数据。

编辑抱歉,它不编译 Texture2D(它提示我的 GraphicsDevice 的循环引用),如果我尝试编译一个 Bitmap 对象,它编译没有错误但不序列化实际的位图数据)

最佳答案

好的,经过一些挖掘和数小时的研究,我已经解决了我的问题。

这是要做的事情:

您无法序列化 Texture2D 并将其加载回来。虽然加载显然没有问题(因为我们在任何 2D XNA 游戏中使用内容管理器加载 Texture2D),但我们无法保存它以便从游戏中加载它。在对该问题进行进一步调查后,我发现了一个 Texture2DContent 类(在图形管道中),我认为它会序列化为 Texture2D(结果证明是完全正确的)。

所以我只是连接了一个 Texture2DContent 类的新实例,但发现无法将其数据设置到我的位图中。搜索了所有 DLL 和基类/派生类,但没有办法。然后我实现了一个具有导入方法的 TextureImporter 类。它需要一个文件名和一个 ContentImporterContext,这是一个复杂的类,它也有来自其他深层内部工作类的构造函数,我只知道我无法正确初始化那个。所以我尝试将 null 作为我的参数传递给导入方法,单步执行代码以查看我的 NullPointerException,但奇怪的是,它起作用了,并输出了我的文件。我检查了 XNB,它只是一个有效的纹理。这是我的代码:

    TextureImporter importer = new TextureImporter();
Texture2DContent tc = importer.Import(item, null) as Texture2DContent;
AssetWriter.Write(item.Substring(item.Replace('\\', '/').LastIndexOf('/') + 1), tc);

其中 item 只是一个文件名,而 AssetWriter 实际上是这样做的(那里有一些方法,但我在下面将它们粘贴在一起):

   Type compilerType = typeof(ContentCompiler);
cc = compilerType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0].Invoke(null) as ContentCompiler;
compileMethod = compilerType.GetMethod("Compile", BindingFlags.NonPublic | BindingFlags.Instance);
string fullPath = Path.Combine(basePath, path, objectName + ".xnb");
using (FileStream fs = File.Create(fullPath))
{
compileMethod.Invoke(cc, new object[]{
fs, objectToWrite, TargetPlatform.Windows, GraphicsProfile.Reach, false/*true*/, fullPath, fullPath
});
}

它就是这样工作的。该程序将所需的一切传递给内容编译器,然后由编译器完成工作。它正确处理 Texture2DContent 并将其映射到 Texture2D 的 XNB 输出,然后可以使用 contentManager 的加载方法加载。

关于c# - 在 XNA 中以编程方式序列化 Texture2D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8856528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com