Как и многие программы, которые делают черепичную карту, как в игре Terraria, и превращают карту в единую картину всей карты, я пытаюсь сделать что-то подобное. Проблема в том, что мои текстуры блоков находятся в одном большом атласе текстуры и на которые ссылается индекс, и у меня возникают проблемы с получением данных о цвете из одного блока и помещением их в правильное место в большей текстуре.Размещение меньшего Texture2D в более крупном
Это мой код.
Получение исходного кода из индекса (этот код работает):
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);
}
Получение текстуру на индекс (где начинаются проблемы):
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;
}
Ввод текстуры в общую картину (это совершенно неправильно, я уверен):
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 для правильного преобразования между текстурой и одномерной матрицей цветов. Было бы намного легче, если бы я знал, как легко и правильно разместить квадрат цветов в большую двухмерную текстуру.
TL; DR: Как вы помещаете меньшую текстуру в большую текстуру?
Вы пытаетесь что-то сделать в режиме реального времени здесь? Или вы просто хотите собрать большую текстуру для последующего использования в приложении реального времени. Потому что я предполагаю, что вы действительно хотите собрать плитки во время выполнения. Помещение всех ваших плиток в большую текстуру убивает все преимущества плитки. – Lucius
Когда вы рисуете плитки, вы можете использовать параметр spritebatch Source rectangle – Cyral
Я делаю большую картинку, потому что я думал, что было бы интересно иметь возможность получить изображение всего вашего мира. В игре все еще используется система на основе плитки. Его чисто для удовольствия, он вообще не работает. Мне нужно знать, как работает система Texture2D, чтобы скомпилировать одно изображение из всей карты. – sm81095