Рисунок Поверхность
Рисунок 1.2. Поверхность
Ширина и высота поверхности измеряются в пикселах. Шаг (pitch) поверхности измеряется в байтах. Более того, шаг поверхности может отличаться от ее ширины в зависимости от используемого оборудования. Вы не должны считать, что шаг = ширина * sizeof(пиксель).
В коде поверхность представляется интерфейсом IDirect3DSurface9. Он предоставляет методы для прямого чтения и записи данных поверхности, а также методы для получения информации о поверхности. Вот наиболее важные методы интерфейса IDirect3DSurface9:
LockRect — Этот метод позволяет получить указатель на память поверхности. После этого, используя арифметику указателей, мы можем читать и записывать отдельные пиксели поверхности.
UnlockRect — После того, как мы вызвали метод LockRect и завершили работу с памятью поверхности, нам следует разблокировать поверхность, вызвав этот метод.
GetDesc — Метод возвращает параметры поверхности, заполняя структуру D3DSURFACE_DESC.
Принимая во внимание наличие такого параметра, как шаг поверхности, блокировка поверхности и запись отдельных пикселей могут вызвать затруднения. Поэтому мы приводим фрагмент кода в котором поверхность блокируется и заполняется пикселями красного цвета:
// Предполагается, что _surface - указатель на интерфейс IDirect3DSurface9 // Предполагается, что у поверхности 32-разрядный формат пикселей
// Получаем описание поверхности D3DSURFACE_DESC surfaceDesc; _surface->GetDesc(&surfaceDesc);
// Получаем указатель на данные пикселей поверхности D3DLOCKED_RECT lockedRect; _surface->LockRect( &lockedRect, // получаемый указатель на данные 0, // блокируем всю поверхность 0); // дополнительных параметров блокировки нет
// Перебираем все пиксели поверхности и делаем их красными DWORD* imageData = (DWORD*)lockedRect.pBits; for(int i = 0; i < surfaceDesc.Height; i++) { for(int j = 0; j < surfaceDesc.Width; j++) { // индекс в текстуре, обратите внимание, что мы используем шаг и // делим его на 4, поскольку шаг задается в байтах, // а каждый пиксель занимает 4 байта. int index = i * lockedRect.Pitch / 4 + j;
imageData[index] = 0xffff0000; // красный цвет } } _surface->UnlockRect();
Структура D3DLOCKED_RECT определена следующим образом:
typedef struct _D3DLOCKED_RECT { INT Pitch; // шаг поверхности void *pBits; // указатель на начало памяти поверхности } D3DLOCKED_RECT;
Приведем несколько комментариев к коду блокировки поверхности. Очень важно предположение о 32-разрядном формате пикселей, поскольку мы выполняем приведение к типу DWORD, который является 32-разрядным. Благодаря этому мы можем считать, что каждое значение DWORD представляет один пиксель. И не заморачивайтесь о том, как 0xffff0000 представляет красный цвет — мы поговорим об этом в главе 4.