Compartilhar via


Visores e Recorte (Direct3D 9)

Conceitualmente, um visor é um retângulo bidimensional (2D) no qual uma cena 3D é projetada. No Direct3D, o retângulo existe como coordenadas dentro de uma superfície do Direct3D que o sistema usa como um destino de renderização. A transformação da projeção converte os vértices no sistema de coordenadas usado para o visor. Um visor também é usado para especificar o intervalo de valores de profundidade em uma superfície de destino de renderização na qual uma cena será renderizada (geralmente 0.0 a 1.0).

Tronco de exibição

Um tronco de exibição é o volume 3D em uma cena posicionado com relação à câmera do visor. A forma do volume afeta como os modelos são projetados do espaço da câmera na tela. O tipo mais comum de projeção, uma projeção de perspectiva, é responsável por fazer com que os objetos próximos da câmera pareçam maiores que os objetos distantes. Para a exibição de perspectiva, o tronco de exibição pode ser visualizado como uma pirâmide, com a câmera posicionada na ponta conforme mostrado na ilustração a seguir. Esta pirâmide é intersectada por um plano de recorte traseiro e frontal. O volume na pirâmide entre aos planos de recorte dianteiro e traseiro é o tronco de exibição. Os objetos ficam visíveis somente quando estão nesse volume.

ilustração de um tronco de exibição com um plano de recorte traseiro e frontal

Se você imaginar que está parado em uma sala escura e olhando por uma janela quadrada, estará visualizando um tronco de exibição. Nessa analogia, o plano de recorte próximo é a janela, e o plano de recorte de fundo é tudo o que finalmente interrompe sua visão – os arranha-céus do outro lado da rua, as montanhas distantes, ou nada. Você pode ver tudo dentro da pirâmide truncada que começa na janela e termina com o que quer que interrompa sua visão, impedindo sua visão.

O tronco de exibição é definido por fov (campo de visão) e por distâncias dos planos de recorte traseiro e frontal, especificados em coordenadas de z, conforme mostrado no diagrama a seguir.

diagrama do tronco de exibição

Neste diagrama, a variável D é a distância da câmera até a origem do espaço que foi definido na última parte do pipeline de geometria - a transformação de exibição. Este é o espaço em torno do qual você organiza os limites de seu tronco de exibição. Para obter informações sobre como essa variável D é usada para criar a matriz de projeção, consulte a Transformação de projeção (Direct3D 9)

Retângulo do visor

Defina o retângulo do visor em C++ usando a estrutura D3DVIEWPORT9 . A estrutura D3DVIEWPORT9 é usada com os seguintes métodos de manipulação de visor expostos pela interface IDirect3DDevice9.

A estrutura D3DVIEWPORT9 contém quatro membros - X, Y, Width, Height - que definem a área da superfície de destino de renderização na qual uma cena será renderizada. Esses valores correspondem ao retângulo de destino ou retângulo do visor, conforme mostrado no diagrama a seguir.

diagrama do retângulo do visor

Os valores que você especificar para os membros X, Y, largura, altura são coordenadas de tela relativas ao canto superior esquerdo da superfície do destino de renderização. A estrutura define dois membros adicionais (MinZ e MaxZ) que indicam os intervalos de profundidade nos quais a cena será renderizada.

O Direct3D pressupõe que o volume de recorte do visor varia de -1,0 a 1,0 em X e de 1,0 a -1,0 em Y. Essas eram as configurações usadas mais frequentemente por aplicativos no passado. Você pode ajustar a taxa de proporção do visor antes de recortar usando a transformação da projeção.

Observação

MinZ e MaxZ indicam os intervalos de profundidade nos quais a cena será renderizada e não são usadas para recorte. A maioria dos aplicativos definirá esses membros como 0.0 e 1.0 para permitir que o sistema seja renderizado para todo o intervalo de valores de profundidade no buffer de profundidade. Em alguns casos, você pode conseguir efeitos especiais usando outros intervalos de profundidade. Por exemplo, para renderizar um painel transparente em um jogo, você pode definir os dois valores como 0,0 para forçar o sistema a renderizar objetos em uma cena em primeiro plano, ou você pode defini-los como 1,0 para renderizar um objeto que sempre deve estar em segundo plano.

 

As dimensões usadas nos membros X, Y, Width, Height da estrutura D3DVIEWPORT9 para um visor definem o local e as dimensões do visor na superfície de destino de renderização. Esses valores são dados em coordenadas de tela, relativas ao canto superior esquerdo da superfície.

O Direct3D usa a localização do visor e as dimensões para dimensionar os vértices para inserir uma cena renderizada no local apropriado na superfície de destino. Internamente, o Direct3D insere esses valores na matriz a seguir, que é aplicada a cada vértice.

equação da matriz que é aplicada a cada vértice

Essa matriz dimensiona os vértices de acordo com a dimensão do visor e o intervalo de profundidade desejado, e os move para o local apropriado na superfície do destino de renderização. A matriz também gira a coordenada y para refletir uma origem de tela no canto superior esquerdo com y aumentando para baixo. Depois que essa matriz é aplicada, os vértices ainda são homogêneos - ou seja, eles ainda existem como vértices [x,y,z,w] - e devem ser convertidos em coordenadas não homogêneas antes de serem enviados para o rasterizador.

Observação

A matriz de dimensionamento do visor incorpora os membros MinZ e MaxZ da estrutura D3DVIEWPORT9 para dimensionar vértices para se ajustar ao intervalo de profundidade [MinZ, MaxZ]. Isso representa uma semântica diferente das versões anteriores do DirectX, nas quais esses membros foram usados para recorte.

 

Observação

Os aplicativos normalmente definem MinZ e MaxZ como 0,0 e 1,0, respectivamente, para fazer com que o sistema seja renderizado para todo o intervalo de profundidade. No entanto, você pode usar outros valores para alcançar determinados efeitos. Por exemplo, você pode definir os dois valores como 0,0 para forçar todos os objetos no primeiro plano ou definir ambos como 1,0 para renderizar todos os objetos em segundo plano.

 

Limpar um visor

Limpar o visor redefine o conteúdo do retângulo do visor na superfície do destino de renderização. Ele também pode limpar o retângulo nas superfícies de buffer de estêncil e de profundidade.

Use IDirect3DDevice9::Clear para limpar o visor. O método aceita um ou mais retângulos que definem as áreas na superfície que estão sendo limpas. Definir o parâmetro Count como 1 e o parâmetro pRects como o endereço de um único retângulo que abrange toda a área do visor limpará todo o visor. Outra maneira de limpar todo o visor é definir o parâmetro pRects como NULL e o parâmetro Count como 0.

O IDirect3DDevice9::Clear pode ser usado para limpar bits de estêncil em um buffer de profundidade. Basta definir o parâmetro Flags para determinar como IDirect3DDevice9::Clear funciona com o destino de renderização e quaisquer buffers de profundidade ou estêncil associados. O sinalizador D3DCLEAR_TARGET limpará o visor usando uma cor RGBA arbitrária que você fornece no argumento Color (essa não é a cor do material). O sinalizador D3DCLEAR_ZBUFFER limpará o buffer de profundidade para uma profundidade arbitrária especificada em Z: 0,0 é a distância mais próxima e 1,0 é a mais distante. O sinalizador D3DCLEAR_STENCIL redefinirá os bits de estêncil para o valor fornecido no argumento Estêncil. Você pode usar inteiros que variam de 0 a 2n-1, em que n é a profundidade do bit do buffer de estêncil.

Em algumas situações, você pode estar renderizando apenas para pequenas partes do destino de renderização e superfícies de buffer de profundidade. Os métodos claros também permitem limpar várias áreas de suas superfícies em uma única chamada. Faça isso definindo o parâmetro Count como o número de retângulos que você deseja limpar e especifique o endereço do primeiro retângulo em uma matriz de retângulos no parâmetro pRects.

Configurar o visor para o recorte

Os resultados da matriz de projeção determinam o volume de recorte no espaço de projeção:

-wc<= xc<= wc

-wc<= yc<= wc

0 <= zc<= wc

Onde: x, y, z e w representam as coordenadas de vértice depois que a transformação da projeção é aplicada. Qualquer vértice que tiver um componente x, y ou z fora desses intervalos será recortado, se o recorte estiver habilitado (comportamento padrão).

Com exceção de buffers de vértice, os aplicativos habilitam ou desabilitam o recorte por meio do estado de renderização D3DRS_CLIPPING . Informações de recorte para buffers de vértice são geradas durante o processamento. Para obter mais informações, consulte Processamento de vértice de função fixa (Direct3D 9) e Processamento de vértice programável (Direct3D 9).

O Direct3D não recorta vértices transformados de um primitivo de um buffer de vértice, a menos que ele venha de IDirect3DDevice9::P rocessVertices. Se você estiver fazendo suas próprias transformações e precisar do Direct3D para fazer o recorte, não deverá usar buffers de vértice. Nesse caso, o aplicativo percorre os dados para transformá-los. O Direct3D percorre os dados uma segunda vez para recortar e, em seguida, o driver renderiza os dados, o que é ineficiente. Portanto, se o aplicativo transformar os dados, também deverá recortar os dados.

Quando o dispositivo recebe vértices pré-transformados e acesos (vértices T&L) que precisam ser recortados, para executar a operação de recorte, os vértices são transformados novamente no espaço de recorte usando o RHW (recíproco homogêneo) do vértice e as informações do visor. Em seguida, o recorte é executado. Nem todos os dispositivos são capazes de executar essa transformação de fundo para recortar vértices T&L.

A funcionalidade D3DPMISCCAPS_CLIPTLVERTS dispositivo indica se o dispositivo é capaz de recortar vértices T&L. Se essa funcionalidade não estiver definida, o aplicativo será responsável por recortar os vértices T&L que pretende enviar para o dispositivo a ser renderizado. O dispositivo é sempre capaz de recortar vértices T&L no modo de processamento de vértice de software (independentemente de o dispositivo ser criado no modo de processamento de vértice de software ou alternado para o modo de processamento de vértice de software).

O único requisito para configurar os parâmetros de visor para um dispositivo de renderização é definir o volume de recorte do visor. Para fazer isso, inicialize e defina valores de recorte para o volume de recorte e para a superfície de destino de renderização. Os visores geralmente são configurados para renderizar para a área completa da superfície de destino de renderização, mas isso não é um requisito.

Você pode usar as configurações a seguir para os membros da estrutura D3DVIEWPORT9 para conseguir isso em C++.

D3DVIEWPORT9 viewData = { 0, 0, width, height, 0.0f, 1.0f };

Depois de definir valores na estrutura D3DVIEWPORT9 , aplique os parâmetros de visor ao dispositivo chamando seu método IDirect3DDevice9::SetViewport . O exemplo de código a seguir mostra a aparência dessa chamada.

HRESULT hr;

hr = pd3dDevice->SetViewport(&viewData);
if(FAILED(hr))
    return hr;

Se a chamada for bem-sucedida, os parâmetros de visor serão definidos e entrarão em vigor na próxima vez que um método de renderização for chamado. Para fazer alterações nos parâmetros do visor, basta atualizar os valores na estrutura D3DVIEWPORT9 e chamar IDirect3DDevice9::SetViewport novamente.

Observação

Os membros da estrutura D3DVIEWPORT9 MinZ e MaxZ indicam os intervalos de profundidade nos quais a cena será renderizada e não são usados para recorte. A maioria dos aplicativos define esses membros como 0.0 e 1.0 para permitir que o sistema renderize para todo o intervalo de valores de profundidade no buffer de profundidade. Em alguns casos, você pode conseguir efeitos especiais usando outros intervalos de profundidade. Por exemplo, para renderizar um painel transparente em um jogo, você pode definir os dois valores como 0,0 para forçar o sistema a renderizar objetos em uma cena em primeiro plano, ou você pode defini-los como 1,0 para renderizar um objeto que sempre deve estar em segundo plano.

 

Introdução