mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 13:18:31 +09:00
[Feat] (MG_Backend/DirectVulkan): half-assed glClear implementation
This commit is contained in:
@@ -7,13 +7,25 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#include "DirectVulkan.h"
|
#include "DirectVulkan.h"
|
||||||
|
#include "MG_State/GLState/Core.h"
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
UniquePtr<VulkanRenderer> pVulkanRenderer = nullptr;
|
UniquePtr<VulkanRenderer> pVulkanRenderer = nullptr;
|
||||||
|
|
||||||
void Clear(GLbitfield mask) {}
|
void Clear(GLbitfield mask) {
|
||||||
|
if (!pVulkanRenderer || !MG_State::pGLContext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& clearColor = MG_State::pGLContext->GetClearColor();
|
||||||
|
pVulkanRenderer->RequestClear(mask, clearColor);
|
||||||
|
}
|
||||||
|
|
||||||
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
|
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
|
||||||
|
if (pVulkanRenderer) {
|
||||||
|
pVulkanRenderer->EnsureFrameRecordingStarted();
|
||||||
|
}
|
||||||
|
|
||||||
(void)mode;
|
(void)mode;
|
||||||
(void)count;
|
(void)count;
|
||||||
(void)type;
|
(void)type;
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
gpi.pColorBlendState = &blend;
|
gpi.pColorBlendState = &blend;
|
||||||
gpi.pDynamicState = &dynamicState;
|
gpi.pDynamicState = &dynamicState;
|
||||||
gpi.layout = m_pipelineLayout;
|
gpi.layout = m_pipelineLayout;
|
||||||
gpi.renderPass = m_renderPass;
|
gpi.renderPass = m_renderPassLoad;
|
||||||
gpi.subpass = 0;
|
gpi.subpass = 0;
|
||||||
|
|
||||||
VK_VERIFY(vkCreateGraphicsPipelines(m_device, VK_NULL_HANDLE, 1, &gpi, nullptr, &m_pipeline),
|
VK_VERIFY(vkCreateGraphicsPipelines(m_device, VK_NULL_HANDLE, 1, &gpi, nullptr, &m_pipeline),
|
||||||
@@ -247,21 +247,127 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
MGLOG_I("VulkanRenderer shut down completed");
|
MGLOG_I("VulkanRenderer shut down completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::Render() {
|
void VulkanRenderer::RequestClear(GLbitfield mask, const FloatVec4& color) {
|
||||||
|
if ((mask & GL_COLOR_BUFFER_BIT) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pendingClearColor.float32[0] = color.x();
|
||||||
|
m_pendingClearColor.float32[1] = color.y();
|
||||||
|
m_pendingClearColor.float32[2] = color.z();
|
||||||
|
m_pendingClearColor.float32[3] = color.w();
|
||||||
|
m_pendingColorClear = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool VulkanRenderer::ConsumePendingColorClear(VkClearColorValue& outClearColor) {
|
||||||
|
if (!m_pendingColorClear) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
outClearColor = m_pendingClearColor;
|
||||||
|
m_pendingColorClear = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::TransitionSwapchainImageToColorAttachment(VkCommandBuffer commandBuffer, Uint32 imageIndex) {
|
||||||
|
const auto oldLayout = m_swapchainObject.GetImageLayout(imageIndex);
|
||||||
|
if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageMemoryBarrier barrier{};
|
||||||
|
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||||
|
barrier.srcAccessMask = 0;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
barrier.oldLayout = oldLayout;
|
||||||
|
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.image = m_swapchainObject.GetImage(imageIndex);
|
||||||
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
barrier.subresourceRange.baseMipLevel = 0;
|
||||||
|
barrier.subresourceRange.levelCount = 1;
|
||||||
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
|
barrier.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||||
|
m_swapchainObject.SetImageLayout(imageIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::RecordColorClear(VkCommandBuffer commandBuffer, const VkClearColorValue& clearColor) {
|
||||||
|
VkClearAttachment clearAttachment{};
|
||||||
|
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
clearAttachment.colorAttachment = 0;
|
||||||
|
clearAttachment.clearValue.color = clearColor;
|
||||||
|
|
||||||
|
VkClearRect clearRect{};
|
||||||
|
clearRect.rect.offset = {0, 0};
|
||||||
|
clearRect.rect.extent = m_swapchainObject.GetExtent();
|
||||||
|
clearRect.baseArrayLayer = 0;
|
||||||
|
clearRect.layerCount = 1;
|
||||||
|
|
||||||
|
vkCmdClearAttachments(commandBuffer, 1, &clearAttachment, 1, &clearRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::EnsureFrameRecordingStarted() {
|
||||||
|
auto& frame = m_frameContext.GetCurrent();
|
||||||
|
if (frame.isCommandRecording) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.hasCommandBufferRecorded) {
|
||||||
|
MGLOG_W("EnsureFrameRecordingStarted skipped: current frame command buffer is already finalized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBuffer& commandBuffer = m_frameContext.BeginCommandRecording();
|
VkCommandBuffer& commandBuffer = m_frameContext.BeginCommandRecording();
|
||||||
|
TransitionSwapchainImageToColorAttachment(commandBuffer, m_imageIndexAcquired);
|
||||||
|
|
||||||
|
const Bool useRenderPassClearValue = m_pendingColorClear;
|
||||||
|
VkClearValue clearValue{};
|
||||||
|
if (useRenderPassClearValue) {
|
||||||
|
clearValue.color = m_pendingClearColor;
|
||||||
|
m_pendingColorClear = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Begin render pass
|
|
||||||
VkRenderPassBeginInfo renderPassInfo{};
|
VkRenderPassBeginInfo renderPassInfo{};
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
renderPassInfo.renderPass = m_renderPass;
|
renderPassInfo.renderPass = useRenderPassClearValue ? m_renderPassClear : m_renderPassLoad;
|
||||||
renderPassInfo.framebuffer = m_framebuffers[m_imageIndexAcquired];
|
renderPassInfo.framebuffer = m_framebuffers[m_imageIndexAcquired];
|
||||||
renderPassInfo.renderArea.offset = {0, 0};
|
renderPassInfo.renderArea.offset = {0, 0};
|
||||||
const auto swapchainExtent = m_swapchainObject.GetExtent();
|
renderPassInfo.renderArea.extent = m_swapchainObject.GetExtent();
|
||||||
renderPassInfo.renderArea.extent = swapchainExtent;
|
renderPassInfo.clearValueCount = useRenderPassClearValue ? 1 : 0;
|
||||||
VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
renderPassInfo.pClearValues = useRenderPassClearValue ? &clearValue : nullptr;
|
||||||
renderPassInfo.clearValueCount = 1;
|
|
||||||
renderPassInfo.pClearValues = &clearColor;
|
|
||||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
m_isMainRenderPassActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::EndFrameRecordingIfNeeded() {
|
||||||
|
auto& frame = m_frameContext.GetCurrent();
|
||||||
|
if (!frame.isCommandRecording) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_isMainRenderPassActive) {
|
||||||
|
vkCmdEndRenderPass(frame.commandBuffer);
|
||||||
|
m_isMainRenderPassActive = false;
|
||||||
|
}
|
||||||
|
m_frameContext.EndCommandRecording();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::Render() {
|
||||||
|
// Route test rendering through the same frame-start logic used by draw calls,
|
||||||
|
// so pending glClear() state can be consumed consistently.
|
||||||
|
EnsureFrameRecordingStarted();
|
||||||
|
auto& frame = m_frameContext.GetCurrent();
|
||||||
|
if (!frame.isCommandRecording || !m_isMainRenderPassActive) {
|
||||||
|
MGLOG_W("Render skipped: frame recording was not started");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandBuffer& commandBuffer = frame.commandBuffer;
|
||||||
|
const auto swapchainExtent = m_swapchainObject.GetExtent();
|
||||||
|
|
||||||
// Render commands
|
// Render commands
|
||||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
|
||||||
@@ -281,18 +387,24 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||||
|
|
||||||
// End render pass
|
|
||||||
vkCmdEndRenderPass(commandBuffer);
|
|
||||||
|
|
||||||
// End command buffer
|
|
||||||
m_frameContext.EndCommandRecording();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::Present() {
|
void VulkanRenderer::Present() {
|
||||||
MOBILEGL_ASSERT(m_imageIndexAcquired < m_swapchainObject.GetImageCount(),
|
MOBILEGL_ASSERT(m_imageIndexAcquired < m_swapchainObject.GetImageCount(),
|
||||||
"Present, acquired image index out of range");
|
"Present, acquired image index out of range");
|
||||||
auto& frame = m_frameContext.GetCurrent();
|
auto& frame = m_frameContext.GetCurrent();
|
||||||
|
if (m_pendingColorClear && frame.isCommandRecording && m_isMainRenderPassActive) {
|
||||||
|
RecordColorClear(frame.commandBuffer, m_pendingClearColor);
|
||||||
|
m_pendingColorClear = false;
|
||||||
|
} else if (m_pendingColorClear && frame.hasCommandBufferRecorded) {
|
||||||
|
MGLOG_W("Dropping pending clear for current frame because command buffer is already finalized");
|
||||||
|
VkClearColorValue droppedClearColor{};
|
||||||
|
ConsumePendingColorClear(droppedClearColor);
|
||||||
|
} else if (m_pendingColorClear) {
|
||||||
|
EnsureFrameRecordingStarted();
|
||||||
|
}
|
||||||
|
EndFrameRecordingIfNeeded();
|
||||||
|
|
||||||
const auto acquiredImageLayout = m_swapchainObject.GetImageLayout(m_imageIndexAcquired);
|
const auto acquiredImageLayout = m_swapchainObject.GetImageLayout(m_imageIndexAcquired);
|
||||||
const Bool needsLayoutTransitionForPresent =
|
const Bool needsLayoutTransitionForPresent =
|
||||||
m_frameContext.TransitionToPresent(m_swapchainObject.GetImage(m_imageIndexAcquired), acquiredImageLayout);
|
m_frameContext.TransitionToPresent(m_swapchainObject.GetImage(m_imageIndexAcquired), acquiredImageLayout);
|
||||||
@@ -671,13 +783,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
MGLOG_I("Command pool created");
|
MGLOG_I("Command pool created");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::CreateDefaultRenderPass() {
|
VkRenderPass VulkanRenderer::CreateDefaultRenderPass(VkAttachmentLoadOp loadOp) {
|
||||||
VkAttachmentDescription color{};
|
VkAttachmentDescription color{};
|
||||||
color.format = m_swapchainObject.GetSurfaceFormat().format;
|
color.format = m_swapchainObject.GetSurfaceFormat().format;
|
||||||
color.samples = VK_SAMPLE_COUNT_1_BIT;
|
color.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
color.loadOp = loadOp;
|
||||||
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
color.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
VkAttachmentReference colorRef{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
VkAttachmentReference colorRef{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||||
@@ -692,9 +804,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
rpci.subpassCount = 1;
|
rpci.subpassCount = 1;
|
||||||
rpci.pSubpasses = ⊂
|
rpci.pSubpasses = ⊂
|
||||||
|
|
||||||
VK_VERIFY(vkCreateRenderPass(m_device, &rpci, nullptr, &m_renderPass), "vkCreateRenderPass");
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||||
|
VK_VERIFY(vkCreateRenderPass(m_device, &rpci, nullptr, &renderPass), "vkCreateRenderPass");
|
||||||
|
return renderPass;
|
||||||
|
}
|
||||||
|
|
||||||
MGLOG_D("RenderPass created.");
|
void VulkanRenderer::CreateDefaultRenderPass() {
|
||||||
|
m_renderPassLoad = CreateDefaultRenderPass(VK_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
|
m_renderPassClear = CreateDefaultRenderPass(VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||||
|
MGLOG_D("RenderPasses created (LOAD/CLEAR).");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::CreateDefaultFramebuffers() {
|
void VulkanRenderer::CreateDefaultFramebuffers() {
|
||||||
@@ -706,7 +824,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
for (auto iv : imageViews) {
|
for (auto iv : imageViews) {
|
||||||
VkImageView attachments[] = {iv};
|
VkImageView attachments[] = {iv};
|
||||||
VkFramebufferCreateInfo fbci{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
|
VkFramebufferCreateInfo fbci{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
|
||||||
fbci.renderPass = m_renderPass;
|
fbci.renderPass = m_renderPassLoad;
|
||||||
fbci.attachmentCount = 1;
|
fbci.attachmentCount = 1;
|
||||||
fbci.pAttachments = attachments;
|
fbci.pAttachments = attachments;
|
||||||
fbci.width = swapchainExtent.width;
|
fbci.width = swapchainExtent.width;
|
||||||
@@ -815,9 +933,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
m_framebuffers.clear();
|
m_framebuffers.clear();
|
||||||
|
|
||||||
if (m_renderPass != VK_NULL_HANDLE) {
|
if (m_renderPassClear != VK_NULL_HANDLE) {
|
||||||
vkDestroyRenderPass(m_device, m_renderPass, nullptr);
|
vkDestroyRenderPass(m_device, m_renderPassClear, nullptr);
|
||||||
m_renderPass = VK_NULL_HANDLE;
|
m_renderPassClear = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_renderPassLoad != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyRenderPass(m_device, m_renderPassLoad, nullptr);
|
||||||
|
m_renderPassLoad = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_swapchainObject.Shutdown(m_device);
|
m_swapchainObject.Shutdown(m_device);
|
||||||
@@ -842,6 +965,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
m_frameContext.GetCurrent().isCommandRecording = false;
|
m_frameContext.GetCurrent().isCommandRecording = false;
|
||||||
m_frameContext.GetCurrent().hasCommandBufferRecorded = false;
|
m_frameContext.GetCurrent().hasCommandBufferRecorded = false;
|
||||||
}
|
}
|
||||||
|
m_isMainRenderPassActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "FrameContext.h"
|
#include "FrameContext.h"
|
||||||
#include "ProgramFactory.h"
|
#include "ProgramFactory.h"
|
||||||
#include "SwapchainObject.h"
|
#include "SwapchainObject.h"
|
||||||
|
#include "MG_Util/Math/VectorTypes.h"
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
|
|
||||||
#include "../VkIncludes.h"
|
#include "../VkIncludes.h"
|
||||||
@@ -24,6 +25,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
void RequestClear(GLbitfield mask, const FloatVec4& color);
|
||||||
|
Bool ConsumePendingColorClear(VkClearColorValue& outClearColor);
|
||||||
|
void EnsureFrameRecordingStarted();
|
||||||
void Render();
|
void Render();
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
@@ -69,7 +73,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkRenderPass m_renderPass = VK_NULL_HANDLE;
|
VkRenderPass m_renderPassLoad = VK_NULL_HANDLE;
|
||||||
|
VkRenderPass m_renderPassClear = VK_NULL_HANDLE;
|
||||||
Vector<VkFramebuffer> m_framebuffers;
|
Vector<VkFramebuffer> m_framebuffers;
|
||||||
|
|
||||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||||
@@ -77,6 +82,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
Uint m_imageIndexAcquired = 0;
|
Uint m_imageIndexAcquired = 0;
|
||||||
FrameContext m_frameContext;
|
FrameContext m_frameContext;
|
||||||
|
Bool m_pendingColorClear = false;
|
||||||
|
VkClearColorValue m_pendingClearColor = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||||
|
Bool m_isMainRenderPassActive = false;
|
||||||
|
|
||||||
UniquePtr<ProgramFactory> m_programFactory;
|
UniquePtr<ProgramFactory> m_programFactory;
|
||||||
|
|
||||||
@@ -91,8 +99,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void CreateCommandPool();
|
void CreateCommandPool();
|
||||||
void CreateFrameContexts();
|
void CreateFrameContexts();
|
||||||
void CreateDefaultRenderPass();
|
void CreateDefaultRenderPass();
|
||||||
|
VkRenderPass CreateDefaultRenderPass(VkAttachmentLoadOp loadOp);
|
||||||
void CreateDefaultFramebuffers();
|
void CreateDefaultFramebuffers();
|
||||||
void PrepareDemoPipeline();
|
void PrepareDemoPipeline();
|
||||||
|
void TransitionSwapchainImageToColorAttachment(VkCommandBuffer commandBuffer, Uint32 imageIndex);
|
||||||
|
void RecordColorClear(VkCommandBuffer commandBuffer, const VkClearColorValue& clearColor);
|
||||||
|
void EndFrameRecordingIfNeeded();
|
||||||
|
|
||||||
void ShutdownSwapchain();
|
void ShutdownSwapchain();
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||||
#endif
|
#endif
|
||||||
|
#include "Init.h"
|
||||||
#include "MG_Backend/DirectVulkan/DirectVulkan.h"
|
#include "MG_Backend/DirectVulkan/DirectVulkan.h"
|
||||||
#include "MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h"
|
#include "MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h"
|
||||||
|
|
||||||
@@ -72,12 +73,18 @@ int main() {
|
|||||||
EGLSurface surface = eglCreateWindowSurface(display, config, nativewindow, nullptr);
|
EGLSurface surface = eglCreateWindowSurface(display, config, nativewindow, nullptr);
|
||||||
eglMakeCurrent(display, surface, surface, context);
|
eglMakeCurrent(display, surface, surface, context);
|
||||||
|
|
||||||
|
MobileGL::MG_Initialize();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(!glfwWindowShouldClose(window)) {
|
while(!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
if (i % 2 == 0)
|
if (i % 1000 > 500)
|
||||||
MobileGL::MG_Backend::DirectVulkan::pVulkanRenderer->Render();
|
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
else
|
||||||
|
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
MobileGL::MG_Backend::DirectVulkan::pVulkanRenderer->Render();
|
||||||
eglSwapBuffers(display, surface);
|
eglSwapBuffers(display, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user