From 3df976c154f76351702fe9f512f09c072dd67f60 Mon Sep 17 00:00:00 2001 From: Roz K Date: Sat, 17 Dec 2022 04:58:19 +0100 Subject: [PATCH] Custom instance parameters. --- __init__.py | 46 +++-- cpp/opengl/render_opengles.cpp | 312 ++++++++++++++++----------------- cpp/opengl/render_opengles.hpp | 59 +------ cpp/render.hpp | 43 ++--- 4 files changed, 210 insertions(+), 250 deletions(-) diff --git a/__init__.py b/__init__.py index 38c3bc7..3a38387 100644 --- a/__init__.py +++ b/__init__.py @@ -46,18 +46,19 @@ VERTEX_FORMAT_NORMALIZE = _flag(7) def vertex_format(*format): return array('B', format).tobytes() +PARAM_FORMAT_VEC3_FLOAT = 1 +PARAM_FORMAT_VEC3_SHORT = 2 +PARAM_FORMAT_VEC3_INT10 = 3 +PARAM_FORMAT_NORMALIZE = _flag(7) + +def params_format(*format): + return array('B', format).tobytes() + INSTANCE_FLAG_SPAWNED = _flag(0) INSTANCE_FLAG_VISIBLE = _flag(1) BATCH_MAX_SIZE = 65536 -BATCH_TRANSLATION_FORMAT_FLOAT = 0 -BATCH_TRANSLATION_FORMAT_SHORT = 1 - -BATCH_ORIENTATION_FORMAT_NONE = 0 -BATCH_ORIENTATION_FORMAT_FLOAT = 1 -BATCH_ORIENTATION_FORMAT_INT10 = 2 - #TODO: remove from engine vec2_zero = (0.0, 0.0) vec3_zero = (0.0, 0.0, 0.0) @@ -243,7 +244,7 @@ select_shader.argtypes = ( ctypes.c_void_p,) # shader resolve_input = _lib.rk_resolve_input -resolve_input.restype = ctypes.c_void_p +resolve_input.restype = ctypes.c_void_p resolve_input.argtypes = ( ctypes.c_char_p,) # name @@ -322,8 +323,7 @@ create_batch = _lib.rk_create_batch create_batch.restype = ctypes.c_void_p create_batch.argtypes = ( ctypes.c_uint, # max_size - ctypes.c_uint, # translation_format - ctypes.c_uint) # orientation_format + ctypes.c_char_p) # params_format begin_frame = _lib.rk_begin_frame @@ -339,21 +339,33 @@ select_vertices = _lib.rk_select_vertices select_vertices.argtypes = ( ctypes.c_void_p,) # vertices +resolve_param = _lib.rk_resolve_param +resolve_param.restype = ctypes.c_void_p +resolve_param.argtypes = ( + ctypes.c_char_p,) # name + +_set_param_vec3 = _lib.rk_set_param_vec3 +_set_param_vec3.argtypes = ( + ctypes.c_uint, # layout + _vec3_t) # value + +def set_param_vec3(param, value): + assert len(value) == 3 + _set_param_vec3(param, _vec3(value)) + _draw_batch = _lib.rk_draw_batch _draw_batch.argtypes = ( ctypes.c_void_p, # batch ctypes.c_uint, # size ctypes.c_void_p, # flags ctypes.c_void_p, # meshes - ctypes.c_void_p, # translations - ctypes.c_void_p) # orientations + ctypes.c_void_p) # params -def draw_batch(batch, flags, meshes, translations, orientations): +def draw_batch(batch, flags, meshes, params): size = len(flags) - assert len(meshes) == size and len(translations) == size * 3 - assert not orientations or len(orientations) == size * 3 - _draw_batch(batch, size, _ubytep(flags), _uintp(meshes), _floatp(translations), - _floatp(orientations) if orientations else None) + assert len(meshes) == size + _params = array('L', map(_voidp, params)) + _draw_batch(batch, size, _ubytep(flags), _uintp(meshes), _voidp(_params)) unselect_vertices = _lib.rk_unselect_vertices unselect_vertices.argtypes = ( diff --git a/cpp/opengl/render_opengles.cpp b/cpp/opengl/render_opengles.cpp index 796b2f4..a8456a4 100644 --- a/cpp/opengl/render_opengles.cpp +++ b/cpp/opengl/render_opengles.cpp @@ -33,9 +33,6 @@ static void rk_debug_message_callback( GLsizei length, GLchar const * message, void const * userParam) { - if (id == 131169 || id == 131185 || id == 131218 || id == 131204) { - return; - } printf("[RK_ENGINE][GL] (id=%d) %s\n", id, message); } @@ -52,15 +49,8 @@ rk_window_t rk_initialize( GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION); printf("[RK_ENGINE] version: %s, language: %s\n", version, language); - GLint context_flags = 0; - glGetIntegerv(GL_CONTEXT_FLAGS, &context_flags); - if (context_flags & GL_CONTEXT_FLAG_DEBUG_BIT) { - printf("[RK_ENGINE] Debug context enabled\n"); - glDebugMessageCallback(rk_debug_message_callback, nullptr); - glEnable(GL_DEBUG_OUTPUT); - } else { - glDisable(GL_DEBUG_OUTPUT); - } + glDebugMessageCallback(rk_debug_message_callback, nullptr); + glEnable(GL_DEBUG_OUTPUT); glDisable(GL_BLEND); glEnable(GL_DITHER); @@ -93,7 +83,6 @@ static void rk_print_program_infolog(GLuint program) { } } -//TODO: external loading of shader sources //TODO: error handling rk_shader_t rk_load_shader( rk_uint const vert_nlines, @@ -104,11 +93,11 @@ rk_shader_t rk_load_shader( shader->vertex = glCreateShader(GL_VERTEX_SHADER); shader->fragment = glCreateShader(GL_FRAGMENT_SHADER); shader->program = glCreateProgram(); - if (vert_nlines == 0 || vert_lines == nullptr) { + if (!vert_nlines || !vert_lines) { rk_printf("Missing vertex shader."); return nullptr; } - if (frag_nlines == 0 || frag_lines == nullptr) { + if (!frag_nlines || !frag_lines) { rk_printf("Missing fragment shader."); return nullptr; } @@ -357,8 +346,6 @@ rk_vertices_t rk_create_vertices( glVertexAttribFormat(vertices->layout, 4, GL_UNSIGNED_INT_2_10_10_10_REV, normalize, offset); offset += sizeof(rk_uint); break; - default: - break; } glVertexAttribBinding(vertices->layout, RK_VERTICES_BINDING); } @@ -370,84 +357,120 @@ rk_vertices_t rk_create_vertices( return vertices; } -//TODO: support for mat3 orientations with packing into int10 * 3 -// - maybe from quaternions inputs -// - maybe it's possible to implement efficient quaternions in glsl? +static rk_uint rk_convert_vec3_float( + rk_ubyte * const dst, + rk_ubyte const * const src, + rk_ushort const idx) { + *reinterpret_cast(dst) = reinterpret_cast(src)[idx]; + return sizeof(rk_vec3); +} + +static rk_uint rk_convert_vec3_short( + rk_ubyte * const _dst, + rk_ubyte const * const _src, + rk_ushort const idx) { + rk_vec3_short * const dst = reinterpret_cast(_dst); + rk_vec3 const & src = reinterpret_cast(_src)[idx]; + dst->x = static_cast(src.x); + dst->y = static_cast(src.y); + dst->z = static_cast(src.z); + return sizeof(rk_vec3_short); +} + +static rk_uint rk_convert_vec3_short_normalize( + rk_ubyte * const _dst, + rk_ubyte const * const _src, + rk_ushort const idx) { + rk_vec3_short * const dst = reinterpret_cast(_dst); + rk_vec3 const & src = reinterpret_cast(_src)[idx]; + #define _convert(s) (static_cast((s) * ((s) < 0.f ? 32768.f : 32767.f))) + dst->x = _convert(src.x); + dst->y = _convert(src.y); + dst->z = _convert(src.z); + #undef _convert + return sizeof(rk_vec3_short); +} + +static rk_uint rk_convert_vec3_int10( + rk_ubyte * const dst, + rk_ubyte const * const _src, + rk_ushort const idx) { + rk_vec3 const & src = reinterpret_cast(_src)[idx]; + #define _convert(s) (static_cast((s) * ((s) < 0.f ? 512.f : 511.f)) & 1023) + *reinterpret_cast(dst) = _convert(src.x) | (_convert(src.y) << 10) | (_convert(src.z) << 20); + #undef _convert + return sizeof(rk_int); +} rk_batch_t rk_create_batch( rk_uint max_size, - rk_batch_translation_format translation_format, - rk_batch_orientation_format orientation_format) { - if (!max_size || max_size > RK_BATCH_MAX_SIZE || !rk_current_shader || !rk_current_vertices) { + rk_param_format const * params_format) { + if (!max_size || !params_format || max_size > RK_BATCH_MAX_SIZE || !rk_current_shader || !rk_current_vertices) { + rk_printf("rk_create_batch(): invalid parameters."); return nullptr; } - rk_uint translation_size = 0; - switch (translation_format) { - case RK_BATCH_TRANSLATION_FORMAT_FLOAT: - translation_size = sizeof(rk_translation_float); - break; - case RK_BATCH_TRANSLATION_FORMAT_SHORT: - translation_size = sizeof(rk_translation_short); - break; - default: - rk_printf("rk_create_batch(): invalid translation format."); - return nullptr; - break; + rk_uint nparams = 0; + rk_uint params_size = 0; + 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); + break; + case RK_PARAM_FORMAT_VEC3_SHORT: + params_size += sizeof(rk_vec3_short); + break; + case RK_PARAM_FORMAT_VEC3_INT10: + params_size += sizeof(rk_int); + break; + default: + rk_printf("rk_create_batch(): invalid param format."); + return nullptr; + break; + } } - rk_uint orientation_size = 0; - switch (orientation_format) { - case RK_BATCH_ORIENTATION_FORMAT_NONE: - orientation_size = 0; - break; - case RK_BATCH_ORIENTATION_FORMAT_FLOAT: - orientation_size = sizeof(rk_orientation_float); - break; - case RK_BATCH_ORIENTATION_FORMAT_INT10: - orientation_size = sizeof(rk_orientation_int10); - break; - default: - rk_printf("rk_create_batch(): invalid orientation format."); - return nullptr; - break; - } - rk_uint const params_size = translation_size + orientation_size; rk_batch * batch = new rk_batch; batch->size = max_size; - batch->translation_format = translation_format; - batch->orientation_format = orientation_format; + batch->nparams = nparams; batch->params_size = params_size; - batch->indices = new rk_ushort[batch->size]; - batch->params = new rk_ubyte[batch->size * params_size]; - batch->commands = new rk_command[batch->size * sizeof(rk_command)]; - glGenBuffers(1, &batch->params_buffer); - rk_uint const translation_layout = rk_current_vertices->layout; - glEnableVertexAttribArray(translation_layout); - switch (translation_format) { - case RK_BATCH_TRANSLATION_FORMAT_FLOAT: - glVertexAttribFormat(translation_layout, 3, GL_FLOAT, GL_FALSE, 0); - break; - case RK_BATCH_TRANSLATION_FORMAT_SHORT: - glVertexAttribFormat(translation_layout, 3, GL_SHORT, GL_FALSE, 0); - break; + batch->indices = new rk_ushort[max_size]; + batch->commands = new rk_command[max_size * sizeof(rk_command)]; + if (nparams) { + batch->converters = new rk_param_converter[nparams]; + batch->params = new rk_ubyte[max_size * params_size]; + glGenBuffers(1, &batch->params_buffer); + rk_uint layout = rk_current_vertices->layout; + rk_param_converter * converter = batch->converters; + rk_uint offset = 0; + for (rk_param_format const * f = params_format; *f; ++f, ++layout, ++converter) { + GLboolean const normalize = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0; + glEnableVertexAttribArray(layout); + switch (*f & RK_PARAM_FORMAT_MASK) { + case RK_PARAM_FORMAT_VEC3_FLOAT: + glVertexAttribFormat(layout, 3, GL_FLOAT, normalize, offset); + *converter = rk_convert_vec3_float; + offset += sizeof(rk_vec3); + break; + case RK_PARAM_FORMAT_VEC3_SHORT: + glVertexAttribFormat(layout, 3, GL_SHORT, normalize, offset); + if (normalize) { + *converter = rk_convert_vec3_short_normalize; + } + else { + *converter = rk_convert_vec3_short; + } + offset += sizeof(rk_vec3_short); + break; + case RK_PARAM_FORMAT_VEC3_INT10: + glVertexAttribFormat(layout, 4, GL_INT_2_10_10_10_REV, normalize, offset); + *converter = rk_convert_vec3_int10; + offset += sizeof(rk_int); + break; + } + glVertexAttribBinding(layout, RK_PARAMS_BINDING); + } + glVertexBindingDivisor(RK_PARAMS_BINDING, 1); + glBindVertexBuffer(RK_PARAMS_BINDING, batch->params_buffer, 0, batch->params_size); } - glVertexAttribBinding(translation_layout, RK_PARAMS_BINDING); - rk_uint const orientation_layout = rk_current_vertices->layout + 1; - switch (orientation_format) { - case RK_BATCH_ORIENTATION_FORMAT_NONE: - break; - case RK_BATCH_ORIENTATION_FORMAT_FLOAT: - glEnableVertexAttribArray(orientation_layout); - glVertexAttribFormat(orientation_layout, 3, GL_FLOAT, GL_FALSE, translation_size); - glVertexAttribBinding(orientation_layout, RK_PARAMS_BINDING); - break; - case RK_BATCH_ORIENTATION_FORMAT_INT10: - glEnableVertexAttribArray(orientation_layout); - glVertexAttribFormat(orientation_layout, GL_BGRA, GL_INT_2_10_10_10_REV, GL_TRUE, translation_size); - glVertexAttribBinding(orientation_layout, RK_PARAMS_BINDING); - break; - } - glVertexBindingDivisor(RK_PARAMS_BINDING, 1); - glBindVertexBuffer(RK_PARAMS_BINDING, batch->params_buffer, 0, batch->params_size); if (rk_MultiDrawElementsIndirect) { glGenBuffers(1, &batch->commands_buffer); } @@ -493,6 +516,24 @@ void rk_select_vertices( } } +rk_param_t rk_resolve_param( + char const * name) { + if (!rk_current_shader || !name) { + return nullptr; + } + GLint const location = glGetAttribLocation(rk_current_shader->program, name); + return reinterpret_cast(location + 1); +} + +void rk_set_param_vec3( + rk_param_t param, + rk_vec3 const & value) { + GLint const location = reinterpret_cast(param) - 1; + if (rk_current_shader && location > -1) { + glVertexAttrib3fv(location, glm::value_ptr(value)); + } +} + static rk_uint rk_batch_filter( rk_uint const size, rk_ushort * const _indices, @@ -534,32 +575,18 @@ static rk_uint rk_batch_build_commands( return commands - _commands; } -template < typename _instance_params_t > static void rk_batch_convert_params( + rk_batch & batch, rk_uint const count, - rk_ushort const * const _indices, - rk_ubyte * const _params, - rk_vec3 const * const translations, - rk_vec3 const * const orientations) { - _instance_params_t * params = reinterpret_cast<_instance_params_t *>(_params); - rk_ushort const * const last = _indices + count; - for (rk_ushort const * indices = _indices; indices < last; ++indices, ++params) { - rk_uint const index = *indices; - params->set(translations[index], orientations[index]); - } -} - -template < typename _instance_params_t > -static void rk_batch_convert_params( - rk_uint const count, - rk_ushort const * const _indices, - rk_ubyte * const _params, - rk_vec3 const * const translations) { - _instance_params_t * params = reinterpret_cast<_instance_params_t *>(_params); - rk_ushort const * const last = _indices + count; - for (rk_ushort const * indices = _indices; indices < last; ++indices, ++params) { - rk_uint const index = *indices; - params->set(translations[index]); + rk_ubyte const ** const params) { + rk_ubyte * dst = batch.params; + rk_ushort const * const last_index = batch.indices + count; + rk_ubyte const ** const last_param = params + batch.nparams; + for (rk_ushort const * index = batch.indices; index < last_index; ++index) { + rk_param_converter const * converter = batch.converters; + for (rk_ubyte const ** src = params; src < last_param; ++src, ++converter) { + dst += (*converter)(dst, *src, *index); + } } } @@ -568,14 +595,9 @@ void rk_draw_batch( rk_uint size, rk_instance_flags const * flags, rk_mesh const * meshes, - rk_vec3 const * translations, - rk_vec3 const * orientations) { + rk_ubyte const ** params) { rk_batch & batch = *reinterpret_cast(_batch); - if (!size || size > batch.size || !flags || !meshes || !translations || - !rk_current_shader || !rk_current_vertices) { - return; - } - if (batch.orientation_format != RK_BATCH_ORIENTATION_FORMAT_NONE && !orientations) { + if (!size || size > batch.size || !flags || !meshes || !rk_current_shader || !rk_current_vertices) { return; } rk_uint const count = rk_batch_filter(size, batch.indices, flags); @@ -587,46 +609,11 @@ void rk_draw_batch( glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch.commands_buffer); glBufferData(GL_DRAW_INDIRECT_BUFFER, ncommands * sizeof(rk_command), batch.commands, GL_STREAM_DRAW); } - switch (batch.translation_format) { - case RK_BATCH_TRANSLATION_FORMAT_FLOAT: - switch (batch.orientation_format) { - case RK_BATCH_ORIENTATION_FORMAT_NONE: - rk_batch_convert_params( - count, batch.indices, batch.params, translations); - break; - case RK_BATCH_ORIENTATION_FORMAT_FLOAT: - rk_batch_convert_params( - count, batch.indices, batch.params, translations, orientations); - break; - case RK_BATCH_ORIENTATION_FORMAT_INT10: - rk_batch_convert_params( - count, batch.indices, batch.params, translations, orientations); - break; - } - break; - case RK_BATCH_TRANSLATION_FORMAT_SHORT: - switch (batch.orientation_format) { - case RK_BATCH_ORIENTATION_FORMAT_NONE: - rk_batch_convert_params( - count, batch.indices, batch.params, translations); - break; - case RK_BATCH_ORIENTATION_FORMAT_FLOAT: - rk_batch_convert_params( - count, batch.indices, batch.params, translations, orientations); - break; - case RK_BATCH_ORIENTATION_FORMAT_INT10: - rk_batch_convert_params( - count, batch.indices, batch.params, translations, orientations); - break; - } - break; - } - glBindBuffer(GL_ARRAY_BUFFER, batch.params_buffer); - glBufferData(GL_ARRAY_BUFFER, count * batch.params_size, batch.params, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - if (batch.orientation_format == RK_BATCH_ORIENTATION_FORMAT_NONE) { - rk_vec3 const forward(0.f, 1.f, 0.f); - glVertexAttrib3fv(rk_current_vertices->layout + 1, glm::value_ptr(forward)); + if (batch.nparams) { + rk_batch_convert_params(batch, count, params); + glBindBuffer(GL_ARRAY_BUFFER, batch.params_buffer); + glBufferData(GL_ARRAY_BUFFER, count * batch.params_size, batch.params, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); } if (rk_DrawElementsInstancedBaseInstance) { if (rk_MultiDrawElementsIndirect) { @@ -645,8 +632,10 @@ void rk_draw_batch( rk_uint params_offset = 0; rk_command const * const last_command = batch.commands + ncommands; for (rk_command const * command = batch.commands; command < last_command; ++command) { - glBindVertexBuffer(RK_PARAMS_BINDING, batch.params_buffer, params_offset, batch.params_size); - params_offset += command->ninstances * batch.params_size; + if (batch.nparams) { + glBindVertexBuffer(RK_PARAMS_BINDING, batch.params_buffer, params_offset, batch.params_size); + params_offset += command->ninstances * batch.params_size; + } glDrawElementsInstanced( GL_TRIANGLES, command->count, GL_UNSIGNED_SHORT, reinterpret_cast(command->base_index << 1), @@ -689,9 +678,12 @@ void rk_destroy_batch( rk_batch * const batch = reinterpret_cast(_batch); if (batch) { delete[] batch->indices; - delete[] batch->params; delete[] batch->commands; - glDeleteBuffers(1, &batch->params_buffer); + if (batch->nparams) { + delete[] batch->converters; + delete[] batch->params; + glDeleteBuffers(1, &batch->params_buffer); + } if (rk_MultiDrawElementsIndirect) { glDeleteBuffers(1, &batch->commands_buffer); } diff --git a/cpp/opengl/render_opengles.hpp b/cpp/opengl/render_opengles.hpp index 18589fa..3490f1c 100644 --- a/cpp/opengl/render_opengles.hpp +++ b/cpp/opengl/render_opengles.hpp @@ -54,6 +54,8 @@ struct rk_vertices { GLuint indices; }; +typedef rk_uint (*rk_param_converter)(rk_ubyte * const, rk_ubyte const * const, rk_ushort const); + struct rk_command { GLuint count; GLuint ninstances; @@ -64,70 +66,21 @@ struct rk_command { struct rk_batch { rk_uint size; - rk_batch_translation_format translation_format; - rk_batch_orientation_format orientation_format; + rk_uint nparams; rk_uint params_size; rk_ushort * indices; - rk_ubyte * params; rk_command * commands; + rk_param_converter * converters; + rk_ubyte * params; GLuint params_buffer; GLuint commands_buffer; }; -struct rk_translation_float { - rk_vec3 xyz; - - inline void set(rk_vec3 const & translation) { - xyz = translation; - } -}; - -struct rk_translation_short { +struct rk_vec3_short { rk_short x; rk_short y; rk_short z; rk_short pad; - - inline void set(rk_vec3 const & translation) { - x = static_cast(translation.x); - y = static_cast(translation.y); - z = static_cast(translation.z); - pad = 0; - } }; -struct rk_orientation_float { - rk_vec3 xyz; - - inline void set(rk_vec3 const & orientation) { - xyz = orientation; - } -}; - -struct rk_orientation_int10 { - rk_uint xyz; - - inline void set(rk_vec3 const & orientation) { - #define _pack_10(x) static_cast(static_cast((x) * ((x) < 0.f ? 512.f : 511.f)) & 1023) - xyz = _pack_10(orientation.x) << 20 | _pack_10(orientation.y) << 10 | _pack_10(orientation.z); - #undef _pack_10 - } -}; - -template < typename _translation_t, typename _orientation_t > -struct rk_params { - _translation_t translation; - _orientation_t orientation; - - inline void set(rk_vec3 const & translation, rk_vec3 const & orientation) { - this->translation.set(translation); - this->orientation.set(orientation); - } -}; - -typedef rk_params rk_params_float_float; -typedef rk_params rk_params_float_int10; -typedef rk_params rk_params_short_float; -typedef rk_params rk_params_short_int10; - #endif // _RK_ENGINE_RENDER_OPENGLES_H diff --git a/cpp/render.hpp b/cpp/render.hpp index 6003f97..a4cff1a 100644 --- a/cpp/render.hpp +++ b/cpp/render.hpp @@ -25,6 +25,7 @@ typedef rk_handle_t rk_input_t; typedef rk_handle_t rk_texture_t; typedef rk_handle_t rk_triangles_t; typedef rk_handle_t rk_vertices_t; +typedef rk_handle_t rk_param_t; typedef rk_handle_t rk_batch_t; #define RK_FLAG(bit) (1 << (bit)) @@ -46,15 +47,23 @@ enum rk_texture_flags : rk_uint { }; enum rk_vertex_format : rk_ubyte { - RK_VERTEX_FORMAT_END = 0, RK_VERTEX_FORMAT_VEC3_FLOAT = 1, RK_VERTEX_FORMAT_VEC3_INT10 = 2, - RK_VERTEX_FORMAT_VEC3_UINT10 = 3, - - RK_VERTEX_FORMAT_NORMALIZE = RK_FLAG(7), - RK_VERTEX_FORMAT_MASK = RK_VERTEX_FORMAT_NORMALIZE - 1 + RK_VERTEX_FORMAT_VEC3_UINT10 = 3 }; +enum : rk_ubyte { RK_VERTEX_FORMAT_NORMALIZE = RK_FLAG(7) }; +enum : rk_ubyte { RK_VERTEX_FORMAT_MASK = RK_VERTEX_FORMAT_NORMALIZE - 1 }; + +enum rk_param_format : rk_ubyte { + RK_PARAM_FORMAT_VEC3_FLOAT = 1, + RK_PARAM_FORMAT_VEC3_SHORT = 2, + RK_PARAM_FORMAT_VEC3_INT10 = 3 +}; + +enum : rk_ubyte { RK_PARAM_FORMAT_NORMALIZE = RK_FLAG(7) }; +enum : rk_ubyte { RK_PARAM_FORMAT_MASK = RK_PARAM_FORMAT_NORMALIZE - 1 }; + enum rk_instance_flags : rk_ubyte { RK_INSTANCE_FLAG_SPAWNED = RK_FLAG(0), RK_INSTANCE_FLAG_VISIBLE = RK_FLAG(1) @@ -64,17 +73,6 @@ enum : rk_ubyte { RK_INSTANCE_FLAGS_SPAWNED_VISIBLE = RK_INSTANCE_FLAG_SPAWNED | enum : rk_uint { RK_BATCH_MAX_SIZE = 65536 }; -enum rk_batch_translation_format : rk_uint { - RK_BATCH_TRANSLATION_FORMAT_FLOAT = 0, - RK_BATCH_TRANSLATION_FORMAT_SHORT = 1 -}; - -enum rk_batch_orientation_format : rk_uint { - RK_BATCH_ORIENTATION_FORMAT_NONE = 0, - RK_BATCH_ORIENTATION_FORMAT_FLOAT = 1, - RK_BATCH_ORIENTATION_FORMAT_INT10 = 2 -}; - union rk_mesh { rk_uint packed; struct { @@ -139,8 +137,7 @@ RK_EXPORT rk_vertices_t rk_create_vertices( RK_EXPORT rk_batch_t rk_create_batch( rk_uint max_size, - rk_batch_translation_format translation_format, - rk_batch_orientation_format orientation_format); + rk_param_format const * params_format); RK_EXPORT void rk_begin_frame(); @@ -153,13 +150,19 @@ RK_EXPORT void rk_draw_triangles( RK_EXPORT void rk_select_vertices( rk_vertices_t vertices); +RK_EXPORT rk_param_t rk_resolve_param( + char const * name); + +RK_EXPORT void rk_set_param_vec3( + rk_param_t param, + rk_vec3 const & value); + RK_EXPORT void rk_draw_batch( rk_batch_t batch, rk_uint size, rk_instance_flags const * flags, rk_mesh const * meshes, - rk_vec3 const * translations, - rk_vec3 const * orientations); + rk_ubyte const ** params); RK_EXPORT void rk_unselect_vertices( rk_vertices_t vertices);