2012-01-13 1 views
3

저는 JPEG/PNG를 받아 들일 수있는 XNA 게임용 게임 편집기를 만들고 Texture2D 콘텐츠가 포함 된 XNB 파일을 출력합니다.Texture2D를 프로그래밍 방식으로 XNA에서 직렬화하기

나는 내 사용자 지정 등을 위해 내 사용자 지정 시리얼을하고 난 진짜 더러운 비트로 간 등 반사를 사용하여 ContentCompiler를 호출들로 모든 것을 파고 해요, 나는 CAN 실제로 내 자신의 형식을 위해 일하고 그 부분을 얻을. 하지만 이제는 XNA가 (프로젝트를 빌드 할 때 Visual Studio에서) 컴파일하고 (가장 많이 사용되는 Content.Load 메서드로 게임에서로드하는 방법을 알고있는 일반 Texture2D 형식으로 직렬화해야합니다. 자신의 이미지를 만들고 싶지 않습니다. Texture2D를 컴파일하려고하면 오류가 발생하지 않고 XNB 파일이 생성되지만 파일 내용은 이미지 데이터가 아닙니다. 3-4KB의 오버 헤드가 있습니다. . 여기

내가 컴파일을 위해 사용하는 코드입니다 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 메소드를 호출한다. , Reflection (내부 클래스)을 사용합니다.

왜 Texture2D가 직렬화되지만 실제 비트 맵 데이터가 없는지 이해할 수 없습니다.

감사합니다. 수 있습니다.

편집 죄송합니다, 그것은 Texture2D를 내가 비트 맵 객체를 컴파일하려고하면이 오류없이 컴파일, (내 GraphicsDevice로의 순환 참조에 대해 불평)하지만 실제 비트 맵 데이터를 직렬화하지 않습니다)

컴파일되지 않습니다

답변

1

일부 파고 및 조사 시간이 끝난 후, 제 문제를 해결했습니다.

당신은 Texture2D를 직렬화하고 다시로드 할 수 없습니다 : 여기

는해야 할 것입니다. 로드는 분명히 문제없이 수행되지만 (2D XNA 게임에서 Content Manager를 사용하여 Texture2D를로드 할 때) 게임에서로드하는 데 저장할 수 없습니다. 이 문제에 대한 추가 조사가 끝나면 Texture2D (완벽하게 올바른 것으로 밝혀졌습니다)로 직렬화한다고 생각한 Texture2DContent 클래스 (그래픽 파이프 라인에서)를 발견했습니다.

그래서 Texture2Dentent 클래스의 새 인스턴스를 연결했지만 데이터를 내 비트 맵으로 설정할 수있는 방법이 없습니다. 모든 DLL과 기본/파생 클래스를 검색했지만 절대 사용하지 마십시오. 그런 다음 import 메서드가있는 TextureImporter 클래스를 구현했습니다. 파일 이름과 ContentImporterContext를 취합니다.이 클래스는 다른 내부 작동 클래스의 생성자를 가진 복잡한 클래스였습니다. 그리고 저는이 클래스를 올바르게 초기화 할 수 없다는 것을 알았습니다. 그래서 null을 내 메서드로 가져 와서 NullPointerException을보기 위해 코드를 밟아 보았습니다.하지만 이상하게도 작동하여 출력되었습니다. 나는 XNB를 검사했고 그것은 단지 유효한 질감이었다. 여기 내 코드입니다 :

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 
     }); 
    } 

는 그냥 작동합니다 항목 그냥 파일 이름과 AssetWriter이 실질적으로 (거기에 몇 가지 방법을하지만 함께 아래를 붙여 넣은)하지

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

이 방법. 이 프로그램은 필요한 모든 것을 내용 컴파일러에 전달하고 컴파일 작업을 수행합니다.Texture2DContent를 올바르게 처리하고 Texture2D의 XNB 출력에 매핑합니다.이 출력은 ContentManager의 load 메서드를 사용하여로드 할 수 있습니다.

+0

어떻게 TextureImporter를 프로젝트 참조로 가져올 수 있습니까? 설명해 주시겠습니까? 감사 ! – icaptan

+0

XNA 콘텐츠 파이프 라인 어셈블리를 참조하십시오. –

+0

XNA 4.0에서 XnaContentPipeline 어셈블리에 대한 참조를 찾을 수 없습니다.이 어셈블리를 프로젝트에 추가하려고합니다. 너는 전체 이름을 줄 수 있니? 감사 ! – icaptan