我正在遵循Vulkan教程系列,并且正在使用此基本代码(https://vulkan-tutorial.com/code/21_descriptor_layout.cpp)并在draw调用中创建多个动态视口,如下所示。修改后的代码在反斜杠内。我已经设置了管道以启用视口动态状态。
void drawFrame() {
vkWaitForFences(device,1,&inFlightFences[currentFrame],VK_TRUE,(std::numeric_limits<uint64_t>::max)());
uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(device,swapChain,(std::numeric_limits<uint64_t>::max)(),imageAvailableSemaphores[currentFrame],VK_NULL_HANDLE,&imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
recreateSwapChain();
return;
}
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
throw std::runtime_error("failed to acquire swap chain image!");
}
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] };
VkPipelinestageflags waitStages[] = { VK_PIpelINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] };
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
vkResetfences(device,&inFlightFences[currentFrame]);
//////////////BEGINNING OF SETTING VIEWPORTS//////////////////////////////////////////
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
if (vkBeginCommandBuffer(commandBuffers[imageIndex],&beginInfo) != VK_SUCCESS) {
throw std::runtime_error("failed to begin recording command buffer!");
}
VkClearColorValue defaultClearColor = { { 1.025f,0.025f,1.0f } };
VkClearValue clearValues[2];
clearValues[0].color = defaultClearColor;
clearValues[1].depthStencil = { 1.0f,0 };
VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = renderPass;
renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
renderPassInfo.renderArea.offset = { 0,0 };
renderPassInfo.renderArea.extent = swapChainExtent;
renderPassInfo.pClearValues = clearValues;
renderPassInfo.clearValueCount = 1;
vkCmdBeginRenderPass(commandBuffers[imageIndex],&renderPassInfo,VK_SUBPASS_CONTENTS_INLINE);
VkCommandBuffer command_buffer = commandBuffers[imageIndex];
for (int i = 0; i < DisplayManager::win.size(); i++) {
uint32_t first_viewport = 0;
std::vector<VkViewport> viewports;
VkViewport viewport = {};
//also have to flip models y.
viewport.width = (float)DisplayManager::win.at(i).viewWidth * (((float)DisplayManager::screenWidth/(float)DisplayManager::initialX));
viewport.height = -(float)DisplayManager::win.at(i).viewHeight* (((float)DisplayManager::screenHeight / (float)DisplayManager::initialY));
viewport.x = DisplayManager::win.at(i).viewPortPosX * (((float)DisplayManager::screenWidth / (float)DisplayManager::initialX));
viewport.y = (DisplayManager::screenHeight - DisplayManager::win.at(i).viewPortPosY* (((float)DisplayManager::screenHeight / (float)DisplayManager::initialY)));
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
viewports.push_back(viewport);
vkCmdSetViewport(command_buffer,first_viewport,static_cast<uint32_t>(viewports.size()),viewports.data());
VkRect2D scissor = {};
scissor.offset = { 0,0 };
scissor.extent = swapChainExtent;
vkCmdSetScissor(command_buffer,&scissor);
vkCmdBindPipeline(commandBuffers[imageIndex],VK_PIpelINE_BIND_POINT_GRAPHICS,graphicsPipeline);
vkCmdDraw(commandBuffers[imageIndex],3,0);
}
vkCmdEndRenderPass(commandBuffers[imageIndex]);
if (vkEndCommandBuffer(commandBuffers[imageIndex]) != VK_SUCCESS) {
throw std::runtime_error("failed to record command buffer!");
}
//////////////////////////////////////////////////////////////////////
if (vkQueueSubmit(graphicsQueue,&submitInfo,inFlightFences[currentFrame]) != VK_SUCCESS) {
throw std::runtime_error("failed to submit draw command buffer!");
}
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapChains[] = { swapChain };
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;
result = vkQueuePresentKHR(presentQueue,&presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
}
else if (result != VK_SUCCESS) {
throw std::runtime_error("failed to present swap chain image!");
}
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}
我可以动态地调整和设置视口,但是我想做的是更新发送到着色器的摄影机转换,以便每个视口可以使用类似的东西独立地调整它的摄影机视矩阵。
for (int i = 0; i < DisplayManager::win.size(); i++) {
//setViewport
//update_camera_transform().
//I've tried updating a single uniform butter object here and a dynamic uniform buffer object from
//Sasha William's examples code.
vkCmdBindPipeline(commandBuffers[imageIndex],graphicsPipeline);
vkCmdDraw(commandBuffers[imageIndex],0);
}
我想知道基本代码提供的当前设置是否可行,或者有人是否可以将我指向正确的方向?