Link

Viewport e scissor

Desenhar um objeto na tela requer que especifiquemos os parâmetros da tela. Criar um swap chain não é suficiente – nem sempre precisamos desenhar para toda a área de imagem disponível. Há situações em que apenas queremos desenhar uma imagem menor em toda a imagem, como o reflexo no espelho retrovisor de um carro ou a metade da imagem em jogos multiplayer de tela dividida. Definimos a área da imagem para a qual queremos desenhar através de uma viewport e um retângulo de corte.

Uma viewport descreve basicamente a região do framebuffer para a qual a saída será renderizada. Neste projeto queremos usar toda a região disponível do framebuffer então isso será (0, 0) para (largura, altura) do framebuffer, que, neste caso, possui as mesmas dimensões das imagens do swap chain.

VkViewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = swapChainImageSize.width();
viewport.height = swapChainImageSize.height();

Como o tamanho das imagens do swap chain podem diferir da largura e altura da janela e essas imagens serão usadas como framebuffers, então devemos nos ater ao tamanho delas.

viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

Os valores de minDepth e maxDepth especificam o intervalo de valores de profundidade a serem usados para o framebuffer. Esses valores devem estar dentro da faixa [0.0f, 1.0f], mas minDepth pode ser maior que maxDepth. Como não estamos fazendo nada de especial, então mantemos os valores padrão de 0.0f para minDepth e 1.0f para maxDepth.

m_deviceFunctions->vkCmdSetViewport(commandBuffer, 0, 1, &viewport);

Como o objeto de estado do pipeline foi criado com o estado dinâmico da viewport (VK_DYNAMIC_STATE_VIEWPORT) ativado, os parâmetros de transformação da viewport são configurados dinamicamente e alterados com o comando vkCmdSetViewport.

Enquanto as viewports definem a transformação da imagem para o framebuffer, os retângulos de corte definem em quais regiões os pixels serão realmente armazenados. Quaisquer pixels fora dos retângulos de corte serão descartados pelo rasterizador. Eles funcionam como um filtro em vez de uma transformação.

Neste projeto, simplesmente queremos desenhar para o framebuffer inteiro, então vamos especificar um retângulo de corte que o cubra inteiramente:

VkRect2D scissor;
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = viewport.width;
scissor.extent.height = viewport.height;

Da mesma forma que a viewport, os parâmetros do retângulo de corte são configurados dinamicamente e alterados com o comando vkCmdSetScissor:

m_deviceFunctions->vkCmdSetScissor(
	commandBuffer,
	0,
	1,
	&scissor
);


Anterior Próximo