From 43d62948b7d58deacc4f2090388a6c72de1286bc Mon Sep 17 00:00:00 2001 From: Roz K Date: Sat, 31 Dec 2022 09:38:18 +0100 Subject: [PATCH] Move vertex array and buffers from vertices to batch. --- __init__.py | 8 - cpp/render.hpp | 10 +- cpp/render/render_opengles.cpp | 338 +++++++++++++++++---------------- cpp/render/render_opengles.hpp | 23 +-- 4 files changed, 187 insertions(+), 192 deletions(-) diff --git a/__init__.py b/__init__.py index 5547944..0e2f8d0 100644 --- a/__init__.py +++ b/__init__.py @@ -404,10 +404,6 @@ draw_triangles = _engine.rk_draw_triangles draw_triangles.argtypes = ( ctypes.c_void_p,) # triangles -select_vertices = _engine.rk_select_vertices -select_vertices.argtypes = ( - ctypes.c_void_p,) # vertices - draw_batch = _engine.rk_draw_batch draw_batch.argtypes = ( ctypes.c_void_p, # batch @@ -416,10 +412,6 @@ draw_batch.argtypes = ( ctypes.POINTER(ctypes.c_uint), # meshes ctypes.POINTER(ctypes.c_void_p)) # params -unselect_vertices = _engine.rk_unselect_vertices -unselect_vertices.argtypes = ( - ctypes.c_void_p,) # vertices - unselect_texture = _engine.rk_unselect_texture unselect_texture.argtypes = ( ctypes.c_uint, # slot diff --git a/cpp/render.hpp b/cpp/render.hpp index 1b38e06..209c1e4 100644 --- a/cpp/render.hpp +++ b/cpp/render.hpp @@ -105,7 +105,7 @@ RK_EXPORT rk_texture_t rk_create_texture( rk_uint height, rk_uint nlevels, rk_texture_flags flags, - void const * pixels); + rk_ubyte const * pixels); RK_EXPORT rk_triangles_t rk_create_triangles( rk_uint nvertices, @@ -114,7 +114,7 @@ RK_EXPORT rk_triangles_t rk_create_triangles( RK_EXPORT rk_vertices_t rk_create_vertices( rk_vertex_format const * format, rk_uint nvertices, - void const * vertices, + rk_ubyte const * vertices, rk_uint nindices, rk_ushort const * indices); @@ -161,9 +161,6 @@ RK_EXPORT void rk_select_texture( RK_EXPORT void rk_draw_triangles( rk_triangles_t triangles); -RK_EXPORT void rk_select_vertices( - rk_vertices_t vertices); - RK_EXPORT void rk_draw_batch( rk_batch_t batch, rk_uint size, @@ -171,9 +168,6 @@ RK_EXPORT void rk_draw_batch( rk_mesh const * meshes, rk_ubyte const ** params); -RK_EXPORT void rk_unselect_vertices( - rk_vertices_t vertices); - RK_EXPORT void rk_unselect_texture( rk_uint slot, rk_texture_t texture); diff --git a/cpp/render/render_opengles.cpp b/cpp/render/render_opengles.cpp index 06001a6..792e6c8 100644 --- a/cpp/render/render_opengles.cpp +++ b/cpp/render/render_opengles.cpp @@ -24,9 +24,6 @@ typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *, static rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance = nullptr; static rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect = nullptr; -static rk_shader const * rk_current_shader = nullptr; -static rk_vertices const * rk_current_vertices = nullptr; - static void rk_gl_printf(char const * message) { printf("[GL] %s\n", message); } @@ -143,7 +140,7 @@ rk_shader_t rk_load_shader( rk_print_program_infolog(shader->program); rk_printf("Done."); glReleaseShaderCompiler(); - return shader; + return reinterpret_cast(shader); } rk_input_t rk_resolve_input( @@ -174,7 +171,7 @@ rk_texture_t rk_create_texture( rk_uint height, rk_uint nlevels, rk_texture_flags flags, - void const * pixels) { + rk_ubyte const * pixels) { if (!width || !height || !pixels) { return nullptr; } @@ -250,7 +247,7 @@ rk_texture_t rk_create_texture( } texture->nlevels = nlevels; glBindTexture(target, 0); - return texture; + return reinterpret_cast(texture); } rk_triangles_t rk_create_triangles( @@ -270,33 +267,30 @@ rk_triangles_t rk_create_triangles( glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - return triangles; + return reinterpret_cast(triangles); } rk_vertices_t rk_create_vertices( rk_vertex_format const * format, rk_uint nvertices, - void const * _vertices, + rk_ubyte const * _vertices, rk_uint nindices, rk_ushort const * indices) { if (!format || !nvertices || !_vertices || !nindices || !indices) { return nullptr; } + unsigned format_size = 0; unsigned vertex_size = 0; - unsigned nattribs = 0; - for (rk_vertex_format const * f = format; *f; ++f) { + for (rk_vertex_format const * f = format; *f; ++f, ++format_size) { switch (*f & RK_VERTEX_FORMAT_MASK) { case RK_VERTEX_FORMAT_VEC3_FLOAT: vertex_size += sizeof(rk_vec3_float); - nattribs += 1; break; case RK_VERTEX_FORMAT_VEC3_INT10: vertex_size += sizeof(rk_vec3_int10); - nattribs += 1; break; case RK_VERTEX_FORMAT_VEC3_UINT10: vertex_size += sizeof(rk_vec3_uint10); - nattribs += 1; break; default: rk_printf("rk_create_vertices(): invalid format."); @@ -304,49 +298,20 @@ rk_vertices_t rk_create_vertices( break; } } - if (!vertex_size) { + if (!format_size) { rk_printf("rk_create_vertices(): empty format."); return nullptr; } rk_vertices * const vertices = new rk_vertices; - vertices->vertex_size = vertex_size; - glGenVertexArrays(1, &vertices->array); - glBindVertexArray(vertices->array); - glGenBuffers(1, &vertices->vertices); - glBindBuffer(GL_ARRAY_BUFFER, vertices->vertices); - glBufferData(GL_ARRAY_BUFFER, nvertices * vertex_size, _vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexBuffer(RK_VERTICES_BINDING, vertices->vertices, 0, vertices->vertex_size); - for (unsigned attrib = 0; attrib < nattribs; ++attrib) { - glEnableVertexAttribArray(attrib); - } - vertices->layout = 0; - unsigned offset = 0; - for (rk_vertex_format const * f = format; *f; ++f) { - GLboolean const norm = (*f & RK_VERTEX_FORMAT_NORMALIZE) != 0; - switch (*f & RK_VERTEX_FORMAT_MASK) { - case RK_VERTEX_FORMAT_VEC3_FLOAT: - glVertexAttribFormat(vertices->layout++, 3, GL_FLOAT, GL_FALSE, offset); - offset += sizeof(rk_vec3_float); - break; - case RK_VERTEX_FORMAT_VEC3_INT10: - glVertexAttribFormat(vertices->layout++, 4, GL_INT_2_10_10_10_REV, norm, offset); - offset += sizeof(rk_vec3_int10); - break; - case RK_VERTEX_FORMAT_VEC3_UINT10: - glVertexAttribFormat(vertices->layout++, 4, GL_UNSIGNED_INT_2_10_10_10_REV, norm, offset); - offset += sizeof(rk_vec3_uint10); - break; - } - } - for (unsigned attrib = 0; attrib < nattribs; ++attrib) { - glVertexAttribBinding(attrib, RK_VERTICES_BINDING); - } - glGenBuffers(1, &vertices->indices); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertices->indices); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, nindices * sizeof(rk_ushort), indices, GL_STATIC_DRAW); - glBindVertexArray(0); - return vertices; + vertices->nvertices = nvertices; + vertices->nindices = nindices; + vertices->format = new rk_vertex_format[format_size + 1]; + memcpy(vertices->format, format, (format_size + 1) * sizeof(rk_vertex_format)); + vertices->vertices = new rk_ubyte[nvertices * vertex_size]; + memcpy(vertices->vertices, _vertices, nvertices * vertex_size); + vertices->indices = new rk_ushort[nindices]; + memcpy(vertices->indices, indices, nindices * sizeof(rk_ushort)); + return reinterpret_cast(vertices); } static void rk_pack_vec3_float( @@ -480,7 +445,6 @@ static void rk_pack_mat3_int10_norm( #undef _convert } -//TODO: multiple batches per vertices with their own buffers rk_batch_t rk_create_batch( rk_vertices_t _vertices, rk_uint max_size, @@ -491,98 +455,151 @@ rk_batch_t rk_create_batch( rk_printf("rk_create_batch(): invalid parameters."); return nullptr; } + unsigned vertex_size = 0; + for (rk_vertex_format const * f = vertices->format; *f; ++f) { + switch (*f & RK_VERTEX_FORMAT_MASK) { + case RK_VERTEX_FORMAT_VEC3_FLOAT: + vertex_size += sizeof(rk_vec3_float); + break; + case RK_VERTEX_FORMAT_VEC3_INT10: + vertex_size += sizeof(rk_vec3_int10); + break; + case RK_VERTEX_FORMAT_VEC3_UINT10: + vertex_size += sizeof(rk_vec3_uint10); + break; + } + } unsigned nparams = 0; + unsigned params_size = 0; if (params_format) { - for ( ; params_format[nparams]; ++nparams); + for (rk_param_format const * f = params_format; *f; ++f, ++nparams) { + switch (*f & RK_PARAM_FORMAT_MASK) { + case RK_PARAM_FORMAT_VEC3_FLOAT: + params_size += sizeof(rk_vec3_float); + break; + case RK_PARAM_FORMAT_VEC3_SHORT: + params_size += sizeof(rk_vec3_short); + break; + case RK_PARAM_FORMAT_VEC3_INT10: + params_size += sizeof(rk_vec3_int10); + break; + case RK_PARAM_FORMAT_MAT3_FLOAT: + params_size += sizeof(rk_mat3_float); + break; + case RK_PARAM_FORMAT_MAT3_INT10: + params_size += sizeof(rk_mat3_int10); + break; + default: + rk_printf("rk_create_batch(): invalid param format."); + return nullptr; + break; + } + } } rk_batch * batch = new rk_batch; batch->max_size = max_size; batch->max_meshes = max_meshes; batch->nparams = nparams; - batch->commands_size = 0; - batch->packed_size = 0; - batch->indices = nullptr; - batch->commands = nullptr; - batch->params = nullptr; - batch->commands_buffer = 0; - batch->params_array = 0; - unsigned packed_size = 0; - if (nparams) { - batch->params = new rk_parameter[nparams]; - rk_parameter * param = batch->params; - for (rk_param_format const * f = params_format; *f; ++f, ++param) { - param->offset = packed_size; - bool const norm = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0; - switch (*f & RK_PARAM_FORMAT_MASK) { - case RK_PARAM_FORMAT_VEC3_FLOAT: - param->size = sizeof(rk_vec3_float); - param->packer = rk_pack_vec3_float; - break; - case RK_PARAM_FORMAT_VEC3_SHORT: - param->size = sizeof(rk_vec3_short); - param->packer = norm ? rk_pack_vec3_short_norm : rk_pack_vec3_short; - break; - case RK_PARAM_FORMAT_VEC3_INT10: - param->size = sizeof(rk_vec3_int10); - param->packer = norm ? rk_pack_vec3_int10_norm : rk_pack_vec3_int10; - break; - case RK_PARAM_FORMAT_MAT3_FLOAT: - param->size = sizeof(rk_mat3_float); - param->packer = rk_pack_mat3_float; - break; - case RK_PARAM_FORMAT_MAT3_INT10: - param->size = sizeof(rk_mat3_int10); - param->packer = norm ? rk_pack_mat3_int10_norm : rk_pack_mat3_int10; - break; - default: - rk_printf("rk_create_batch(): invalid param format."); - delete[] batch->params; - delete batch; - return nullptr; - break; - } - packed_size += max_size * param->size; - } - } - batch->commands_size = max_meshes * sizeof(rk_command); - batch->packed_size = packed_size; batch->indices = new rk_ushort[max_size]; batch->commands = new rk_command[max_meshes]; + batch->params = new rk_parameter[nparams]; + glGenVertexArrays(1, &batch->vertex_array); + glBindVertexArray(batch->vertex_array); + glGenBuffers(1, &batch->vertices_buffer); + glBindBuffer(GL_ARRAY_BUFFER, batch->vertices_buffer); + glBufferData(GL_ARRAY_BUFFER, vertices->nvertices * vertex_size, vertices->vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glGenBuffers(1, &batch->indices_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->indices_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices->nindices * sizeof(rk_ushort), vertices->indices, GL_STATIC_DRAW); if (rk_MultiDrawElementsIndirect) { glGenBuffers(1, &batch->commands_buffer); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch->commands_buffer); - glBufferData(GL_DRAW_INDIRECT_BUFFER, batch->commands_size, nullptr, GL_DYNAMIC_DRAW); + glBufferData(GL_DRAW_INDIRECT_BUFFER, max_meshes * sizeof(rk_command), nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); } if (nparams) { - glBindVertexArray(vertices->array); - glGenBuffers(1, &batch->params_array); - glBindBuffer(GL_ARRAY_BUFFER, batch->params_array); - glBufferData(GL_ARRAY_BUFFER, batch->packed_size, nullptr, GL_DYNAMIC_DRAW); + glGenBuffers(1, &batch->params_buffer); + glBindBuffer(GL_ARRAY_BUFFER, batch->params_buffer); + glBufferData(GL_ARRAY_BUFFER, max_size * params_size, nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); - rk_parameter const * param = batch->params; - unsigned binding = RK_PARAMS_BINDING_BASE; - unsigned attrib = vertices->layout; + } + unsigned binding = 0; + unsigned attrib = 0; + unsigned offset = 0; + glBindVertexBuffer(binding, batch->vertices_buffer, 0, vertex_size); + for (rk_vertex_format const * f = vertices->format; *f; ++f) { + GLboolean const norm = (*f & RK_VERTEX_FORMAT_NORMALIZE) != 0; + switch (*f & RK_VERTEX_FORMAT_MASK) { + case RK_VERTEX_FORMAT_VEC3_FLOAT: + glEnableVertexAttribArray(attrib); + glVertexAttribFormat(attrib, 3, GL_FLOAT, GL_FALSE, offset); + glVertexAttribBinding(attrib++, binding); + offset += sizeof(rk_vec3_float); + break; + case RK_VERTEX_FORMAT_VEC3_INT10: + glEnableVertexAttribArray(attrib); + glVertexAttribFormat(attrib, 4, GL_INT_2_10_10_10_REV, norm, offset); + glVertexAttribBinding(attrib++, binding); + offset += sizeof(rk_vec3_int10); + break; + case RK_VERTEX_FORMAT_VEC3_UINT10: + glEnableVertexAttribArray(attrib); + glVertexAttribFormat(attrib, 4, GL_UNSIGNED_INT_2_10_10_10_REV, norm, offset); + glVertexAttribBinding(attrib++, binding); + offset += sizeof(rk_vec3_uint10); + break; + } + } + ++binding; + offset = 0; + if (nparams) { + rk_parameter * param = batch->params; for (rk_param_format const * f = params_format; *f; ++f, ++param, ++binding) { - bool const norm = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0; - glBindVertexBuffer(binding, batch->params_array, param->offset, param->size); + GLboolean const norm = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0; switch (*f & RK_PARAM_FORMAT_MASK) { case RK_PARAM_FORMAT_VEC3_FLOAT: + param->binding = binding; + param->offset = offset; + param->size = sizeof(rk_vec3_float); + param->packer = rk_pack_vec3_float; + glBindVertexBuffer(binding, batch->params_buffer, param->offset, param->size); glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(attrib++, binding); + glVertexBindingDivisor(binding, 1); + offset += max_size * param->size; break; case RK_PARAM_FORMAT_VEC3_SHORT: + param->binding = binding; + param->offset = offset; + param->size = sizeof(rk_vec3_short); + param->packer = norm ? rk_pack_vec3_short_norm : rk_pack_vec3_short; + glBindVertexBuffer(binding, batch->params_buffer, param->offset, param->size); glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 3, GL_SHORT, norm, 0); glVertexAttribBinding(attrib++, binding); + glVertexBindingDivisor(binding, 1); + offset += max_size * param->size; break; case RK_PARAM_FORMAT_VEC3_INT10: + param->binding = binding; + param->offset = offset; + param->size = sizeof(rk_vec3_int10); + param->packer = norm ? rk_pack_vec3_int10_norm : rk_pack_vec3_int10; + glBindVertexBuffer(binding, batch->params_buffer, param->offset, param->size); glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 4, GL_INT_2_10_10_10_REV, norm, 0); glVertexAttribBinding(attrib++, binding); + glVertexBindingDivisor(binding, 1); + offset += max_size * param->size; break; case RK_PARAM_FORMAT_MAT3_FLOAT: + param->binding = binding; + param->offset = offset; + param->size = sizeof(rk_mat3_float); + param->packer = rk_pack_mat3_float; + glBindVertexBuffer(binding, batch->params_buffer, param->offset, param->size); glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 3, GL_FLOAT, GL_FALSE, offsetof(rk_mat3_float, x)); glVertexAttribBinding(attrib++, binding); @@ -592,8 +609,15 @@ rk_batch_t rk_create_batch( glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 3, GL_FLOAT, GL_FALSE, offsetof(rk_mat3_float, z)); glVertexAttribBinding(attrib++, binding); + glVertexBindingDivisor(binding, 1); + offset += max_size * param->size; break; case RK_PARAM_FORMAT_MAT3_INT10: + param->binding = binding; + param->offset = offset; + param->size = sizeof(rk_mat3_int10); + param->packer = norm ? rk_pack_mat3_int10_norm : rk_pack_mat3_int10; + glBindVertexBuffer(binding, batch->params_buffer, param->offset, param->size); glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 4, GL_INT_2_10_10_10_REV, norm, offsetof(rk_mat3_int10, x)); glVertexAttribBinding(attrib++, binding); @@ -603,13 +627,14 @@ rk_batch_t rk_create_batch( glEnableVertexAttribArray(attrib); glVertexAttribFormat(attrib, 4, GL_INT_2_10_10_10_REV, norm, offsetof(rk_mat3_int10, z)); glVertexAttribBinding(attrib++, binding); + glVertexBindingDivisor(binding, 1); + offset += max_size * param->size; break; } - glVertexBindingDivisor(binding, 1); } - glBindVertexArray(0); } - return batch; + glBindVertexArray(0); + return reinterpret_cast(batch); } void rk_begin_frame() { @@ -620,7 +645,6 @@ void rk_select_shader( rk_shader_t _shader) { rk_shader * const shader = reinterpret_cast(_shader); if (shader) { - rk_current_shader = shader; glUseProgram(shader->program); } } @@ -629,7 +653,7 @@ void rk_set_input_float( rk_input_t _input, float value) { GLint const input = reinterpret_cast(_input) - 1; - if (rk_current_shader && input > -1) { + if (input > -1) { glUniform1f(input, value); } } @@ -638,7 +662,7 @@ void rk_set_input_vec3( rk_input_t _input, rk_vec3 const & value) { GLint const input = reinterpret_cast(_input) - 1; - if (rk_current_shader && input > -1) { + if (input > -1) { glUniform3fv(input, 1, glm::value_ptr(value)); } } @@ -647,7 +671,7 @@ void rk_set_input_mat3( rk_input_t _input, rk_mat3 const & value) { GLint const input = reinterpret_cast(_input) - 1; - if (rk_current_shader && input > -1) { + if (input > -1) { glUniformMatrix3fv(input, 1, GL_FALSE, glm::value_ptr(value)); } } @@ -656,7 +680,7 @@ void rk_set_input_mat4( rk_input_t _input, rk_mat4 const & value) { GLint const input = reinterpret_cast(_input) - 1; - if (rk_current_shader && input > -1) { + if (input > -1) { glUniformMatrix4fv(input, 1, GL_FALSE, glm::value_ptr(value)); } } @@ -665,7 +689,7 @@ void rk_set_param_vec3( rk_param_t _param, rk_vec3 const & value) { GLint const param = reinterpret_cast(_param) - 1; - if (rk_current_shader && param > -1) { + if (param > -1) { glVertexAttrib3fv(param, glm::value_ptr(value)); } } @@ -674,7 +698,7 @@ void rk_set_param_mat3( rk_param_t _param, rk_mat3 const & value) { GLint const param = reinterpret_cast(_param) - 1; - if (rk_current_shader && param > -1) { + if (param > -1) { glVertexAttrib3fv(param + 0, glm::value_ptr(value[0])); glVertexAttrib3fv(param + 1, glm::value_ptr(value[1])); glVertexAttrib3fv(param + 2, glm::value_ptr(value[2])); @@ -687,7 +711,7 @@ void rk_select_texture( rk_input_t _sampler) { rk_texture const * const texture = reinterpret_cast(_texture); GLint const sampler = reinterpret_cast(_sampler) - 1; - if (texture && sampler > -1 && rk_current_shader) { + if (texture && sampler > -1) { glActiveTexture(GL_TEXTURE0 + slot); if (texture->nlevels) { glBindTexture(GL_TEXTURE_2D_ARRAY, texture->texture); @@ -701,24 +725,15 @@ void rk_select_texture( RK_EXPORT void rk_draw_triangles( rk_triangles_t _triangles) { rk_triangles const * const triangles = reinterpret_cast(_triangles); - if (triangles && rk_current_shader && !rk_current_vertices) { + if (triangles) { glBindVertexArray(triangles->array); glDrawArrays(GL_TRIANGLES, 0, triangles->size); glBindVertexArray(0); } } -void rk_select_vertices( - rk_vertices_t _vertices) { - rk_vertices * const vertices = reinterpret_cast(_vertices); - if (vertices) { - glBindVertexArray(vertices->array); - rk_current_vertices = vertices; - } -} - static unsigned rk_batch_filter( - rk_batch & batch, + rk_batch const & batch, unsigned const size, rk_instance_flags const * flags) { rk_ushort * indices = batch.indices; @@ -731,7 +746,7 @@ static unsigned rk_batch_filter( } static unsigned rk_batch_build_commands( - rk_batch & batch, + rk_batch const & batch, unsigned const ninstances, rk_mesh const * const meshes) { rk_command * const last_command = batch.commands + batch.max_meshes; @@ -759,7 +774,7 @@ static unsigned rk_batch_build_commands( } static void rk_batch_pack( - rk_batch & batch, + rk_batch const & batch, unsigned const ninstances, rk_ubyte const ** srcs) { rk_parameter const * const last_param = batch.params + batch.nparams; @@ -783,29 +798,30 @@ void rk_draw_batch( rk_instance_flags const * flags, rk_mesh const * meshes, rk_ubyte const ** params) { - rk_batch & batch = *reinterpret_cast(_batch); - if (!count || count > batch.max_size || !flags || !meshes || !rk_current_shader || !rk_current_vertices) { + rk_batch const * const batch = reinterpret_cast(_batch); + if (!batch || !count || count > batch->max_size || !flags || !meshes) { return; } - unsigned const ninstances = rk_batch_filter(batch, count, flags); + unsigned const ninstances = rk_batch_filter(*batch, count, flags); if (!ninstances) { return; } - unsigned const ncommands = rk_batch_build_commands(batch, ninstances, meshes); + glBindVertexArray(batch->vertex_array); + unsigned const ncommands = rk_batch_build_commands(*batch, ninstances, meshes); if (rk_MultiDrawElementsIndirect) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch.commands_buffer); - glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, ncommands * sizeof(rk_command), batch.commands); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch->commands_buffer); + glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, ncommands * sizeof(rk_command), batch->commands); } - if (batch.nparams && params) { - glBindBuffer(GL_ARRAY_BUFFER, batch.params_array); - rk_batch_pack(batch, ninstances, params); + if (batch->nparams && params) { + glBindBuffer(GL_ARRAY_BUFFER, batch->params_buffer); + rk_batch_pack(*batch, ninstances, params); } if (rk_DrawElementsInstancedBaseInstance) { if (rk_MultiDrawElementsIndirect) { rk_MultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, ncommands, sizeof(rk_command)); } else { - rk_command const * const last_command = batch.commands + ncommands; - for (rk_command const * command = batch.commands; command < last_command; ++command) { + rk_command const * const last_command = batch->commands + ncommands; + for (rk_command const * command = batch->commands; command < last_command; ++command) { rk_DrawElementsInstancedBaseInstance( GL_TRIANGLES, command->nvertices, GL_UNSIGNED_SHORT, reinterpret_cast(command->base_index << 1), @@ -814,12 +830,11 @@ void rk_draw_batch( } } else { unsigned param_index = 0; - rk_command const * const last_command = batch.commands + ncommands; - rk_parameter const * const last_param = batch.params + batch.nparams; - for (rk_command const * command = batch.commands; command < last_command; ++command) { - unsigned binding = RK_PARAMS_BINDING_BASE; - for (rk_parameter const * param = batch.params; param < last_param; ++param, ++binding) { - glBindVertexBuffer(binding, batch.params_array, + rk_command const * const last_command = batch->commands + ncommands; + rk_parameter const * const last_param = batch->params + batch->nparams; + for (rk_command const * command = batch->commands; command < last_command; ++command) { + for (rk_parameter const * param = batch->params; param < last_param; ++param) { + glBindVertexBuffer(param->binding, batch->params_buffer, param->offset + param_index * param->size, param->size); } param_index += command->ninstances; @@ -832,14 +847,9 @@ void rk_draw_batch( if (rk_MultiDrawElementsIndirect) { glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); } - if (batch.nparams && params) { + if (batch->nparams && params) { glBindBuffer(GL_ARRAY_BUFFER, 0); } -} - -void rk_unselect_vertices( - rk_vertices_t _vertices) { - rk_current_vertices = nullptr; glBindVertexArray(0); } @@ -859,7 +869,6 @@ void rk_unselect_texture( void rk_unselect_shader( rk_shader_t _shader) { - rk_current_shader = nullptr; glUseProgram(0); } @@ -877,8 +886,11 @@ void rk_destroy_batch( } if (batch->nparams) { delete[] batch->params; - glDeleteBuffers(1, &batch->params_array); + glDeleteBuffers(1, &batch->params_buffer); } + glDeleteBuffers(1, &batch->indices_buffer); + glDeleteBuffers(1, &batch->vertices_buffer); + glDeleteVertexArrays(1, &batch->vertex_array); delete batch; } } @@ -897,9 +909,9 @@ void rk_destroy_vertices( rk_vertices_t _vertices) { rk_vertices * const vertices = reinterpret_cast(_vertices); if (vertices) { - glDeleteBuffers(1, &vertices->indices); - glDeleteBuffers(1, &vertices->vertices); - glDeleteVertexArrays(1, &vertices->array); + delete[] vertices->format; + delete[] vertices->vertices; + delete[] vertices->indices; delete vertices; } } diff --git a/cpp/render/render_opengles.hpp b/cpp/render/render_opengles.hpp index 892b9ff..3d8af34 100644 --- a/cpp/render/render_opengles.hpp +++ b/cpp/render/render_opengles.hpp @@ -21,11 +21,6 @@ #include #include -enum : GLuint { - RK_VERTICES_BINDING = 0, - RK_PARAMS_BINDING_BASE = 1 -}; - struct rk_shader { GLuint vertex; GLuint fragment; @@ -44,11 +39,11 @@ struct rk_triangles { }; struct rk_vertices { - unsigned vertex_size; - unsigned layout; - GLuint array; - GLuint vertices; - GLuint indices; + unsigned nvertices; + unsigned nindices; + rk_vertex_format * format; + rk_ubyte * vertices; + rk_ushort * indices; }; struct rk_command { @@ -94,6 +89,7 @@ typedef void (*rk_packer)( rk_ubyte const * const); // src struct rk_parameter { + unsigned binding; unsigned offset; unsigned size; rk_packer packer; @@ -103,13 +99,14 @@ struct rk_batch { unsigned max_size; unsigned max_meshes; unsigned nparams; - unsigned commands_size; - unsigned packed_size; rk_ushort * indices; rk_command * commands; rk_parameter * params; + GLuint vertex_array; + GLuint vertices_buffer; + GLuint indices_buffer; GLuint commands_buffer; - GLuint params_array; + GLuint params_buffer; }; #endif // _RK_ENGINE_RENDER_OPENGLES_H