Custom instance parameters.
This commit is contained in:
parent
fa7f1bdaa9
commit
3df976c154
44
__init__.py
44
__init__.py
@ -46,18 +46,19 @@ VERTEX_FORMAT_NORMALIZE = _flag(7)
|
|||||||
def vertex_format(*format):
|
def vertex_format(*format):
|
||||||
return array('B', format).tobytes()
|
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_SPAWNED = _flag(0)
|
||||||
INSTANCE_FLAG_VISIBLE = _flag(1)
|
INSTANCE_FLAG_VISIBLE = _flag(1)
|
||||||
|
|
||||||
BATCH_MAX_SIZE = 65536
|
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
|
#TODO: remove from engine
|
||||||
vec2_zero = (0.0, 0.0)
|
vec2_zero = (0.0, 0.0)
|
||||||
vec3_zero = (0.0, 0.0, 0.0)
|
vec3_zero = (0.0, 0.0, 0.0)
|
||||||
@ -322,8 +323,7 @@ create_batch = _lib.rk_create_batch
|
|||||||
create_batch.restype = ctypes.c_void_p
|
create_batch.restype = ctypes.c_void_p
|
||||||
create_batch.argtypes = (
|
create_batch.argtypes = (
|
||||||
ctypes.c_uint, # max_size
|
ctypes.c_uint, # max_size
|
||||||
ctypes.c_uint, # translation_format
|
ctypes.c_char_p) # params_format
|
||||||
ctypes.c_uint) # orientation_format
|
|
||||||
|
|
||||||
begin_frame = _lib.rk_begin_frame
|
begin_frame = _lib.rk_begin_frame
|
||||||
|
|
||||||
@ -339,21 +339,33 @@ select_vertices = _lib.rk_select_vertices
|
|||||||
select_vertices.argtypes = (
|
select_vertices.argtypes = (
|
||||||
ctypes.c_void_p,) # vertices
|
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 = _lib.rk_draw_batch
|
||||||
_draw_batch.argtypes = (
|
_draw_batch.argtypes = (
|
||||||
ctypes.c_void_p, # batch
|
ctypes.c_void_p, # batch
|
||||||
ctypes.c_uint, # size
|
ctypes.c_uint, # size
|
||||||
ctypes.c_void_p, # flags
|
ctypes.c_void_p, # flags
|
||||||
ctypes.c_void_p, # meshes
|
ctypes.c_void_p, # meshes
|
||||||
ctypes.c_void_p, # translations
|
ctypes.c_void_p) # params
|
||||||
ctypes.c_void_p) # orientations
|
|
||||||
|
|
||||||
def draw_batch(batch, flags, meshes, translations, orientations):
|
def draw_batch(batch, flags, meshes, params):
|
||||||
size = len(flags)
|
size = len(flags)
|
||||||
assert len(meshes) == size and len(translations) == size * 3
|
assert len(meshes) == size
|
||||||
assert not orientations or len(orientations) == size * 3
|
_params = array('L', map(_voidp, params))
|
||||||
_draw_batch(batch, size, _ubytep(flags), _uintp(meshes), _floatp(translations),
|
_draw_batch(batch, size, _ubytep(flags), _uintp(meshes), _voidp(_params))
|
||||||
_floatp(orientations) if orientations else None)
|
|
||||||
|
|
||||||
unselect_vertices = _lib.rk_unselect_vertices
|
unselect_vertices = _lib.rk_unselect_vertices
|
||||||
unselect_vertices.argtypes = (
|
unselect_vertices.argtypes = (
|
||||||
|
@ -33,9 +33,6 @@ static void rk_debug_message_callback(
|
|||||||
GLsizei length,
|
GLsizei length,
|
||||||
GLchar const * message,
|
GLchar const * message,
|
||||||
void const * userParam) {
|
void const * userParam) {
|
||||||
if (id == 131169 || id == 131185 || id == 131218 || id == 131204) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
printf("[RK_ENGINE][GL] (id=%d) %s\n", id, message);
|
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);
|
GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||||
printf("[RK_ENGINE] version: %s, language: %s\n", version, language);
|
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);
|
glDebugMessageCallback(rk_debug_message_callback, nullptr);
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
} else {
|
|
||||||
glDisable(GL_DEBUG_OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_DITHER);
|
glEnable(GL_DITHER);
|
||||||
@ -93,7 +83,6 @@ static void rk_print_program_infolog(GLuint program) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: external loading of shader sources
|
|
||||||
//TODO: error handling
|
//TODO: error handling
|
||||||
rk_shader_t rk_load_shader(
|
rk_shader_t rk_load_shader(
|
||||||
rk_uint const vert_nlines,
|
rk_uint const vert_nlines,
|
||||||
@ -104,11 +93,11 @@ rk_shader_t rk_load_shader(
|
|||||||
shader->vertex = glCreateShader(GL_VERTEX_SHADER);
|
shader->vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
shader->program = glCreateProgram();
|
shader->program = glCreateProgram();
|
||||||
if (vert_nlines == 0 || vert_lines == nullptr) {
|
if (!vert_nlines || !vert_lines) {
|
||||||
rk_printf("Missing vertex shader.");
|
rk_printf("Missing vertex shader.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (frag_nlines == 0 || frag_lines == nullptr) {
|
if (!frag_nlines || !frag_lines) {
|
||||||
rk_printf("Missing fragment shader.");
|
rk_printf("Missing fragment shader.");
|
||||||
return nullptr;
|
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);
|
glVertexAttribFormat(vertices->layout, 4, GL_UNSIGNED_INT_2_10_10_10_REV, normalize, offset);
|
||||||
offset += sizeof(rk_uint);
|
offset += sizeof(rk_uint);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
glVertexAttribBinding(vertices->layout, RK_VERTICES_BINDING);
|
glVertexAttribBinding(vertices->layout, RK_VERTICES_BINDING);
|
||||||
}
|
}
|
||||||
@ -370,84 +357,120 @@ rk_vertices_t rk_create_vertices(
|
|||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: support for mat3 orientations with packing into int10 * 3
|
static rk_uint rk_convert_vec3_float(
|
||||||
// - maybe from quaternions inputs
|
rk_ubyte * const dst,
|
||||||
// - maybe it's possible to implement efficient quaternions in glsl?
|
rk_ubyte const * const src,
|
||||||
|
rk_ushort const idx) {
|
||||||
|
*reinterpret_cast<rk_vec3 *>(dst) = reinterpret_cast<rk_vec3 const *>(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<rk_vec3_short *>(_dst);
|
||||||
|
rk_vec3 const & src = reinterpret_cast<rk_vec3 const *>(_src)[idx];
|
||||||
|
dst->x = static_cast<rk_short>(src.x);
|
||||||
|
dst->y = static_cast<rk_short>(src.y);
|
||||||
|
dst->z = static_cast<rk_short>(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<rk_vec3_short *>(_dst);
|
||||||
|
rk_vec3 const & src = reinterpret_cast<rk_vec3 const *>(_src)[idx];
|
||||||
|
#define _convert(s) (static_cast<rk_short>((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<rk_vec3 const *>(_src)[idx];
|
||||||
|
#define _convert(s) (static_cast<rk_int>((s) * ((s) < 0.f ? 512.f : 511.f)) & 1023)
|
||||||
|
*reinterpret_cast<rk_int *>(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_batch_t rk_create_batch(
|
||||||
rk_uint max_size,
|
rk_uint max_size,
|
||||||
rk_batch_translation_format translation_format,
|
rk_param_format const * params_format) {
|
||||||
rk_batch_orientation_format orientation_format) {
|
if (!max_size || !params_format || max_size > RK_BATCH_MAX_SIZE || !rk_current_shader || !rk_current_vertices) {
|
||||||
if (!max_size || max_size > RK_BATCH_MAX_SIZE || !rk_current_shader || !rk_current_vertices) {
|
rk_printf("rk_create_batch(): invalid parameters.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
rk_uint translation_size = 0;
|
rk_uint nparams = 0;
|
||||||
switch (translation_format) {
|
rk_uint params_size = 0;
|
||||||
case RK_BATCH_TRANSLATION_FORMAT_FLOAT:
|
for (rk_param_format const * f = params_format; *f; ++f, ++nparams) {
|
||||||
translation_size = sizeof(rk_translation_float);
|
switch (*f & RK_PARAM_FORMAT_MASK) {
|
||||||
|
case RK_PARAM_FORMAT_VEC3_FLOAT:
|
||||||
|
params_size += sizeof(rk_vec3);
|
||||||
break;
|
break;
|
||||||
case RK_BATCH_TRANSLATION_FORMAT_SHORT:
|
case RK_PARAM_FORMAT_VEC3_SHORT:
|
||||||
translation_size = sizeof(rk_translation_short);
|
params_size += sizeof(rk_vec3_short);
|
||||||
|
break;
|
||||||
|
case RK_PARAM_FORMAT_VEC3_INT10:
|
||||||
|
params_size += sizeof(rk_int);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rk_printf("rk_create_batch(): invalid translation format.");
|
rk_printf("rk_create_batch(): invalid param format.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
break;
|
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;
|
rk_batch * batch = new rk_batch;
|
||||||
batch->size = max_size;
|
batch->size = max_size;
|
||||||
batch->translation_format = translation_format;
|
batch->nparams = nparams;
|
||||||
batch->orientation_format = orientation_format;
|
|
||||||
batch->params_size = params_size;
|
batch->params_size = params_size;
|
||||||
batch->indices = new rk_ushort[batch->size];
|
batch->indices = new rk_ushort[max_size];
|
||||||
batch->params = new rk_ubyte[batch->size * params_size];
|
batch->commands = new rk_command[max_size * sizeof(rk_command)];
|
||||||
batch->commands = new rk_command[batch->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);
|
glGenBuffers(1, &batch->params_buffer);
|
||||||
rk_uint const translation_layout = rk_current_vertices->layout;
|
rk_uint layout = rk_current_vertices->layout;
|
||||||
glEnableVertexAttribArray(translation_layout);
|
rk_param_converter * converter = batch->converters;
|
||||||
switch (translation_format) {
|
rk_uint offset = 0;
|
||||||
case RK_BATCH_TRANSLATION_FORMAT_FLOAT:
|
for (rk_param_format const * f = params_format; *f; ++f, ++layout, ++converter) {
|
||||||
glVertexAttribFormat(translation_layout, 3, GL_FLOAT, GL_FALSE, 0);
|
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;
|
break;
|
||||||
case RK_BATCH_TRANSLATION_FORMAT_SHORT:
|
case RK_PARAM_FORMAT_VEC3_SHORT:
|
||||||
glVertexAttribFormat(translation_layout, 3, GL_SHORT, GL_FALSE, 0);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
glVertexAttribBinding(translation_layout, RK_PARAMS_BINDING);
|
glVertexAttribBinding(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);
|
glVertexBindingDivisor(RK_PARAMS_BINDING, 1);
|
||||||
glBindVertexBuffer(RK_PARAMS_BINDING, batch->params_buffer, 0, batch->params_size);
|
glBindVertexBuffer(RK_PARAMS_BINDING, batch->params_buffer, 0, batch->params_size);
|
||||||
|
}
|
||||||
if (rk_MultiDrawElementsIndirect) {
|
if (rk_MultiDrawElementsIndirect) {
|
||||||
glGenBuffers(1, &batch->commands_buffer);
|
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<rk_param_t>(location + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rk_set_param_vec3(
|
||||||
|
rk_param_t param,
|
||||||
|
rk_vec3 const & value) {
|
||||||
|
GLint const location = reinterpret_cast<intptr_t>(param) - 1;
|
||||||
|
if (rk_current_shader && location > -1) {
|
||||||
|
glVertexAttrib3fv(location, glm::value_ptr(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static rk_uint rk_batch_filter(
|
static rk_uint rk_batch_filter(
|
||||||
rk_uint const size,
|
rk_uint const size,
|
||||||
rk_ushort * const _indices,
|
rk_ushort * const _indices,
|
||||||
@ -534,32 +575,18 @@ static rk_uint rk_batch_build_commands(
|
|||||||
return commands - _commands;
|
return commands - _commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename _instance_params_t >
|
|
||||||
static void rk_batch_convert_params(
|
static void rk_batch_convert_params(
|
||||||
|
rk_batch & batch,
|
||||||
rk_uint const count,
|
rk_uint const count,
|
||||||
rk_ushort const * const _indices,
|
rk_ubyte const ** const params) {
|
||||||
rk_ubyte * const _params,
|
rk_ubyte * dst = batch.params;
|
||||||
rk_vec3 const * const translations,
|
rk_ushort const * const last_index = batch.indices + count;
|
||||||
rk_vec3 const * const orientations) {
|
rk_ubyte const ** const last_param = params + batch.nparams;
|
||||||
_instance_params_t * params = reinterpret_cast<_instance_params_t *>(_params);
|
for (rk_ushort const * index = batch.indices; index < last_index; ++index) {
|
||||||
rk_ushort const * const last = _indices + count;
|
rk_param_converter const * converter = batch.converters;
|
||||||
for (rk_ushort const * indices = _indices; indices < last; ++indices, ++params) {
|
for (rk_ubyte const ** src = params; src < last_param; ++src, ++converter) {
|
||||||
rk_uint const index = *indices;
|
dst += (*converter)(dst, *src, *index);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,14 +595,9 @@ void rk_draw_batch(
|
|||||||
rk_uint size,
|
rk_uint size,
|
||||||
rk_instance_flags const * flags,
|
rk_instance_flags const * flags,
|
||||||
rk_mesh const * meshes,
|
rk_mesh const * meshes,
|
||||||
rk_vec3 const * translations,
|
rk_ubyte const ** params) {
|
||||||
rk_vec3 const * orientations) {
|
|
||||||
rk_batch & batch = *reinterpret_cast<rk_batch *>(_batch);
|
rk_batch & batch = *reinterpret_cast<rk_batch *>(_batch);
|
||||||
if (!size || size > batch.size || !flags || !meshes || !translations ||
|
if (!size || size > batch.size || !flags || !meshes || !rk_current_shader || !rk_current_vertices) {
|
||||||
!rk_current_shader || !rk_current_vertices) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (batch.orientation_format != RK_BATCH_ORIENTATION_FORMAT_NONE && !orientations) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rk_uint const count = rk_batch_filter(size, batch.indices, flags);
|
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);
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch.commands_buffer);
|
||||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, ncommands * sizeof(rk_command), batch.commands, GL_STREAM_DRAW);
|
glBufferData(GL_DRAW_INDIRECT_BUFFER, ncommands * sizeof(rk_command), batch.commands, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
switch (batch.translation_format) {
|
if (batch.nparams) {
|
||||||
case RK_BATCH_TRANSLATION_FORMAT_FLOAT:
|
rk_batch_convert_params(batch, count, params);
|
||||||
switch (batch.orientation_format) {
|
|
||||||
case RK_BATCH_ORIENTATION_FORMAT_NONE:
|
|
||||||
rk_batch_convert_params<rk_translation_float>(
|
|
||||||
count, batch.indices, batch.params, translations);
|
|
||||||
break;
|
|
||||||
case RK_BATCH_ORIENTATION_FORMAT_FLOAT:
|
|
||||||
rk_batch_convert_params<rk_params_float_float>(
|
|
||||||
count, batch.indices, batch.params, translations, orientations);
|
|
||||||
break;
|
|
||||||
case RK_BATCH_ORIENTATION_FORMAT_INT10:
|
|
||||||
rk_batch_convert_params<rk_params_float_int10>(
|
|
||||||
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<rk_translation_short>(
|
|
||||||
count, batch.indices, batch.params, translations);
|
|
||||||
break;
|
|
||||||
case RK_BATCH_ORIENTATION_FORMAT_FLOAT:
|
|
||||||
rk_batch_convert_params<rk_params_short_float>(
|
|
||||||
count, batch.indices, batch.params, translations, orientations);
|
|
||||||
break;
|
|
||||||
case RK_BATCH_ORIENTATION_FORMAT_INT10:
|
|
||||||
rk_batch_convert_params<rk_params_short_int10>(
|
|
||||||
count, batch.indices, batch.params, translations, orientations);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, batch.params_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, batch.params_buffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, count * batch.params_size, batch.params, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, count * batch.params_size, batch.params, GL_STREAM_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
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 (rk_DrawElementsInstancedBaseInstance) {
|
if (rk_DrawElementsInstancedBaseInstance) {
|
||||||
if (rk_MultiDrawElementsIndirect) {
|
if (rk_MultiDrawElementsIndirect) {
|
||||||
@ -645,8 +632,10 @@ void rk_draw_batch(
|
|||||||
rk_uint params_offset = 0;
|
rk_uint params_offset = 0;
|
||||||
rk_command const * const last_command = batch.commands + ncommands;
|
rk_command const * const last_command = batch.commands + ncommands;
|
||||||
for (rk_command const * command = batch.commands; command < last_command; ++command) {
|
for (rk_command const * command = batch.commands; command < last_command; ++command) {
|
||||||
|
if (batch.nparams) {
|
||||||
glBindVertexBuffer(RK_PARAMS_BINDING, batch.params_buffer, params_offset, batch.params_size);
|
glBindVertexBuffer(RK_PARAMS_BINDING, batch.params_buffer, params_offset, batch.params_size);
|
||||||
params_offset += command->ninstances * batch.params_size;
|
params_offset += command->ninstances * batch.params_size;
|
||||||
|
}
|
||||||
glDrawElementsInstanced(
|
glDrawElementsInstanced(
|
||||||
GL_TRIANGLES, command->count, GL_UNSIGNED_SHORT,
|
GL_TRIANGLES, command->count, GL_UNSIGNED_SHORT,
|
||||||
reinterpret_cast<void const *>(command->base_index << 1),
|
reinterpret_cast<void const *>(command->base_index << 1),
|
||||||
@ -689,9 +678,12 @@ void rk_destroy_batch(
|
|||||||
rk_batch * const batch = reinterpret_cast<rk_batch *>(_batch);
|
rk_batch * const batch = reinterpret_cast<rk_batch *>(_batch);
|
||||||
if (batch) {
|
if (batch) {
|
||||||
delete[] batch->indices;
|
delete[] batch->indices;
|
||||||
delete[] batch->params;
|
|
||||||
delete[] batch->commands;
|
delete[] batch->commands;
|
||||||
|
if (batch->nparams) {
|
||||||
|
delete[] batch->converters;
|
||||||
|
delete[] batch->params;
|
||||||
glDeleteBuffers(1, &batch->params_buffer);
|
glDeleteBuffers(1, &batch->params_buffer);
|
||||||
|
}
|
||||||
if (rk_MultiDrawElementsIndirect) {
|
if (rk_MultiDrawElementsIndirect) {
|
||||||
glDeleteBuffers(1, &batch->commands_buffer);
|
glDeleteBuffers(1, &batch->commands_buffer);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ struct rk_vertices {
|
|||||||
GLuint indices;
|
GLuint indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef rk_uint (*rk_param_converter)(rk_ubyte * const, rk_ubyte const * const, rk_ushort const);
|
||||||
|
|
||||||
struct rk_command {
|
struct rk_command {
|
||||||
GLuint count;
|
GLuint count;
|
||||||
GLuint ninstances;
|
GLuint ninstances;
|
||||||
@ -64,70 +66,21 @@ struct rk_command {
|
|||||||
|
|
||||||
struct rk_batch {
|
struct rk_batch {
|
||||||
rk_uint size;
|
rk_uint size;
|
||||||
rk_batch_translation_format translation_format;
|
rk_uint nparams;
|
||||||
rk_batch_orientation_format orientation_format;
|
|
||||||
rk_uint params_size;
|
rk_uint params_size;
|
||||||
rk_ushort * indices;
|
rk_ushort * indices;
|
||||||
rk_ubyte * params;
|
|
||||||
rk_command * commands;
|
rk_command * commands;
|
||||||
|
rk_param_converter * converters;
|
||||||
|
rk_ubyte * params;
|
||||||
GLuint params_buffer;
|
GLuint params_buffer;
|
||||||
GLuint commands_buffer;
|
GLuint commands_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rk_translation_float {
|
struct rk_vec3_short {
|
||||||
rk_vec3 xyz;
|
|
||||||
|
|
||||||
inline void set(rk_vec3 const & translation) {
|
|
||||||
xyz = translation;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rk_translation_short {
|
|
||||||
rk_short x;
|
rk_short x;
|
||||||
rk_short y;
|
rk_short y;
|
||||||
rk_short z;
|
rk_short z;
|
||||||
rk_short pad;
|
rk_short pad;
|
||||||
|
|
||||||
inline void set(rk_vec3 const & translation) {
|
|
||||||
x = static_cast<rk_short>(translation.x);
|
|
||||||
y = static_cast<rk_short>(translation.y);
|
|
||||||
z = static_cast<rk_short>(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<rk_uint>(static_cast<rk_int>((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_translation_float, rk_orientation_float> rk_params_float_float;
|
|
||||||
typedef rk_params<rk_translation_float, rk_orientation_int10> rk_params_float_int10;
|
|
||||||
typedef rk_params<rk_translation_short, rk_orientation_float> rk_params_short_float;
|
|
||||||
typedef rk_params<rk_translation_short, rk_orientation_int10> rk_params_short_int10;
|
|
||||||
|
|
||||||
#endif // _RK_ENGINE_RENDER_OPENGLES_H
|
#endif // _RK_ENGINE_RENDER_OPENGLES_H
|
||||||
|
@ -25,6 +25,7 @@ typedef rk_handle_t rk_input_t;
|
|||||||
typedef rk_handle_t rk_texture_t;
|
typedef rk_handle_t rk_texture_t;
|
||||||
typedef rk_handle_t rk_triangles_t;
|
typedef rk_handle_t rk_triangles_t;
|
||||||
typedef rk_handle_t rk_vertices_t;
|
typedef rk_handle_t rk_vertices_t;
|
||||||
|
typedef rk_handle_t rk_param_t;
|
||||||
typedef rk_handle_t rk_batch_t;
|
typedef rk_handle_t rk_batch_t;
|
||||||
|
|
||||||
#define RK_FLAG(bit) (1 << (bit))
|
#define RK_FLAG(bit) (1 << (bit))
|
||||||
@ -46,15 +47,23 @@ enum rk_texture_flags : rk_uint {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum rk_vertex_format : rk_ubyte {
|
enum rk_vertex_format : rk_ubyte {
|
||||||
RK_VERTEX_FORMAT_END = 0,
|
|
||||||
RK_VERTEX_FORMAT_VEC3_FLOAT = 1,
|
RK_VERTEX_FORMAT_VEC3_FLOAT = 1,
|
||||||
RK_VERTEX_FORMAT_VEC3_INT10 = 2,
|
RK_VERTEX_FORMAT_VEC3_INT10 = 2,
|
||||||
RK_VERTEX_FORMAT_VEC3_UINT10 = 3,
|
RK_VERTEX_FORMAT_VEC3_UINT10 = 3
|
||||||
|
|
||||||
RK_VERTEX_FORMAT_NORMALIZE = RK_FLAG(7),
|
|
||||||
RK_VERTEX_FORMAT_MASK = RK_VERTEX_FORMAT_NORMALIZE - 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 {
|
enum rk_instance_flags : rk_ubyte {
|
||||||
RK_INSTANCE_FLAG_SPAWNED = RK_FLAG(0),
|
RK_INSTANCE_FLAG_SPAWNED = RK_FLAG(0),
|
||||||
RK_INSTANCE_FLAG_VISIBLE = RK_FLAG(1)
|
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_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 {
|
union rk_mesh {
|
||||||
rk_uint packed;
|
rk_uint packed;
|
||||||
struct {
|
struct {
|
||||||
@ -139,8 +137,7 @@ RK_EXPORT rk_vertices_t rk_create_vertices(
|
|||||||
|
|
||||||
RK_EXPORT rk_batch_t rk_create_batch(
|
RK_EXPORT rk_batch_t rk_create_batch(
|
||||||
rk_uint max_size,
|
rk_uint max_size,
|
||||||
rk_batch_translation_format translation_format,
|
rk_param_format const * params_format);
|
||||||
rk_batch_orientation_format orientation_format);
|
|
||||||
|
|
||||||
RK_EXPORT void rk_begin_frame();
|
RK_EXPORT void rk_begin_frame();
|
||||||
|
|
||||||
@ -153,13 +150,19 @@ RK_EXPORT void rk_draw_triangles(
|
|||||||
RK_EXPORT void rk_select_vertices(
|
RK_EXPORT void rk_select_vertices(
|
||||||
rk_vertices_t 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_EXPORT void rk_draw_batch(
|
||||||
rk_batch_t batch,
|
rk_batch_t batch,
|
||||||
rk_uint size,
|
rk_uint size,
|
||||||
rk_instance_flags const * flags,
|
rk_instance_flags const * flags,
|
||||||
rk_mesh const * meshes,
|
rk_mesh const * meshes,
|
||||||
rk_vec3 const * translations,
|
rk_ubyte const ** params);
|
||||||
rk_vec3 const * orientations);
|
|
||||||
|
|
||||||
RK_EXPORT void rk_unselect_vertices(
|
RK_EXPORT void rk_unselect_vertices(
|
||||||
rk_vertices_t vertices);
|
rk_vertices_t vertices);
|
||||||
|
Loading…
Reference in New Issue
Block a user