Поделиться через


Ширина и шаг (Direct3D 9)

Хотя термины ширина и шаг часто используются неофициально, они имеют очень важные и явно разные значения. В результате вы должны понимать значения каждого из них и как интерпретировать значения, которые Direct3D использует для их описания.

Direct3D использует структуру D3DSURFACE_DESC для передачи информации, описывающей поверхность. Помимо прочего, эта структура определяется для хранения сведений о измерениях поверхности, а также о том, как эти измерения представлены в памяти. Структура использует элементы Height и Width для описания логических размеров поверхности. Оба элемента измеряются в пикселях. Таким образом, значения Height и Width для поверхности 640 x 480 одинаковы независимо от того, является ли она 8-разрядной поверхностью или 24-разрядной поверхностью RGB.

При блокировке поверхности с помощью метода IDirect3DSurface9::LockRect метод заполняет D3DLOCKED_RECT структуру, содержащую шаг поверхности и указатель на заблокированные биты. Значение в элементе Pitch описывает шаг памяти поверхности, также называемый шагом. Шаг — это расстояние в байтах между двумя адресами памяти, представляющими начало одной линии растрового изображения и начало следующей. Так как шаг измеряется в байтах, а не в пикселях, поверхность размером 640x480x8 имеет совершенно другое значение тона, чем поверхность с теми же размерами, но другим форматом пикселей. Кроме того, значение шага иногда отражает байты, зарезервированные Direct3D в качестве кэша, поэтому небезопасно предположить, что шаг — это просто ширина, умноженная на количество байтов на пиксель. Вместо этого визуализируйте разницу между шириной и шагом, как показано на следующей схеме.

схема шага и ширины для одного и того же переднего буфера, заднего буфера и кэша

На этой схеме передний и задний буферы имеют размер 640x480x8, а кэш имеет размер 384x480x8.

При непосредственном доступе к поверхностям следите за тем, чтобы оставаться в памяти, выделенной для размеров поверхности, и оставаться вне любой памяти, зарезервированной для кэша. Кроме того, при блокировке только части поверхности необходимо оставаться в пределах прямоугольника, указанного при блокировке поверхности. Несоблюдение этих рекомендаций приведет к непредсказуемым результатам. При отрисовке непосредственно в память surface всегда используйте шаг, возвращаемый методом IDirect3DSurface9::LockRect . Не предполагайте, что шаг основан исключительно на режиме отображения. Если приложение работает на некоторых видеоадаптерах, но выглядит искаженно на других, это может быть причиной проблемы.

Дополнительные сведения см. в статье Прямой доступ к памяти Surface (Direct3D 9).

Поверхности Direct3D