Это мой первый вопрос на StackOverflow, ура! Я могу честно сказать, что использую StackOverflow ежедневно для решения тайн как в своей работе, так и в личном программировании. В 99,9% случаев я действительно нахожу здесь нужный ответ, и это здорово!
Моя текущая проблема на самом деле немного озадачила меня, так как я не могу найти ничего, что действительно работает. Я уже прочитал несколько сообщений на GameDev.net и нашел другие ресурсы в сети, но не могу разобраться.
Я в процессе портирования небольшого 2D-движка, который я написал для XNA, на SlimDX (только DirectX9 на момент), что было хорошим шагом, поскольку я узнал больше о внутренней работе DirectX всего за несколько дней, чем за шесть месяцев работы с XNA. Я выполнил большинство моих основных функций рендеринга и фактически сумел воссоздать XNA SpriteBatch с множеством дополнительных функций (которые мне очень не хватало в XNA).
Одна из последних вещей, которые я пытаюсь заставить работать, - это извлеките исходный прямоугольник из заданной текстуры и используйте его для тайлинга. Почему: когда вы не укладываете мозаику, вы можете просто повозиться с UV, чтобы получить источник, который хотите отобразить (например: 0,3; от 0,3 до 0,5; 0,5), но при мозаике вам нужно, чтобы UV мозаично (от 0; от 0 до 2; 2 означает мозаичное изображение дважды), и поэтому мне нужна вырезанная текстура.
Короче говоря, я пытаюсь использовать следующее:
DataRectangle dataRectangle = sprite.Texture.LockRectangle(0, LockFlags.None);
Format format = sprite.Texture.GetLevelDescription(0).Format;
byte[] buffer = new byte[4];
dataRectangle.Data.Read(buffer, ([y] * dataRectangle.Pitch) + ([x] * 4), buffer.Length);
texture.UnlockRectangle(0);
Я пробовал разные пиксели, но все, похоже, дают фальшивые данные. Например, я действительно пытался использовать свой текущий аватар, чтобы проверить, соответствует ли буфер, который я получил из DataRectangle, фактическому пикселю в изображении, но безуспешно (даже проверил, был ли формат правильным, а это так).
Что такое Я делаю не так? Есть ли способ лучше? Или моя УФ-история ошибочна и можно ли ее решить? намного проще, чем вырезать исходный прямоугольник перед его мозаикой?
Спасибо за ваше время,
Леннард Фонтейн
Обновление №1
Мне действительно удалось экспортировать данные пикселей в растровое изображение, используя следующее преобразование из байтового массива:
int pixel = (buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) | ((buffer[2] & 0xFF) << 16) | ((255 - buffer[3] & 0xFF) << 24);
Таким образом, данные не кажутся такими фальшивыми, как я думал. Однако моя следующая проблема - захватить пиксели, указанные в исходном прямоугольнике, и скопировать их в новую текстуру. Изображение, которое я пытаюсь вырезать, имеет размер 150x150, но по какой-то причине оно растянуто до изображения 256x256 (степень двойки), но при фактической попытке доступа к пикселям за пределами 150x150 выдает исключение OutOfBounds. Кроме того, когда я на самом деле пытаюсь создать вторую пустую текстуру размером 256x256, независимо от того, что я в нее вкладываю, она оказывается полностью черной.
Вот мой текущий код:
//Texture texture = 150x150
DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None);
SurfaceDescription surface = texture.GetLevelDescription(0);
Texture texture2 = new Texture(_graphicsDevice, surface.Width, surface.Height, 0, surface.Usage, surface.Format, surface.Pool);
DataRectangle dataRectangle2 = texture2.LockRectangle(0, LockFlags.None);
for (int k = sourceX; k < sourceHeight; k++)
{
for (int l = sourceY; l < sourceWidth; l++)
{
byte[] buffer = new byte[4];
dataRectangle.Data.Seek((k * dataRectangle.Pitch) + (l* 4), SeekOrigin.Begin);
dataRectangle.Data.Read(buffer, 0, 4);
dataRectangle2.Data.Seek(((k - sourceY) * dataRectangle2.Pitch) + ((l - sourceX) * 4), SeekOrigin.Begin);
dataRectangle2.Data.Write(buffer, 0, 4);
}
}
sprite.Texture.UnlockRectangle(0);
texture2.UnlockRectangle(0);
_graphicsDevice.SetTexture(0, texture2);
Итак, мои новые (дополнительные) вопросы: Как я могу перемещать пиксели от одной текстуры к другой меньшей текстуре, включая альфа-канал? Почему SurfaceDescription сообщает 256x256, когда моя исходная текстура 150x150?