2012-01-13 2 views
3

Я создаю редактор игр для игры XNA, которую я создаю, чтобы принимать JPEG/PNG и выводить файл XNB с содержимым Texture2D.Сериализовать Texture2D программно в XNA

У меня есть свои собственные сериализаторы для моих пользовательских и т.д., и я копал все вниз, вызывая ContentCompiler с помощью отражения и т.д., пошли в настоящие грязные биты, и я CAN на самом деле получить эту часть работает для моих собственных форматов. Но теперь мне нужно сериализовать в обычный формат Texture2D, который XNA умеет компилировать (в Visual Studio при создании проекта) и загружать (в игре с наиболее используемым методом Content.Load. Я не хочу создавать свой собственный образ формат файла для этого, очевидно. Когда я пытаюсь скомпилировать Texture2D, он не дает мне ошибку, он создает файл XNB, но содержимое файла не является данным изображения, это всего лишь 3-4 КБ накладных расходов (что я думаю, что это другие, не-изображения свойства объекта 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 , но используя Reflection (поскольку это внутренний класс).

Я не понимаю, почему Texture2D сериализуется, но без фактических данных растрового изображения.

Thanks, Can.

EDIT К сожалению, он не компилируется Texture2D (он жалуется на циклическую ссылки моего GraphicsDevice), если я пытаюсь скомпилировать объект Bitmap, он компилируется без ошибок, но не сериализовать фактические данные растрового изображения)

ответ

1

Хорошо, после некоторых исследований и исследований, я решил свою проблему.

Вот что нужно сделать:

Вы не можете сериализовать Texture2D и загрузить его обратно. Хотя загрузка, очевидно, выполняется без проблем (поскольку мы загружаем Texture2D с помощью менеджера контента в любой 2D-игре XNA), мы не можем ее сохранить для загрузки из игры. После дальнейшего изучения проблемы я нашел класс 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); 

где пункт только имя файла и 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 и сопоставляет его с выводом XNB Texture2D, который затем может быть загружен с использованием метода загрузки contentManager.

+0

Как я могу импортировать TextureImporter в мои ссылки на проекты, вы тоже можете это объяснить? Благодаря ! – icaptan

+0

ссылается на сборку XNA Content Pipeline. –

+0

Я не могу найти ссылки на сборку XnaContentPipeline на XNA 4.0, где я пытаюсь добавить ее в проект. можете ли вы дать полное имя? благодаря ! – icaptan

 Смежные вопросы

  • Нет связанных вопросов^_^