Вьюпорты и клиппинг (Direct3D 9)
Концептуально, окно просмотра представляет собой двухмерный прямоугольник (2D), в который проецируется трехмерная сцена. В Direct3D прямоугольник существует в виде координат в поверхности Direct3D, которую система использует в качестве целевого объекта отрисовки. Преобразование проекции преобразует вершины в систему координат, используемую для окна просмотра. Окно просмотра также используется для указания диапазона значений глубины на целевой поверхности отрисовки, в которой будет отображаться сцена (обычно от 0,0 до 1.0).
Просмотр Frustum
Усеченный конус — это трехмерное пространство в пределах сцены, расположенное относительно камеры окна просмотра. Форма объёма влияет на то, как модели проецируются из пространства камеры на экран. Наиболее распространенный тип проекции, проекция перспективы, отвечает за то, что объекты рядом с камерой появляются больше, чем объекты на расстоянии. Для перспективного просмотра отсечение можно представить как пирамиду с камерой, расположенной на вершине, как показано на следующем рисунке. Эта пирамида пересекается передней и задней плоскостями отсечения. Объем внутри пирамиды между передней и задней плоскостями отсечения называется пирамидой отображения. Объекты становятся видимыми только когда они находятся в этом объёме.
Если вы представите, что стоите в темной комнате и смотрите через квадратное окно, вы представляете себе видовой усеченный конус. В этой аналогии, близкая плоскость отсечения является окном, а дальняя плоскость отсечения - это что бы ни прерывало ваш вид: небоскреб через улицу, горы вдали или вовсе ничего. Вы можете увидеть все внутри усеченной пирамиды, которая начинается в окне и заканчивается тем, что прерывает ваше представление, и вы не видите ничего другого.
Видимая усечённая пирамида определяется полем обзора (fov) и расстояниями передней и задней отсекающих плоскостей, указанными в z-координатах, как показано на следующей схеме.
На этой схеме переменная D — это расстояние от камеры к источнику пространства, определенного в последней части конвейера геометрии — преобразование просмотра. Это пространство, вокруг которого вы упорядочиете пределы просмотра frustum. Сведения о том, как эта переменная D используется для построения матрицы проекции, см. в преобразования проекции (Direct3D 9).
Прямоугольник области просмотра
Вы определяете прямоугольник окна представления в C++ с помощью структуры D3DVIEWPORT9. Структура D3DVIEWPORT9 используется со следующими методами обработки представления, предоставляемыми интерфейсом IDirect3Device9.
Структура D3DVIEWPORT9 содержит четыре элемента : X, Y, Width, Height , определяющие область целевой поверхности отрисовки, в которую будет отображаться сцена. Эти значения соответствуют прямоугольнику назначения или прямоугольнику окна представления, как показано на следующей схеме.
Значения, заданные для элементов X, Y, Width, Height, — это координаты экрана относительно левого верхнего угла целевой поверхности отрисовки. Структура определяет два дополнительных элемента (MinZ и MaxZ), указывающие диапазоны глубины, в которые будет отображаться сцена.
Direct3D предполагает, что объем отсечения в окне просмотра варьируется от -1.0 до 1.0 по оси X и от 1.0 до -1.0 по оси Y. Это были настройки, которые чаще всего использовались приложениями в прошлом. Вы можете настроить соотношение сторон окна просмотра перед кадрированием с помощью преобразования проекции .
Заметка
MinZ и MaxZ указывают диапазоны глубины, в которые будет отображаться сцена, и не используются для вырезки. Большинство приложений установят для этих элементов значение 0.0 и 1.0, чтобы система отображала весь диапазон значений глубины в буфере глубины. В некоторых случаях можно добиться специальных эффектов с помощью других диапазонов глубины. Например, чтобы в игре отобразить индикатор, можно задать обоим значениям 0.0, чтобы система отрисовала объекты сцены на переднем плане, или задать им 1.0, чтобы отрисовать объект, который всегда должен находиться на заднем плане.
Измерения, используемые в элементах X, Y, Width, Height в структуре D3DVIEWPORT9 для окна просмотра, определяют расположение и размеры окна просмотра на поверхности отрисовки. Эти значения находятся в координатах экрана относительно левого верхнего угла поверхности.
Direct3D использует расположение и измерения окна просмотра для масштабирования вершин, чтобы поместить отрисованную сцену в соответствующее расположение на целевой поверхности. Во внутреннем режиме Direct3D вставляет эти значения в следующую матрицу, которая применяется к каждой вершине.
Эта матрица масштабирует вершины в соответствии с измерениями окна просмотра и требуемым диапазоном глубины и преобразует их в соответствующее расположение на целевой поверхности отрисовки. Матрица также переворачивает координату y, чтобы отразить начало координат экрана в левом верхнем углу, при этом координата y увеличивается вниз. После применения этой матрицы вершины по-прежнему однородные - то есть они по-прежнему существуют как вершины [x,y,z,w], и они должны быть преобразованы в неоднородные координаты перед отправкой в растризатор.
Заметка
Матрица масштабирования окна просмотра включает элементы MinZ и MaxZ структуры D3DVIEWPORT9 для масштабирования вершин, чтобы соответствовать диапазону глубины [MinZ, MaxZ]. Это представляет другую семантику от предыдущих выпусков DirectX, в которых эти элементы использовались для вырезки.
Заметка
Приложения обычно задают для MinZ и MaxZ значение 0.0 и 1.0 соответственно, чтобы система отображала весь диапазон глубины. Однако для достижения определённых эффектов можно использовать другие значения. Например, можно задать для обоих значений значение 0,0, чтобы принудительно перевести все объекты на передний план или задать для отображения всех объектов в фоновом режиме оба значения 1.0.
Очистка окна просмотра
Очистка видового окна сбрасывает содержимое прямоугольника видового окна на плоскости рендера. Он также может очистить прямоугольник в поверхностях буфера глубины и трафаретного буфера.
Используйте IDirect3Device9::Clear для очистки окна просмотра. Метод принимает один или несколько прямоугольников, определяющих области на поверхности, очищаемые. Установка параметра Count значение 1, а параметр pRects — адрес одного прямоугольника, охватывающего всю область просмотра, очищает весь окно просмотра. Другой способ очистить весь порт просмотра — задать для параметра pRects значение NULL и параметр Count равным 0.
IDirect3DDevice9::Clear можно использовать для очистки стенсильных битов в буфере глубины. Просто задайте параметр Flags, чтобы определить, как IDirect3DDevice9::Clear работает с целевым объектом отрисовки и любыми связанными буферами глубины или наборов элементов. Флаг D3DCLEAR_TARGET очищает окно просмотра с помощью произвольного цвета RGBA, предоставленного в аргументе Color (это не цвет материала). Флаг D3DCLEAR_ZBUFFER очищает буфер глубины до произвольной глубины, указанной в Z: 0.0, является ближайшим расстоянием, и 1.0 является самым дальним. Флаг D3DCLEAR_STENCIL сбрасывает биты стенсила в значение, указанное в аргументе Stencil. Можно использовать целые числа, которые варьируются от 0 до 2n-1, где n — глубина трафаретного буфера в битах.
В некоторых ситуациях может отрисовываться только небольшие части целевых поверхностей и буфера глубины. Методы очистки также позволяют очистить несколько областей на поверхностях в одном вызове. Для этого задайте параметр Count число прямоугольников, которые требуется очистить, и укажите адрес первого прямоугольника в массиве прямоугольников в параметре pRects.
Настройка окна просмотра для обрезки
Результаты матрицы проекции определяют объем вырезки в пространстве проекции следующим образом:
-wc<= xc<= wc
-wc<= yc<= wc
0 <= zc<= wc
Где: x, y, z и w представляют координаты вершин после применения преобразования проекции. Все вершины, имеющие компонент x-, y или z вне этих диапазонов, обрезаются, если вырезка включена (поведение по умолчанию).
За исключением буферов вершин, приложения включают или отключают отсечение, используя состояние отрисовки D3DRS_CLIPPING. Сведения об обрезке буферов вершин создаются во время обработки. Дополнительные сведения см. в фиксированной обработке вершин (Direct3D 9) и программируемой обработке вершин (Direct3D 9).
Direct3D не обрезает преобразованные вершины примитива из буфера вершин, если он не поступает от IDirect3DDevice9::ProcessVertices. Если вы выполняете собственные преобразования и вам требуется Direct3D для обрезки, не следует использовать буферы вершин. В этом случае приложение просматривает данные для их преобразования. Direct3D проходит данные во второй раз, чтобы обрезать их, а затем драйвер отрисовывает данные, что неэффективно. Таким образом, если приложение преобразует данные, оно должно также обрезать данные.
Когда устройство получает предварительно преобразованные и освещённые вершины (T&L вершины), которые необходимо отсечь, для выполнения операции отсечения вершины преобразуются обратно в пространство отсечения с помощью обратной однородной координаты w вершины (RHW) и информации о видовом окне. Затем выполняется обрезка. Не все устройства способны выполнять это обратное преобразование, чтобы обрезать вершины T&L.
Способность устройства D3DPMISCCAPS_CLIPTLVERTS указывает, может ли устройство осуществлять обрезку вершин типов T&L. Если эта возможность не задана, приложение отвечает за обрезку вершин T&L, которые оно намерено отправить на устройство для отрисовки. Устройство всегда может обрезать вершины T&L в режиме обработки вершин программного обеспечения (независимо от того, создано ли устройство в режиме обработки вершин программного обеспечения или переключится в режим обработки вершин программного обеспечения).
Единственным требованием для настройки параметров окна просмотра для устройства отрисовки является задание объема отсечения окна просмотра. Для этого инициализируете и задаете значения параметров отсечения для объема отсечения и для целевой поверхности вывода. Обычно видовые порты настраивают для отрисовки на всю область целевой поверхности, но это необязательное условие.
Для достижения этого в C++можно использовать следующие параметры для членов структуры D3DVIEWPORT9.
D3DVIEWPORT9 viewData = { 0, 0, width, height, 0.0f, 1.0f };
После установки значений в структуре D3DVIEWPORT9 примените параметры окна просмотра к устройству, вызвав метод IDirect3Device9::SetViewport. В следующем примере кода показано, как может выглядеть этот вызов.
HRESULT hr;
hr = pd3dDevice->SetViewport(&viewData);
if(FAILED(hr))
return hr;
Если вызов выполнен успешно, параметры окна просмотра задаются и вступают в силу при следующем вызове метода отрисовки. Чтобы внести изменения в параметры окна просмотра, просто обновите значения в структуре D3DVIEWPORT9 и вызовите IDirect3Device9::SetViewport еще раз.
Заметка
Элементы структуры D3DVIEWPORT9 MinZ и MaxZ указывают диапазоны глубины, в которые будет отображаться сцена, и не используются для вырезки. Большинство приложений устанавливают для этих элементов значение 0.0 и 1.0, чтобы система отображала весь диапазон значений глубины в буфере глубины. В некоторых случаях можно добиться специальных эффектов с помощью других диапазонов глубины. Например, чтобы отобразить головное отображение в игре, можно задать для обоих значений 0.0, чтобы заставить систему отображать объекты в сцене на переднем плане, или можно задать для них значение 1.0 для отображения объекта, который всегда должен находиться в фоновом режиме.
Связанные разделы