|
|
@ -17,7 +17,6 @@
|
|
|
|
#include "render_opengles.hpp"
|
|
|
|
#include "render_opengles.hpp"
|
|
|
|
#include "../display/display_glx.hpp"
|
|
|
|
#include "../display/display_glx.hpp"
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef void (*rk_DrawElementsInstancedBaseInstanceFunc)(rk_uint, rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
|
|
|
typedef void (*rk_DrawElementsInstancedBaseInstanceFunc)(rk_uint, rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
|
|
|
typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
|
|
|
typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
|
|
@ -49,7 +48,8 @@ static void rk_debug_message_callback(
|
|
|
|
printf("[GL] (id=%d) %s\n", id, message);
|
|
|
|
printf("[GL] (id=%d) %s\n", id, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rk_render_initialize() {
|
|
|
|
void rk_render_initialize(
|
|
|
|
|
|
|
|
rk_bool debug) {
|
|
|
|
GLubyte const * const vendor = glGetString(GL_VENDOR);
|
|
|
|
GLubyte const * const vendor = glGetString(GL_VENDOR);
|
|
|
|
GLubyte const * const renderer = glGetString(GL_RENDERER);
|
|
|
|
GLubyte const * const renderer = glGetString(GL_RENDERER);
|
|
|
|
printf("[GL] vendor: %s, renderer: %s\n", vendor, renderer);
|
|
|
|
printf("[GL] vendor: %s, renderer: %s\n", vendor, renderer);
|
|
|
@ -57,8 +57,10 @@ void rk_render_initialize() {
|
|
|
|
GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
|
|
GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
|
|
printf("[GL] version: %s, language: %s\n", version, language);
|
|
|
|
printf("[GL] version: %s, language: %s\n", version, language);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
glDebugMessageCallback(rk_debug_message_callback, nullptr);
|
|
|
|
glDebugMessageCallback(rk_debug_message_callback, nullptr);
|
|
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char const * const gl_exts = reinterpret_cast<char const *>(glGetString(GL_EXTENSIONS));
|
|
|
|
char const * const gl_exts = reinterpret_cast<char const *>(glGetString(GL_EXTENSIONS));
|
|
|
|
// printf("[GL] %s\n", gl_exts);
|
|
|
|
// printf("[GL] %s\n", gl_exts);
|
|
|
@ -373,6 +375,7 @@ static void rk_pack_vec3_short(
|
|
|
|
dst->x = static_cast<rk_short>(input.x);
|
|
|
|
dst->x = static_cast<rk_short>(input.x);
|
|
|
|
dst->y = static_cast<rk_short>(input.y);
|
|
|
|
dst->y = static_cast<rk_short>(input.y);
|
|
|
|
dst->z = static_cast<rk_short>(input.z);
|
|
|
|
dst->z = static_cast<rk_short>(input.z);
|
|
|
|
|
|
|
|
dst->pad = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -390,6 +393,7 @@ static void rk_pack_vec3_short_norm(
|
|
|
|
dst->x = _convert(input.x);
|
|
|
|
dst->x = _convert(input.x);
|
|
|
|
dst->y = _convert(input.y);
|
|
|
|
dst->y = _convert(input.y);
|
|
|
|
dst->z = _convert(input.z);
|
|
|
|
dst->z = _convert(input.z);
|
|
|
|
|
|
|
|
dst->pad = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef _convert
|
|
|
|
#undef _convert
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -493,18 +497,19 @@ rk_batch_t rk_create_batch(
|
|
|
|
rk_batch * batch = new rk_batch;
|
|
|
|
rk_batch * batch = new rk_batch;
|
|
|
|
batch->max_size = max_size;
|
|
|
|
batch->max_size = max_size;
|
|
|
|
batch->nparams = nparams;
|
|
|
|
batch->nparams = nparams;
|
|
|
|
|
|
|
|
batch->commands_size = 0;
|
|
|
|
|
|
|
|
batch->packed_size = 0;
|
|
|
|
batch->indices = nullptr;
|
|
|
|
batch->indices = nullptr;
|
|
|
|
batch->commands = nullptr;
|
|
|
|
batch->commands = nullptr;
|
|
|
|
batch->params = nullptr;
|
|
|
|
batch->params = nullptr;
|
|
|
|
batch->packed_params = nullptr;
|
|
|
|
batch->commands_buffer = 0;
|
|
|
|
batch->indirect_buffer = 0;
|
|
|
|
|
|
|
|
batch->params_array = 0;
|
|
|
|
batch->params_array = 0;
|
|
|
|
unsigned params_size = 0;
|
|
|
|
unsigned packed_size = 0;
|
|
|
|
if (nparams) {
|
|
|
|
if (nparams) {
|
|
|
|
batch->params = new rk_parameter[nparams];
|
|
|
|
batch->params = new rk_parameter[nparams];
|
|
|
|
rk_parameter * param = batch->params;
|
|
|
|
rk_parameter * param = batch->params;
|
|
|
|
for (rk_param_format const * f = params_format; *f; ++f, ++param) {
|
|
|
|
for (rk_param_format const * f = params_format; *f; ++f, ++param) {
|
|
|
|
param->offset = params_size;
|
|
|
|
param->offset = packed_size;
|
|
|
|
bool const norm = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0;
|
|
|
|
bool const norm = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0;
|
|
|
|
switch (*f & RK_PARAM_FORMAT_MASK) {
|
|
|
|
switch (*f & RK_PARAM_FORMAT_MASK) {
|
|
|
|
case RK_PARAM_FORMAT_VEC3_FLOAT:
|
|
|
|
case RK_PARAM_FORMAT_VEC3_FLOAT:
|
|
|
@ -534,26 +539,25 @@ rk_batch_t rk_create_batch(
|
|
|
|
return nullptr;
|
|
|
|
return nullptr;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
params_size += max_size * param->size;
|
|
|
|
packed_size += max_size * param->size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
batch->commands_size = max_size * sizeof(rk_command);
|
|
|
|
|
|
|
|
batch->packed_size = packed_size;
|
|
|
|
batch->indices = new rk_ushort[max_size];
|
|
|
|
batch->indices = new rk_ushort[max_size];
|
|
|
|
batch->commands = new rk_command[max_size];
|
|
|
|
batch->commands = new rk_command[max_size];
|
|
|
|
memset(batch->commands, 0, max_size * sizeof(rk_command));
|
|
|
|
memset(batch->commands, 0, batch->commands_size);
|
|
|
|
batch->indirect_buffer = 0;
|
|
|
|
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
glGenBuffers(1, &batch->indirect_buffer);
|
|
|
|
glGenBuffers(1, &batch->commands_buffer);
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch->indirect_buffer);
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch->commands_buffer);
|
|
|
|
glBufferData(GL_DRAW_INDIRECT_BUFFER, max_size * sizeof(rk_command), nullptr, GL_DYNAMIC_DRAW);
|
|
|
|
glBufferData(GL_DRAW_INDIRECT_BUFFER, batch->commands_size, nullptr, GL_STREAM_DRAW);
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nparams) {
|
|
|
|
if (nparams) {
|
|
|
|
batch->packed_params = new rk_ubyte[params_size];
|
|
|
|
|
|
|
|
memset(batch->packed_params, 0, params_size);
|
|
|
|
|
|
|
|
glBindVertexArray(vertices->array);
|
|
|
|
glBindVertexArray(vertices->array);
|
|
|
|
glGenBuffers(1, &batch->params_array);
|
|
|
|
glGenBuffers(1, &batch->params_array);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch->params_array);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch->params_array);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, params_size, nullptr, GL_DYNAMIC_DRAW);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, batch->packed_size, nullptr, GL_STREAM_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
rk_parameter const * param = batch->params;
|
|
|
|
rk_parameter const * param = batch->params;
|
|
|
|
unsigned binding = RK_PARAMS_BINDING_BASE;
|
|
|
|
unsigned binding = RK_PARAMS_BINDING_BASE;
|
|
|
@ -746,6 +750,7 @@ static unsigned rk_batch_build_commands(
|
|
|
|
commands->nvertices = static_cast<GLuint>(mesh.ntriangles) * 3;
|
|
|
|
commands->nvertices = static_cast<GLuint>(mesh.ntriangles) * 3;
|
|
|
|
commands->ninstances = first - base;
|
|
|
|
commands->ninstances = first - base;
|
|
|
|
commands->base_index = mesh.base_index;
|
|
|
|
commands->base_index = mesh.base_index;
|
|
|
|
|
|
|
|
commands->base_vertex = 0;
|
|
|
|
commands->base_instance = base - batch.indices;
|
|
|
|
commands->base_instance = base - batch.indices;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return commands - batch.commands;
|
|
|
|
return commands - batch.commands;
|
|
|
@ -759,9 +764,13 @@ static void rk_batch_pack(
|
|
|
|
for (rk_parameter const * param = batch.params; param < last_param; ++param) {
|
|
|
|
for (rk_parameter const * param = batch.params; param < last_param; ++param) {
|
|
|
|
rk_ubyte const * const src = *srcs++;
|
|
|
|
rk_ubyte const * const src = *srcs++;
|
|
|
|
if (src) {
|
|
|
|
if (src) {
|
|
|
|
rk_ubyte * const dst = batch.packed_params + param->offset;
|
|
|
|
rk_ubyte * const dst = reinterpret_cast<rk_ubyte *>(
|
|
|
|
|
|
|
|
glMapBufferRange(GL_ARRAY_BUFFER, param->offset, ninstances * param->size,
|
|
|
|
|
|
|
|
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
|
|
|
|
|
|
|
|
if (dst) {
|
|
|
|
param->packer(ninstances, batch.indices, dst, src);
|
|
|
|
param->packer(ninstances, batch.indices, dst, src);
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, param->offset, ninstances * param->size, dst);
|
|
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -782,11 +791,13 @@ void rk_draw_batch(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsigned const ncommands = rk_batch_build_commands(batch, ninstances, meshes);
|
|
|
|
unsigned const ncommands = rk_batch_build_commands(batch, ninstances, meshes);
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch.indirect_buffer);
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, batch.commands_buffer);
|
|
|
|
|
|
|
|
glBufferData(GL_DRAW_INDIRECT_BUFFER, batch.commands_size, nullptr, GL_STREAM_DRAW);
|
|
|
|
glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, ncommands * sizeof(rk_command), batch.commands);
|
|
|
|
glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, ncommands * sizeof(rk_command), batch.commands);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (batch.nparams && params) {
|
|
|
|
if (batch.nparams && params) {
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch.params_array);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch.params_array);
|
|
|
|
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, batch.packed_size, nullptr, GL_STREAM_DRAW);
|
|
|
|
rk_batch_pack(batch, ninstances, params);
|
|
|
|
rk_batch_pack(batch, ninstances, params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (rk_DrawElementsInstancedBaseInstance) {
|
|
|
|
if (rk_DrawElementsInstancedBaseInstance) {
|
|
|
@ -862,11 +873,10 @@ void rk_destroy_batch(
|
|
|
|
delete[] batch->indices;
|
|
|
|
delete[] batch->indices;
|
|
|
|
delete[] batch->commands;
|
|
|
|
delete[] batch->commands;
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
if (rk_MultiDrawElementsIndirect) {
|
|
|
|
glDeleteBuffers(1, &batch->indirect_buffer);
|
|
|
|
glDeleteBuffers(1, &batch->commands_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (batch->nparams) {
|
|
|
|
if (batch->nparams) {
|
|
|
|
delete[] batch->params;
|
|
|
|
delete[] batch->params;
|
|
|
|
delete[] batch->packed_params;
|
|
|
|
|
|
|
|
glDeleteBuffers(1, &batch->params_array);
|
|
|
|
glDeleteBuffers(1, &batch->params_array);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete batch;
|
|
|
|
delete batch;
|
|
|
|