XNA ContentPipeline을 사용하여 전체 XNA GS가없는 시스템에서 파일 내보내기


9

내 게임은 콘텐츠 파이프 라인을 사용하여 런타임에 spriteSheet를로드합니다. 게임 아티스트가 수정 된 스프라이트 시트를 보내면 컴퓨터에서 빌드를 수행하여 업데이트 된 프로젝트를 보냅니다. 따라서 전체 XNA Game Studio를 설치하지 않고도 자신의 컴퓨터에서 xnb 파일 (콘텐츠 파이프 라인의 출력)을 생성하는 방법을 찾고 있습니다.

1) 아티스트가 VS + Xna를 설치하는 것을 원하지 않습니다 (무료 버전의 VS가 있다는 것을 알고 있지만 팀에 더 많은 사람들을 추가하면 확장되지 않습니다). 2) Xbox 에서이 편집기 / 도구를 실행하는 데 관심이 없으므로 Windows 전용 솔루션이 작동합니다. 3) MSBuild 옵션을 알고 있지만 전체 XNA가 필요합니다.

Shawn의 블로그를 조사한 결과 여기에 유망 보였지만 동일한 제한이있는 것처럼 보이는 Msbuild Sample 또는 XNA 4.0의 새로운 옵션 사용 옵션이 발견 되었습니다. ContentPipeline은 XNA Redist의 일부가 아니므로 전체 XNA GS를 설치해야합니다.

아무도 이것에 대한 해결책을 찾았습니까?

답변:


11

이것에 대한 정답은 ContentPipeline을 건너 뛰고 Texture2D.FromStream을 사용하여 런타임에 텍스처를로드하는 것 같습니다. 이 방법은 PC에서 잘 작동하며 약간의 성능 저하가 있더라도 출시 날짜에 가까워지면 최적화 할 수 있습니다. 현재로서는 에디터와 게임 모두에 대해 컨텐츠를 동적으로 수정할 수있는 능력이 필요합니다. 내용이 고정되면 ContentPipeline으로 돌아가서이를 최적화 할 수 있습니다.

이 경로를 선택 했으므로 실제로 Texture2D.FromStream두 가지 이유로 사용 하는 것만 큼 ​​간단하지 않다는 경고를 표시해야합니다 .

문제 # 1-사전 곱셈 알파 지원 부족

XNA4는 이제 기본적으로 사전 곱셈 된 알파 형식의 색상으로 텍스처를 처리합니다. 콘텐츠 파이프 라인을 통해 텍스처를로드하면 해당 처리가 자동으로 수행됩니다. 불행히도 Texture2D.FromStream같은 일을하지 않으므로 어느 정도의 투명성이 필요한 텍스처가로드되고 잘못 렌더링됩니다. 아래는 문제를 설명하는 스크린 샷입니다.

여기에 이미지 설명을 입력하십시오

따라서 올바른 결과를 얻으려면 처리를 직접 수행해야합니다. 내가 보여줄 방법은 GPU를 사용하여 처리를 수행하므로 매우 빠릅니다. 이 위대한 기사를 기반으로했다 . 물론 SpriteBatch이전 NonPremultiplyAlpha 모드에서 렌더링 하도록 지시 할 수도 있지만 실제로는 권장하지 않습니다.

문제 # 2-지원되지 않는 형식

콘텐츠 파이프 라인은보다 많은 형식을 지원합니다 Texture2D.FromStream. 특히 Texture2D.FromStreampng, jpg 및 gif 만 지원합니다. 반면 컨텐츠 파이프 라인은 bmp, dds, dib, hdr, jpg, pfm, png, ppm 및 tga를 지원합니다. 당신이 usuported 형식을로드하려고하면 통해 Texture2D.FromStream당신은 얻을 것이다 InvalidOperationException약간의 추가 정보.

실제로 엔진에서 bmp 지원이 필요했기 때문에 특정 경우에는 제대로 작동하는 것으로 나타났습니다. 그래도 다른 형식에 대해서는 모르겠습니다. 내 방법의 System.Drawing장점은 프로젝트 보다 어셈블리에 대한 참조를 추가해야한다는 것 입니다. GDI를 Image.FromStream보다 많이 지원하는 GDI를 사용하기 때문 Texture2D.FromStream입니다.

bmp 지원에 신경 쓰지 않는다면 내 솔루션의 해당 부분을 쉽게 삭제하고 미리 곱한 알파 처리를 수행 할 수 있습니다.

솔루션-단순 버전 (느리게)

우선, bmp 지원에 신경 쓰지 않는다면 가장 간단한 해결책이 있습니다. 이 예제에서 처리 단계는 전적으로 CPU에서 수행됩니다. 아래에 보여 줄 대안보다 약간 느리지 만 (두 솔루션을 벤치 마크 했음) 이해하기 쉽습니다.

public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream)
{
    Texture2D texture = Texture2D.FromStream(graphicsDevice, stream);
    Color[] data = new Color[texture.Width * texture.Height];
    texture.GetData(data);
    for (int i = 0; i != data.Length; ++i)
        data[i] = Color.FromNonPremultiplied(data[i].ToVector4());
    texture.SetData(data);
    return texture;
}

bmp에 관심이 있다면 먼저 GDI로 이미지를로드 한 다음 PNG로 전달하기 전에 내부적으로 PNG로 변환해야합니다 Texture2D.FromStream. 이를 수행하는 코드는 다음과 같습니다.

// Load image using GDI because Texture2D.FromStream doesn't support BMP
using (Image image = Image.FromStream(stream))
{
    // Now create a MemoryStream which will be passed to Texture2D after converting to PNG internally
    using (MemoryStream ms = new MemoryStream())
    {
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Seek(0, SeekOrigin.Begin);
        texture = Texture2D.FromStream(_graphicsDevice, ms);
    }
}

솔루션-복잡한 버전 (빠른)

마지막으로 프로젝트에서 사용하는 방법은 GPU를 사용하여 처리하는 것입니다. 이 방법에서는 렌더링 대상을 만들고 일부 블렌드 상태를 올바르게 설정 한 다음 SpriteBatch로 이미지를 두 번 그려야합니다. 마지막으로 전체 RenderTarget2D를 살펴보고 RenderTarget2D가 휘발성이고 백 버퍼 크기를 변경하는 것과 같이 살아남지 않으므로 사본을 만드는 것이 더 안전하므로 내용을 별도의 Texture2D 객체로 복제합니다.

재미있는 점은이 모든 것조차도 내 테스트 에서이 접근법이 CPU 접근법보다 약 3 배 빠르게 수행되었다는 것입니다. 따라서 각 픽셀을 살펴보고 색상을 직접 계산하는 것보다 확실히 빠릅니다. 코드가 약간 길어서 pastebin에 넣었습니다.

http://pastie.org/3651642

해당 클래스를 프로젝트에 추가하고 다음과 같이 간단하게 사용하십시오.

TextureLoader textureLoader = new TextureLoader(GraphicsDevice);
Texture2D texture = textureLoader.FromFile("Content/texture.png");

참고 : TextureLoader전체 게임에 대해 하나의 인스턴스 만 작성 하면됩니다. 또한 BMP 수정 프로그램을 사용하고 있지만 많은 성능이 필요하지 않거나 needsBmp매개 변수를 false로 남겨두면 제거 할 수 있습니다.


와, 대단해! 그것은 많은 도움이 될 것입니다 :) 감사합니다.
krolth

+1 실제로 FromStream다른 예제와 마찬가지로 32 비트 비트 맵 (png로 저장)이 포함 된 메모리 스트림을 사용 했지만이 방법은 미리 곱셈 된 텍스처를 만들지 않았습니다. 각 색상을 명시 적으로 미리 곱하면 트릭을 얻었습니다.
Groo

3

나는 대부분의 팀이 xnb 변경 사항 (잘, 모든 변경 사항, xnb includud)을 svn 서버 (무료로 설정할 수 있음)에 커밋하고 다른 사람 (아티스트 등)이 자신의 작업 사본을 업데이트 할 수 있다고 생각합니다.

실제로 이는 아티스트가 원본 (pre-nbnb) 아트를 버전 관리하는 좋은 메커니즘입니다. 그는 변경 사항을 커밋하고 작업 복사본을 업데이트하고 빌드 (프로세스에서 xnb로 만들기) 변경 사항을 커밋하고 작업 작업 복사본을 업데이트하며 모든 사람이 모든 변경 사항을 갖습니다. (당신은 최신 원시 작품을 가지고 있으며, 그는 xnb를 가지고 있습니다.

이것도 아주 잘 확장됩니다.


그렇게 할 수 있다고 생각하지 않습니까? 귀하의 제안은 XNB와 스프라이트에 버전 제어를 추가하는 것입니다. 우리는 이미 그렇게하고 있습니다. 하지만 병목 현상이 발생하기 때문에 마음에 들지 않습니다. 애니메이션을 편집 할 수있는 도구를 이미 작성했으며 게임에서 사용해 볼 수 있습니다. 그러나 그들이 스프라이트 시트를 변경하면 볼 때까지 기다릴 필요가 있습니다. 그들이 실수를한다면 상상할 수 있듯이 다시해야합니다.
krolth

@krolth 아티스트들이 프로젝트에서 작업 할 수 있도록 VS Express와 XNA를 얻는 것은 큰 일입니까? 이 시점에서 가이드를 작성하고 가이드를 통해 사람들을 도와야한다는 트레이드 오프는 아티스트가 자신의 작품을 엔진에서 볼 수 없기 때문에 지금 잃어버린 생산성을 훨씬 능가한다고 생각합니다. 프로세스를 간소화하려면 IDE를 열지 않고도 두 번 클릭하여 모든 것을 다시 컴파일 할 수있는 .BAT 파일을 제공하십시오. 그리고 그들이 OS X 만 실행하고 있다면 어려워요. 게임 개발자에 오신 것을 환영합니다. 그들은 스프라이트를 커밋하고 다음 커밋 된 XNB를 기다릴 수 있습니다.
michael.bartnett

그렇게 큰 문제가 아니라 고통 일뿐입니다. 하지만해야 할 것 같아요. 답변 / 코멘트에 대해 모두 감사합니다!
krolth

1

나는 이것을 계속 조사했으며 같은 질문을하는 사람의 이익을 위해 이것을 게시 할 것입니다.

이것에 대한 정답은 ContentPipeline을 건너 뛰고 Texture2D.FromStream 을 사용 하여 런타임에 텍스처를로드하는 것 같습니다 . 이 방법은 PC에서 잘 작동하고있을 것입니다 비록 작은 성능은 공격 이 내가 가까이 릴리스 날짜에있어 일단 내가 최적화 할 수있는 무언가이다.

현재로서는 에디터와 게임 모두에 대해 컨텐츠를 동적으로 수정할 수있는 능력이 필요합니다. 내용이 고정되면 ContentPipeline으로 돌아가서이를 최적화 할 수 있습니다.


이것을 올바르게 테스트 했습니까? 내 경험 Texture2D.FromStream으로는 충분하지 않습니다. 그 이유는 버전 4 XNA가 미리 곱셈 된 알파 텍스처와 함께 작동하기 때문에 콘텐츠 파이프 라인이 자동으로이 처리를 처리하지만 Texture2D.FromStream투명성이있는 스프라이트를 그릴 때 문제가 발생할 수 있기 때문입니다. 원하는 경우 작동하는 솔루션을 게시 할 수 있습니다.
David Gouveia

또한 콘텐츠 파이프 라인에서는 파일 Texture2D.FromStream로드를 지원하지 않습니다 .BMP. .BMP이전에 자산 을 사용한 다음로 전환 하면이 기능이 중단 될 수 있습니다 Texture2D.FromStream. 또한 그 한계에 대한 해결 방법이 있습니다. 그냥 가서 게시하겠습니다.
David Gouveia

0

프로젝트를 확인하십시오 .

아티스트가 기본 XNA 콘텐츠 파이프 라인이 지원하는 모든 것에서 XNB를 만들 수 있습니다. 아티스트에게 Visual Studio가 필요하지 않지만 재배포 가능 XNA 프레임 워크는 여전히 필요합니다.


포인터 주셔서 감사합니다. 코드를 보면 내가 참조한 Microsoft 샘플을 수정 한 것 같습니다. 전체 XNA Game Studio가 설치되어 있는지에 따라 다릅니다 (ContentBuilder.cs 참조). 왜 그렇지 않다고 생각합니까?
krolth 2014 년

나는 그렇지 않다고 생각합니다. 콘텐츠 파이프 라인을 사용하려면 전체 게임 스튜디오가 있어야합니다. 그러나이 프로젝트는 아티스트가 Visual Studio를 사용하지 못하게합니다. 콘텐츠 파이프 라인을 다시 작성하는 유일한 대안입니다.
ClassicThunder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.