Add doFrame function
This commit is contained in:
parent
ebe78cb4ca
commit
c5e1a66e36
@ -19,8 +19,7 @@ namespace nf::client {
|
||||
m_renderEngine = std::make_unique<render::RenderEngine>(std::move(windowFuture.get()), m_config.display);
|
||||
|
||||
while (m_running) {
|
||||
NFLog("Client running...");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
m_renderEngine->doFrame();
|
||||
}
|
||||
|
||||
inputThread.join();
|
||||
|
@ -107,11 +107,6 @@ namespace nf::client {
|
||||
}
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hWnd);
|
||||
NFLog("Window destroyed");
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
@ -127,4 +122,9 @@ namespace nf::client {
|
||||
int width = cli.right - cli.left, height = cli.bottom - cli.top;
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
DestroyWindow(m_handle);
|
||||
NFLog("Window destroyed");
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ namespace nf::client {
|
||||
void setDisplay(DisplayConfig config);
|
||||
void runLoop();
|
||||
void show(bool show = true);
|
||||
|
||||
~Window();
|
||||
private:
|
||||
void registerWindowClass();
|
||||
static LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
@ -281,11 +281,19 @@ namespace nf::client::render {
|
||||
subpassDescription.colorAttachmentCount = 1;
|
||||
subpassDescription.pColorAttachments = &outputColorAttachmentReference;
|
||||
|
||||
VkSubpassDependency dependency = {};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo renderPassCI = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
|
||||
renderPassCI.attachmentCount = 1;
|
||||
renderPassCI.pAttachments = &outputColorAttachment;
|
||||
renderPassCI.subpassCount = 1;
|
||||
renderPassCI.pSubpasses = &subpassDescription;
|
||||
renderPassCI.dependencyCount = 1;
|
||||
renderPassCI.pDependencies = &dependency;
|
||||
|
||||
if (vkCreateRenderPass(m_device, &renderPassCI, nullptr, &m_renderPassOutput) != VK_SUCCESS)
|
||||
NFError("Could not create Vulkan output render pass.");
|
||||
@ -375,8 +383,7 @@ namespace nf::client::render {
|
||||
framebufferCI.renderPass = m_renderPassOutput;
|
||||
framebufferCI.attachmentCount = 1;
|
||||
framebufferCI.pAttachments = &m_swapchainImageViews[i];
|
||||
framebufferCI.width = m_display.width;
|
||||
framebufferCI.height = m_display.height;
|
||||
framebufferCI.width = m_display.width, framebufferCI.height = m_display.height;
|
||||
framebufferCI.layers = 1;
|
||||
|
||||
if (vkCreateFramebuffer(m_device, &framebufferCI, nullptr, &m_swapchainFramebuffers[i]) != VK_SUCCESS)
|
||||
@ -407,11 +414,84 @@ namespace nf::client::render {
|
||||
NFError("Could not create semaphore.");
|
||||
|
||||
VkFenceCreateInfo fenceCI = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
||||
fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
if (vkCreateFence(m_device, &fenceCI, nullptr, &m_fenceInFlight) != VK_SUCCESS)
|
||||
NFError("Could not create fence.");
|
||||
}
|
||||
|
||||
void RenderEngine::doFrame() {
|
||||
// First, wait for previous frame to complete
|
||||
vkWaitForFences(m_device, 1, &m_fenceInFlight, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(m_device, 1, &m_fenceInFlight);
|
||||
|
||||
// Get next swapchain image
|
||||
uint32_t nextImageIndex = 0;
|
||||
vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, m_semaphoreImageAvailable, nullptr, &nextImageIndex);
|
||||
|
||||
// Begin recording
|
||||
VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||
|
||||
if (vkBeginCommandBuffer(m_commandBuffer, &commandBufferBI) != VK_SUCCESS)
|
||||
NFError("Could not begin recording command buffer.");
|
||||
|
||||
// Start the render pass
|
||||
VkClearValue black = { {{0.0, 0.0, 0.0, 1.0}} };
|
||||
VkRenderPassBeginInfo renderPassBI = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
|
||||
renderPassBI.renderPass = m_renderPassOutput;
|
||||
renderPassBI.framebuffer = m_swapchainFramebuffers[nextImageIndex];
|
||||
renderPassBI.renderArea.extent = { m_display.width, m_display.height };
|
||||
renderPassBI.clearValueCount = 1;
|
||||
renderPassBI.pClearValues = &black;
|
||||
vkCmdBeginRenderPass(m_commandBuffer, &renderPassBI, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
// Bind output pipeline
|
||||
vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineOutput);
|
||||
|
||||
// Set viewport
|
||||
VkViewport viewport = {};
|
||||
viewport.width = static_cast<float>(m_display.width), viewport.height = static_cast<float>(m_display.height);
|
||||
viewport.maxDepth = 1.0;
|
||||
vkCmdSetViewport(m_commandBuffer, 0, 1, &viewport);
|
||||
|
||||
// Draw
|
||||
vkCmdDraw(m_commandBuffer, 3, 1, 0, 0);
|
||||
|
||||
// End the render pass
|
||||
vkCmdEndRenderPass(m_commandBuffer);
|
||||
|
||||
// Finish recording
|
||||
if (vkEndCommandBuffer(m_commandBuffer) != VK_SUCCESS)
|
||||
NFError("Could not end command buffer.");
|
||||
|
||||
// Submit to graphics queue
|
||||
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = &m_semaphoreImageAvailable;
|
||||
submitInfo.pWaitDstStageMask = &waitStage;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &m_commandBuffer;
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &m_semaphoreRenderFinished;
|
||||
|
||||
if (vkQueueSubmit(m_queueGraphics, 1, &submitInfo, m_fenceInFlight) != VK_SUCCESS)
|
||||
NFError("Could not submit to Vulkan queue.");
|
||||
|
||||
// And present!
|
||||
VkPresentInfoKHR presentInfo = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pWaitSemaphores = &m_semaphoreRenderFinished;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = &m_swapchain;
|
||||
presentInfo.pImageIndices = &nextImageIndex;
|
||||
|
||||
vkQueuePresentKHR(m_queuePresent, &presentInfo);
|
||||
}
|
||||
|
||||
|
||||
RenderEngine::~RenderEngine() {
|
||||
vkDeviceWaitIdle(m_device);
|
||||
|
||||
vkDestroyFence(m_device, m_fenceInFlight, nullptr);
|
||||
vkDestroySemaphore(m_device, m_semaphoreRenderFinished, nullptr);
|
||||
vkDestroySemaphore(m_device, m_semaphoreImageAvailable, nullptr);
|
||||
|
@ -9,6 +9,8 @@ namespace nf::client::render {
|
||||
public:
|
||||
RenderEngine(std::shared_ptr<Window> window, DisplayConfig display);
|
||||
|
||||
void doFrame();
|
||||
|
||||
~RenderEngine();
|
||||
private:
|
||||
void createInstance();
|
||||
|
Loading…
x
Reference in New Issue
Block a user