mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (MG_Backend/DirectGLES): Implement more draw funcs. Add DrawSyncBit.
This commit is contained in:
@@ -13,6 +13,22 @@
|
|||||||
#include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h>
|
#include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectGLES {
|
namespace MobileGL::MG_Backend::DirectGLES {
|
||||||
|
enum class DrawSyncBit : Uint32 {
|
||||||
|
None = 0,
|
||||||
|
IndexBuffer = 1 << 0,
|
||||||
|
IndirectBuffer = 1 << 1,
|
||||||
|
Instancing = 1 << 2
|
||||||
|
};
|
||||||
|
|
||||||
|
inline DrawSyncBit operator|(DrawSyncBit a, DrawSyncBit b) {
|
||||||
|
return static_cast<DrawSyncBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DrawSyncBit& operator|=(DrawSyncBit& a, DrawSyncBit b) {
|
||||||
|
a = a | b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DebugImpl {
|
namespace DebugImpl {
|
||||||
void ErrorLopper::Loop(std::function<void(GLenum)> func) {
|
void ErrorLopper::Loop(std::function<void(GLenum)> func) {
|
||||||
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
|
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
|
||||||
@@ -45,9 +61,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// TODO: deletion for deleted objects
|
// TODO: deletion for deleted objects
|
||||||
|
|
||||||
namespace BufferImpl {
|
namespace BufferImpl {
|
||||||
void SyncNeccessaryBuffers() {
|
void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) {
|
||||||
// All buffers we need are:
|
// All buffers we need are:
|
||||||
// 1.VBO 2.IBO 3.UBO 4.PBO 5.SSBO (TODO)
|
// 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed) 5.SSBO (TODO)
|
||||||
|
// PBO is not needed since it should be handled in frontend
|
||||||
|
|
||||||
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
||||||
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
||||||
@@ -69,11 +86,25 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IBO
|
// IBO
|
||||||
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
|
if (includeIBO) {
|
||||||
if (possibleIBO) {
|
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
|
||||||
const auto& end = buffersToSync.end();
|
if (possibleIBO) {
|
||||||
if (std::find(buffersToSync.begin(), end, possibleIBO) == end) {
|
const auto& end = buffersToSync.end();
|
||||||
buffersToSync.push_back(possibleIBO);
|
if (std::find(buffersToSync.begin(), end, possibleIBO) == end) {
|
||||||
|
buffersToSync.push_back(possibleIBO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indirect Buffer Object
|
||||||
|
if (includeIndirectBuffer) {
|
||||||
|
const auto& possibleIndirectBuffer =
|
||||||
|
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject();
|
||||||
|
if (possibleIndirectBuffer) {
|
||||||
|
const auto& end = buffersToSync.end();
|
||||||
|
if (std::find(buffersToSync.begin(), end, possibleIndirectBuffer) == end) {
|
||||||
|
buffersToSync.push_back(possibleIndirectBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,9 +354,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareForDraw() {
|
void PrepareForDraw(DrawSyncBit syncBit) {
|
||||||
BufferImpl::SyncNeccessaryBuffers();
|
BufferImpl::SyncNeccessaryBuffers(syncBit & DrawSyncBit::IndexBuffer, syncBit & DrawSyncBit::IndirectBuffer);
|
||||||
VertexArrayImpl::SyncCurrentVAO();
|
VertexArrayImpl::SyncCurrentVAO(); // TODO: instancing
|
||||||
TextureImpl::SyncNeccessaryTextures();
|
TextureImpl::SyncNeccessaryTextures();
|
||||||
FramebufferImpl::SyncCurrentFBO();
|
FramebufferImpl::SyncCurrentFBO();
|
||||||
PrgramImpl::SyncCurrentProgram();
|
PrgramImpl::SyncCurrentProgram();
|
||||||
@@ -474,16 +505,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
|
||||||
PrepareForDraw();
|
|
||||||
MG_External::GLES::glDrawArrays(mode, first, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
|
|
||||||
PrepareForDraw();
|
|
||||||
MG_External::GLES::glDrawElements(mode, count, type, indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear(GLbitfield mask) {
|
void Clear(GLbitfield mask) {
|
||||||
TextureImpl::SyncNeccessaryTextures();
|
TextureImpl::SyncNeccessaryTextures();
|
||||||
FramebufferImpl::SyncCurrentFBO();
|
FramebufferImpl::SyncCurrentFBO();
|
||||||
@@ -494,27 +515,128 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
MG_External::GLES::glClear(mask);
|
MG_External::GLES::glClear(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint baseVertex) {
|
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
|
||||||
PrepareForDraw();
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
MG_External::GLES::glDrawElementsBaseVertex(mode, count, type, indices, baseVertex);
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawElements(mode, count, type, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDrawElements(GLenum mode, const GLsizei* counts, GLenum type, const void* const* indices,
|
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::None;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawArrays(mode, first, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
|
||||||
GLsizei drawcount) {
|
GLsizei drawcount) {
|
||||||
PrepareForDraw();
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
|
||||||
for (GLsizei i = 0; i < drawcount; ++i) {
|
for (GLsizei i = 0; i < drawcount; ++i) {
|
||||||
MG_External::GLES::glDrawElements(mode, counts[i], type, indices[i]);
|
MG_External::GLES::glDrawElements(mode, count[i], type, indices[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* counts, GLenum type, const void* const* indices,
|
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
|
||||||
GLsizei drawcount, const GLint* baseVertices) {
|
GLsizei drawcount, const GLint* basevertex) {
|
||||||
PrepareForDraw();
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
|
||||||
for (GLsizei i = 0; i < drawcount; ++i) {
|
for (GLsizei i = 0; i < drawcount; ++i) {
|
||||||
MG_External::GLES::glDrawElementsBaseVertex(mode, counts[i], type, indices[i], baseVertices[i]);
|
MG_External::GLES::glDrawElementsBaseVertex(mode, count[i], type, indices[i], basevertex[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::IndirectBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < drawcount; ++i) {
|
||||||
|
const GLvoid* cmd = reinterpret_cast<const GLvoid*>(reinterpret_cast<const uint8_t*>(indirect) +
|
||||||
|
i * (stride ? stride : sizeof(GLsizei) * 4));
|
||||||
|
MG_External::GLES::glDrawElementsIndirect(mode, type, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndirectBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < drawcount; ++i) {
|
||||||
|
const GLvoid* cmd = reinterpret_cast<const GLvoid*>(reinterpret_cast<const uint8_t*>(indirect) +
|
||||||
|
i * (stride ? stride : sizeof(GLsizei) * 4));
|
||||||
|
MG_External::GLES::glDrawArraysIndirect(mode, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
|
||||||
|
const void* indices, GLint basevertex) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawRangeElements(mode, start, end, count, type, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLint basevertex, GLuint baseinstance) {
|
||||||
|
// Not supported in OpenGL ES
|
||||||
|
MGLOG_W("DrawElementsInstancedBaseVertexBaseInstance is not supported in OpenGL ES.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLint basevertex) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLuint baseinstance) {
|
||||||
|
// Not supported in OpenGL ES
|
||||||
|
MGLOG_W("DrawElementsInstancedBaseInstance is not supported in OpenGL ES.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawElementsInstanced(mode, count, type, indices, instancecount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::IndirectBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawElementsIndirect(mode, type, indirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
|
||||||
|
GLuint baseinstance) {
|
||||||
|
// Not supported in OpenGL ES
|
||||||
|
MGLOG_W("DrawArraysInstancedBaseInstance is not supported in OpenGL ES.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::Instancing;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawArraysInstanced(mode, first, count, instancecount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawArraysIndirect(GLenum mode, const void* indirect) {
|
||||||
|
DrawSyncBit syncBit = DrawSyncBit::IndirectBuffer;
|
||||||
|
PrepareForDraw(syncBit);
|
||||||
|
MG_External::GLES::glDrawArraysIndirect(mode, indirect);
|
||||||
|
}
|
||||||
|
|
||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
||||||
GLint dstY1, GLbitfield mask, GLenum filter) {
|
GLint dstY1, GLbitfield mask, GLenum filter) {
|
||||||
DebugImpl::ErrorLopper errorLopper;
|
DebugImpl::ErrorLopper errorLopper;
|
||||||
|
|||||||
@@ -14,6 +14,23 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLsizei drawcount);
|
GLsizei drawcount);
|
||||||
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
|
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
|
||||||
GLsizei drawcount, const GLint* basevertex);
|
GLsizei drawcount, const GLint* basevertex);
|
||||||
|
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride);
|
||||||
|
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride);
|
||||||
|
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
|
||||||
|
const void* indices, GLint basevertex);
|
||||||
|
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
|
||||||
|
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLint basevertex, GLuint baseinstance);
|
||||||
|
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLint basevertex);
|
||||||
|
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
|
||||||
|
GLsizei instancecount, GLuint baseinstance);
|
||||||
|
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount);
|
||||||
|
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect);
|
||||||
|
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
|
||||||
|
GLuint baseinstance);
|
||||||
|
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
|
||||||
|
void DrawArraysIndirect(GLenum mode, const void* indirect);
|
||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
||||||
GLint dstY1, GLbitfield mask, GLenum filter);
|
GLint dstY1, GLbitfield mask, GLenum filter);
|
||||||
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
|
||||||
|
|||||||
Reference in New Issue
Block a user