[Feat] (GL_State/RenderState): implement glDrawArrays (command only)

This commit is contained in:
2026-02-17 08:50:34 +08:00
parent 3ce7a2fd46
commit 5412d1c165
5 changed files with 82 additions and 9 deletions
@@ -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<VulkanRenderer> 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
@@ -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<float>(swapchainExtent.width);
viewport.height = static_cast<float>(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<Uint32>(count), 1, static_cast<Uint32>(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.
@@ -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();
@@ -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
@@ -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;
}