From 5412d1c1657670a452c709370a7ebd2534da8881 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 17 Feb 2026 08:50:34 +0800 Subject: [PATCH] [Feat] (GL_State/RenderState): implement glDrawArrays (command only) --- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 52 ++++++++++++++++--- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 30 +++++++++++ .../DirectVulkan/Renderer/VulkanRenderer.h | 1 + .../MG_Impl/GLImpl/Drawing/GL_Drawing.cpp | 5 +- .../MG_Test/Backend/DirectVulkan/TestExec.cpp | 3 +- 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index e1db3e41..840c2755 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -1,4 +1,4 @@ -// MobileGL - MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +// MobileGL - MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp // Copyright (c) 2025-2026 MobileGL-Dev // Licensed under the GNU Lesser General Public License v3.0: // https://www.gnu.org/licenses/gpl-3.0.txt @@ -13,9 +13,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { UniquePtr pVulkanRenderer = nullptr; void Clear(GLbitfield mask) { - if (!pVulkanRenderer || !MG_State::pGLContext) { - return; - } + MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::Clear called with null VulkanRenderer"); + MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::Clear called with null GL context"); const auto& clearColor = MG_State::pGLContext->GetClearColor(); const auto clearDepth = MG_State::pGLContext->GetClearDepth(); @@ -24,13 +23,52 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { - if (pVulkanRenderer) { - pVulkanRenderer->EnsureFrameRecordingStarted(); + MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElements called with null VulkanRenderer"); + + if (count < 0) { + MGLOG_W("DrawElements skipped: count (%d) must be non-negative", count); + return; } + if (count == 0) { + return; + } + + if (mode != GL_TRIANGLES) { + MGLOG_W("DrawElements skipped: primitive mode %u is not supported yet", mode); + return; + } + + pVulkanRenderer->EnsureFrameRecordingStarted(); + (void)mode; - (void)count; (void)type; (void)indices; } + + void DrawArrays(GLenum mode, GLint first, GLsizei count) { + MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArrays called with null VulkanRenderer"); + + if (first < 0) { + MGLOG_W("DrawArrays skipped: first (%d) must be non-negative", first); + return; + } + + if (count < 0) { + MGLOG_W("DrawArrays skipped: count (%d) must be non-negative", count); + return; + } + + if (count == 0) { + return; + } + + if (mode != GL_TRIANGLES) { + MGLOG_W("DrawArrays skipped: primitive mode %u is not supported yet", mode); + return; + } + + pVulkanRenderer->DrawArrays(mode, first, count); + } } // namespace MobileGL::MG_Backend::DirectVulkan + diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index b9fcb918..28343260 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -432,6 +432,36 @@ namespace MobileGL::MG_Backend::DirectVulkan { m_frameContext.EndCommandRecording(); } + void VulkanRenderer::DrawArrays(GLenum mode, GLint first, GLsizei count) { + EnsureFrameRecordingStarted(); + auto& frame = m_frameContext.GetCurrent(); + if (!frame.isCommandRecording || !m_isMainRenderPassActive) { + MGLOG_W("DrawArrays skipped: frame recording was not started"); + return; + } + + VkCommandBuffer& commandBuffer = frame.commandBuffer; + const auto swapchainExtent = m_swapchainObject.GetExtent(); + + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); + + VkViewport viewport{}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = static_cast(swapchainExtent.width); + viewport.height = static_cast(swapchainExtent.height); + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(commandBuffer, 0, 1, &viewport); + + VkRect2D scissor{}; + scissor.offset = {0, 0}; + scissor.extent = swapchainExtent; + vkCmdSetScissor(commandBuffer, 0, 1, &scissor); + + vkCmdDraw(commandBuffer, static_cast(count), 1, static_cast(first), 0); + } + void VulkanRenderer::Render() { // Route test rendering through the same frame-start logic used by draw calls, // so pending glClear() state can be consumed consistently. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index 9386600e..0e77a4f9 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -28,6 +28,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void RequestClear(GLbitfield mask, const FloatVec4& color, Float depth, Uint32 stencil); Bool ConsumePendingColorClear(VkClearColorValue& outClearColor); void EnsureFrameRecordingStarted(); + void DrawArrays(GLenum mode, GLint first, GLsizei count); void Render(); void Present(); diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index 01a40af3..4f45d71f 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -1,4 +1,4 @@ -// MobileGL - MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +// MobileGL - MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp // Copyright (c) 2025-2026 MobileGL-Dev // Licensed under the GNU Lesser General Public License v3.0: // https://www.gnu.org/licenses/gpl-3.0.txt @@ -68,6 +68,8 @@ namespace MobileGL { #endif #if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES MG_Backend::DirectGLES::DrawArrays(mode, first, count); +#elif MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_VULKAN + MG_Backend::DirectVulkan::DrawArrays(mode, first, count); #endif } @@ -285,3 +287,4 @@ namespace MobileGL { } // namespace MG_Impl::GLImpl } // namespace MobileGL + diff --git a/MobileGL/MG_Test/Backend/DirectVulkan/TestExec.cpp b/MobileGL/MG_Test/Backend/DirectVulkan/TestExec.cpp index d9ff0340..ece297ee 100644 --- a/MobileGL/MG_Test/Backend/DirectVulkan/TestExec.cpp +++ b/MobileGL/MG_Test/Backend/DirectVulkan/TestExec.cpp @@ -84,7 +84,8 @@ int main() { else glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - MobileGL::MG_Backend::DirectVulkan::pVulkanRenderer->Render(); + if (i % 500 > 250) + glDrawArrays(GL_TRIANGLES, 0, 3); eglSwapBuffers(display, surface); ++i; }