2013-04-25 4 views
0

테라 리아 게임에서와 같이 바둑판 식으로 맵핑 한 많은 프로그램과 비슷하게지도를 전체지도의 단일 그림으로 바꾸고 싶습니다. 비슷한 것을하려고합니다. 문제는 내 블록 텍스처가 하나의 커다란 텍스처 맵에 있고 인덱스로 참조된다는 것입니다. 단일 블록에서 색상 데이터를 가져 와서 더 큰 텍스처의 올바른 위치에 배치하는 데 문제가 있습니다.더 큰 텍스처 2D를 큰 하나에 배치하기

이것은 지금까지 제 코드입니다.

(이 코드가 작동) 인덱스에서 소스를 얻기 : 큰 그림으로 질감을 퍼팅

public static Texture2D GetTextureAtIndex(int index, Texture2D tex) 
    { 
     Rectangle source = GetSourceForIndex(index, tex); 
     Texture2D texture = new Texture2D(_device, source.Width, source.Height); 

     Color[] colors = new Color[tex.Width * tex.Height]; 
     tex.GetData<Color>(colors); 
     Color[] colorData = new Color[source.Width * source.Height]; 

     for (int x = 0; x < source.Width; x++) 
     { 
      for (int y = 0; y < source.Height; y++) 
      { 
       colorData[x + y * source.Width] = colors[x + source.X + (y + source.Y) * tex.Width]; 
      } 
     } 

     texture.SetData<Color>(colorData); 
     return texture; 
    } 

:

public static Rectangle GetSourceForIndex(int index, Texture2D tex) 
    { 
     int dim = tex.Width/TEXTURE_MAP_DIM; 

     int startx = index % TEXTURE_MAP_DIM; 
     int starty = index/TEXTURE_MAP_DIM; 

     return new Rectangle(startx * dim, starty * dim, dim, dim); 
    } 

는 (문제가 시작) 인덱스의 질감을 얻기 (이것은 완전히 틀 렸습니다.) :

private void doSave() 
    { 
     int texWidth = this._rWidth * Region.REGION_DIM * 16; 
     int texHeight = this._rHeight * Region.REGION_DIM * 16; 

     Texture2D picture = new Texture2D(Game.GraphicsDevice, texWidth, texHeight); 
     Color[] pictureData = new Color[picture.Width * picture.Height]; 

     for (int blockX = 0; blockX < texWidth/16; blockX++) 
     { 
      for (int blockY = 0; blockY < texHeight/16; blockY++) 
      { 
       Block b = this.GetBlockAt(blockX, blockY); 
       Texture2D toCopy = TextureManager.GetTextureAtIndex(b.GetIndexBasedOnMetadata(b.GetMetadataForSurroundings(this, blockX, blockY)), b.GetTextureFile()); 
       Color[] copyData = new Color[toCopy.Width * toCopy.Height]; 
       Rectangle source = new Rectangle(blockX * 16, blockY * 16, 16, 16); 
       toCopy.GetData<Color>(copyData); 

       for (int x = 0; x < source.Width; x++) 
       { 
        for (int y = 0; y < source.Height; y++) 
        { 
         pictureData[x + source.X + (y + source.Y) * picture.Width] = copyData[x + y * source.Width]; 
        } 
       } 
      } 
     } 

     picture.SetData<Color>(pictureData); 

     string fileName = "picture" + DateTime.Now.ToString(@"MM\-dd\-yyyy-h\-mm-tt"); 
     FileStream stream = File.Open(this.GetSavePath() + @"Pictures\" + fileName, FileMode.OpenOrCreate); 
     picture.SaveAsPng(stream, picture.Width, picture.Height); 

h에 대한 설명이 없습니다. ow를 사용하여 텍스처와 1 차원 색상 배열을 적절하게 변환합니다. 더 큰 2 차원 텍스쳐에 여러 색상의 사각형을 쉽고 적절하게 배치하는 방법을 알고 있다면 훨씬 더 쉬울 것입니다.

TL : DR : 어떻게 작은 텍스처를 큰 텍스처에 넣을까요?

+1

여기서 실시간으로 무엇을하려고하십니까? 아니면 나중에 실시간 응용 프로그램에서 사용하기 위해 더 큰 텍스처를 조합하기를 원하십니까? 왜냐하면 당신이 정말로 원하는 것은 런타임에 타일을 조립하는 것이라고 생각하기 때문입니다. 모든 타일을 큰 텍스처에 넣으면 타일 시스템의 모든 이점이 사라집니다. – Lucius

+0

타일을 그릴 때 spritebatch 소스 사각형 매개 변수 – Cyral

+0

을 사용할 수 있습니다. 전 세계의 이미지를 얻을 수 있다는 것이 흥미로울 것이라고 생각하여 큰 그림을 만들고 있습니다. 게임은 아직 타일 기반 시스템을 사용하고 있습니다. 그것의 순전히 재미를 위해, 그것은 전혀 기능이 없습니다. 필자가 알아야 할 것은 전체 맵에서 하나의 이미지를 컴파일하기 위해 Texture2D 시스템이 어떻게 작동하는지입니다. – sm81095

답변

0

가장 큰 텍스처 크기 인 RenderTarget2D를 만들고 활성화로 설정하십시오. 큰 텍스처를 그린 다음 더 작은 텍스처를 그립니다. 원본 텍스처에 대한 참조를 방금 그린 RenderTarget2D로 설정합니다.

int texWidth = this._rWidth * Region.REGION_DIM * 16; 
int texHeight = this._rHeight * Region.REGION_DIM * 16; 

_renderTarget = new RenderTarget2D(GraphicsDevice, texWidth, texHeight); 
GraphicsDevice.SetRenderTarget(_renderTarget); 
GraphicsDevice.Clear(Color.Transparent); 

_spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); 

for (int blockX = 0; blockX < texWidth/16; blockX++) 
{ 
    for (int blockY = 0; blockY < texHeight/16; blockY++) 
    { 
     _spriteBatch.Draw(
      TextureManager.GetTextureAtIndex(b.GetIndexBasedOnMetadata(b.GetMetadataForSurroundings(this, blockX, blockY)), b.GetTextureFile()), 
     new Rectangle(blockX * 16, blockY * 16, 16, 16), 
     Color.White); 
    } 
} 

_spriteBatch.End() 

GraphicsDevice.SetRenderTarget(null); 
var picture = _renderTarget; 
+0

귀하의 방법을 사용해 보았지만 "GraphicsDevice.SetRenderTarget (renderTarget)"행에 "Framebuffer Incomplete"오류가 발생했습니다. – sm81095

+0

어떤 플랫폼이 개발 중입니까? 그리고 그것은 순수한 XNA와 함께 작동하고 모노 게임이 아닌가? – ClassicThunder

+0

monogame 버그가있는 것 같습니다. https://monogame.codeplex.com/discussions/406741. – ClassicThunder

관련 문제