Леннард Фонтейн

ой первый вопрос о StackOverflow, ура! Я могу честно сказать, что ежедневно использую StackOverflow как для своей работы, так и для личных тайн программирования. 99,9% времени я нахожу здесь ответ, который мне нужен, и это здорово!

Моя текущая проблема немного озадачила меня, так как я не могу найти ничего, что действительно работает. Я уже прочитал несколько сообщений на GameDev.net и нашел другие ресурсы в сети, но не могу разобраться.

Я нахожусь в процессе переноса небольшого 2D-движка, который я написал для XNA, на SlimDX (на данный момент только DirectX9), и это был хороший шаг, поскольку я узнал больше о внутренней работе DirectX всего за несколько дней, чем я сделал в шесть месяцев работы с XNA. Я выполнил большинство основных функций рендеринга и фактически сумел воссоздать XNA SpriteBatch с кучей дополнительных функций (которые я действительно упустил в XNA).

Одна из последних вещей, которую я пытаюсь заставить работать, - это извлечь исходный прямоугольник из заданной текстуры и использовать его для листов. Почему: когда вы не используете мозаику, вы можете просто возиться с ультрафиолетом, чтобы получить источник, который вы хотите отобразить (например, от 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?

Ответы на вопрос(1)

Ваш ответ на вопрос