Get rendering
This commit is contained in:
parent
6009d3178f
commit
65954d2dcf
|
@ -3,6 +3,7 @@
|
|||
#include <Orange/Core/Log.h>
|
||||
#include <Orange/Core/AlignedStorage.h>
|
||||
#include <Orange/Core/Traits.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
|
@ -17,6 +18,10 @@ namespace orange
|
|||
Success = 0,
|
||||
};
|
||||
|
||||
struct VoidResult
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, typename ErrorCode = BasicErrorCode, ErrorCode SuccessCode = BasicErrorCode::Success, ErrorCode InvalidCode = BasicErrorCode::Invalid, ErrorCode DefaultFail = BasicErrorCode::Failed>
|
||||
class Result
|
||||
{
|
||||
|
@ -128,4 +133,51 @@ namespace orange
|
|||
ErrorCode m_error = InvalidCode;
|
||||
bool m_created = false;
|
||||
};
|
||||
|
||||
// It's like a reference, but allows
|
||||
// it to be nullptr once, at constructor time
|
||||
// and never again.
|
||||
template <typename T>
|
||||
class WeakRef
|
||||
{
|
||||
public:
|
||||
WeakRef() {}
|
||||
WeakRef(std::nullptr_t) = delete;
|
||||
WeakRef(T& ref)
|
||||
: m_ptr{ &ref } { }
|
||||
|
||||
WeakRef(const WeakRef& other)
|
||||
: m_ptr { other.m_ptr } {}
|
||||
|
||||
WeakRef& operator = (T& object)
|
||||
{
|
||||
m_ptr = &object;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WeakRef& operator = (const WeakRef& other)
|
||||
{
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WeakRef& operator = (std::nullptr_t) = delete;
|
||||
|
||||
T* operator -> () const { return m_ptr; }
|
||||
|
||||
T** operator & () { return &m_ptr; }
|
||||
T* const* operator & () const { return &m_ptr; }
|
||||
|
||||
bool operator == (const WeakRef& other) const { return m_ptr == other.m_ptr; }
|
||||
bool operator != (const WeakRef& other) const { return m_ptr != other.m_ptr; }
|
||||
|
||||
bool operator == (const T* other) const { return m_ptr == other; }
|
||||
bool operator != (const T* other) const { return m_ptr != other; }
|
||||
|
||||
bool operator == (std::nullptr_t) const { return m_ptr == nullptr; }
|
||||
bool operator != (std::nullptr_t) const { return m_ptr != nullptr; }
|
||||
|
||||
private:
|
||||
T* m_ptr = nullptr;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace orange
|
|||
|
||||
VulkanResult<VkFence> CreateFence(bool signalled);
|
||||
VulkanResult<VkSemaphore> CreateSemaphore();
|
||||
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
|
||||
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
|
||||
protected:
|
||||
friend VulkanResult<RenderContext>;
|
||||
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
|
||||
|
|
|
@ -18,7 +18,12 @@ namespace orange
|
|||
|
||||
static Result<Swapchain> Create(RenderContext& context, VkSurfaceKHR surface);
|
||||
|
||||
VkCommandBuffer CommandBuffer() const { return m_commandBuffers[m_currentImage]; }
|
||||
VkImage Image() const { return m_images[m_currentImage]; }
|
||||
VkImageView ImageView() const { return m_imageViews[m_currentImage]; }
|
||||
VkCommandBuffer CommandBuffer() const { return m_commandBuffers[m_currentFrame]; }
|
||||
VkExtent2D Extent() const { return m_extent; }
|
||||
|
||||
void Present();
|
||||
protected:
|
||||
friend class Result<Swapchain>;
|
||||
Swapchain(RenderContext& context, VkSurfaceKHR surface, VkFormat format, VkExtent2D extent, VkSwapchainKHR swapchain,
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace orange
|
|||
static const char* GetError();
|
||||
|
||||
static Result<Window> Create();
|
||||
|
||||
bool Update();
|
||||
protected:
|
||||
friend Result<Window>;
|
||||
Window(SDL_Window* window);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <Orange/Render/Window.h>
|
||||
#include <Orange/Render/RenderContext.h>
|
||||
#include <Orange/Render/Swapchain.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace orange;
|
||||
|
||||
|
@ -26,5 +27,34 @@ int main(int argc, char** argv)
|
|||
if (!r_swapchain)
|
||||
return 1;
|
||||
|
||||
while (r_window->Update())
|
||||
{
|
||||
r_renderContext->BeginCommandBuffer(r_swapchain->CommandBuffer());
|
||||
{
|
||||
const VkRenderingAttachmentInfoKHR attachmentInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
|
||||
.imageView = r_swapchain->ImageView(),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.clearValue = { .color = { .float32 = { 1.0f, 0.5f, 0.0f, 1.0f } } },
|
||||
};
|
||||
|
||||
const VkRenderingInfo renderInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea = { {}, r_swapchain->Extent() },
|
||||
.layerCount = 1,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &attachmentInfo,
|
||||
};
|
||||
vkCmdBeginRendering(r_swapchain->CommandBuffer(), &renderInfo);
|
||||
vkCmdEndRendering(r_swapchain->CommandBuffer());
|
||||
}
|
||||
r_renderContext->EndCommandBuffer(r_swapchain->CommandBuffer());
|
||||
r_swapchain->Present();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -33,4 +33,26 @@ namespace orange
|
|||
|
||||
return VulkanResult<VkSemaphore>::Success(semaphore);
|
||||
}
|
||||
|
||||
VulkanResult<VoidResult> RenderContext::BeginCommandBuffer(VkCommandBuffer buffer)
|
||||
{
|
||||
VkCommandBufferBeginInfo beginInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
};
|
||||
|
||||
VkResult res = VK_SUCCESS;
|
||||
if ((res = vkBeginCommandBuffer(buffer, &beginInfo)) != VK_SUCCESS)
|
||||
return VulkanResult<VoidResult>::Error(res);
|
||||
|
||||
return VulkanResult<VoidResult>::Success();
|
||||
}
|
||||
VulkanResult<VoidResult> RenderContext::EndCommandBuffer(VkCommandBuffer buffer)
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
if ((res = vkEndCommandBuffer(buffer)) != VK_SUCCESS)
|
||||
return VulkanResult<VoidResult>::Error(res);
|
||||
|
||||
return VulkanResult<VoidResult>::Success();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,12 @@ namespace orange
|
|||
// TODO: Handle failure
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(context.Device(), swapchain, ~0u, imageAvailableSemaphores[0], VK_NULL_HANDLE, &imageIndex);
|
||||
|
||||
return Result<Swapchain>::Success(
|
||||
context, surface, r_format->format, extent, swapchain,
|
||||
swapchainImages, swapchainImageViews, commandBuffers,
|
||||
imageAvailableSemaphores, renderFinishedSemaphores, inFlightFences,
|
||||
imageIndex);
|
||||
}
|
||||
|
||||
Swapchain::~Swapchain()
|
||||
|
@ -162,4 +168,51 @@ namespace orange
|
|||
vkDestroyImageView(m_ctx.Device(), imageView, nullptr);
|
||||
vkDestroySwapchainKHR(m_ctx.Device(), m_swapchain, nullptr);
|
||||
}
|
||||
|
||||
void Swapchain::Present()
|
||||
{
|
||||
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo submitInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &m_imageAvailableSemaphores[m_currentFrame],
|
||||
.pWaitDstStageMask = &waitStage,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &m_commandBuffers[m_currentFrame],
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &m_renderFinishedSemaphores[m_currentFrame],
|
||||
};
|
||||
|
||||
// TODO: Handle failure properly.
|
||||
if (vkQueueSubmit(m_ctx.Queue(), 1, &submitInfo, m_inFlightFences[m_currentFrame]) != VK_SUCCESS) {
|
||||
log::err("Failed to submit work");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPresentInfoKHR presentInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &m_renderFinishedSemaphores[m_currentFrame],
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &m_swapchain,
|
||||
.pImageIndices = &m_currentImage,
|
||||
};
|
||||
|
||||
if (vkQueuePresentKHR(m_ctx.Queue(), &presentInfo) != VK_SUCCESS) {
|
||||
log::err("Failed to submit present");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare for next frame.
|
||||
|
||||
m_currentFrame = (m_currentFrame + 1) % DefaultFramesInFlight;
|
||||
|
||||
vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u);
|
||||
|
||||
vkWaitForFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame], VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]);
|
||||
vkAcquireNextImageKHR(m_ctx.Device(), m_swapchain, ~0u, m_imageAvailableSemaphores[m_currentFrame], VK_NULL_HANDLE, &m_currentImage);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_error.h>
|
||||
#include <SDL2/SDL_events.h>
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
|
||||
namespace orange
|
||||
|
@ -56,4 +57,22 @@ namespace orange
|
|||
{
|
||||
return SDL_GetError();
|
||||
}
|
||||
|
||||
bool Window::Update()
|
||||
{
|
||||
bool quit = false;
|
||||
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e))
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !quit;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue