mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-22 10:42:11 -04:00
[Feat](drawing): draw indirect impl
This commit is contained in:
parent
40709ce56d
commit
03948b6c52
@ -8,17 +8,68 @@
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static bool g_indirect_cmds_inited = false;
|
||||
std::vector<draw_elements_indirect_command_t> g_commands;
|
||||
GLuint g_indirectbuffer = 0;
|
||||
|
||||
void glMultiDrawElementsBaseVertex(GLenum mode, GLsizei* counts, GLenum type, const void* const* indices, GLsizei primcount, const GLint* basevertex) {
|
||||
LOG()
|
||||
|
||||
LOAD_GLES_FUNC(glDrawElementsBaseVertex)
|
||||
|
||||
for (GLsizei i = 0; i < primcount; ++i) {
|
||||
const GLsizei count = counts[i];
|
||||
if (count > 0) {
|
||||
gles_glDrawElementsBaseVertex(mode, count, type, indices[i], basevertex[i]);
|
||||
}
|
||||
// LOAD_GLES_FUNC(glDrawElementsBaseVertex)
|
||||
//
|
||||
// for (GLsizei i = 0; i < primcount; ++i) {
|
||||
// const GLsizei count = counts[i];
|
||||
// if (count > 0) {
|
||||
// gles_glDrawElementsBaseVertex(mode, count, type, indices[i], basevertex[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!g_indirect_cmds_inited) {
|
||||
GLES.glGenBuffers(1, &g_indirectbuffer);
|
||||
GLES.glBindBuffer(GL_DRAW_INDIRECT_BUFFER, g_indirectbuffer);
|
||||
g_commands.resize(1);
|
||||
|
||||
g_indirect_cmds_inited = true;
|
||||
}
|
||||
|
||||
if (g_commands.size() < primcount) {
|
||||
size_t sz = g_commands.size();
|
||||
|
||||
LOG_D("Before resize: %d", sz)
|
||||
|
||||
// 2-exponential to reduce reallocation
|
||||
while (sz < primcount)
|
||||
sz *= 2;
|
||||
|
||||
g_commands.resize(sz);
|
||||
GLES.glBufferData(GL_DRAW_INDIRECT_BUFFER,
|
||||
sz * sizeof(draw_elements_indirect_command_t), NULL, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
LOG_D("After resize: %d", g_commands.size())
|
||||
|
||||
for (GLsizei i = 0; i < primcount; ++i) {
|
||||
g_commands[i].count = counts[i];
|
||||
g_commands[i].instanceCount = 1;
|
||||
g_commands[i].firstIndex = static_cast<GLuint>(reinterpret_cast<uintptr_t>(indices[i]));
|
||||
g_commands[i].baseVertex = basevertex[i];
|
||||
g_commands[i].reservedMustBeZero = 0;
|
||||
}
|
||||
|
||||
void* pcmds = GLES.glMapBufferRange(GL_DRAW_INDIRECT_BUFFER,
|
||||
0, primcount * sizeof(draw_elements_indirect_command_t),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
|
||||
memcpy(pcmds, g_commands.data(), primcount * sizeof(draw_elements_indirect_command_t));
|
||||
GLES.glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
|
||||
// Draw indirect!
|
||||
for (GLsizei i = 0; i < primcount; ++i) {
|
||||
const GLvoid* offset = reinterpret_cast<GLvoid*>(i * sizeof(draw_elements_indirect_command_t));
|
||||
GLES.glDrawElementsIndirect(mode, type, offset);
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR
|
||||
}
|
||||
|
||||
void glMultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, GLsizei primcount) {
|
||||
|
@ -21,6 +21,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct draw_elements_indirect_command_t {
|
||||
GLuint count;
|
||||
GLuint instanceCount;
|
||||
GLuint firstIndex;
|
||||
GLint baseVertex;
|
||||
GLuint reservedMustBeZero;
|
||||
};
|
||||
|
||||
GLAPI GLAPIENTRY void glMultiDrawElementsBaseVertex(GLenum mode, GLsizei *counts, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
|
||||
|
||||
GLAPI GLAPIENTRY void glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount);
|
||||
|
@ -896,6 +896,8 @@ struct gles_func_t {
|
||||
|
||||
extern struct gles_func_t g_gles_func;
|
||||
|
||||
#define GLES g_gles_func
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user