diff --git a/__init__.py b/__init__.py index c0cbf26..5be0188 100644 --- a/__init__.py +++ b/__init__.py @@ -239,14 +239,68 @@ def load_shader(vert_lines, frag_lines): vert_nlines, ctypes.addressof(vert_lines), frag_nlines, ctypes.addressof(frag_lines)) -select_shader = _lib.rk_select_shader -select_shader.argtypes = ( - ctypes.c_void_p,) # shader - resolve_input = _lib.rk_resolve_input resolve_input.restype = ctypes.c_void_p resolve_input.argtypes = ( - ctypes.c_char_p,) # name + ctypes.c_void_p, # shader + ctypes.c_char_p) # name + +resolve_param = _lib.rk_resolve_param +resolve_param.restype = ctypes.c_void_p +resolve_param.argtypes = ( + ctypes.c_void_p, # shader + ctypes.c_char_p) # name + +_create_texture = _lib.rk_create_texture +_create_texture.restype = ctypes.c_void_p +_create_texture.argtypes = ( + ctypes.c_uint, # slot + ctypes.c_uint, # format + ctypes.c_uint, # width + ctypes.c_uint, # height + ctypes.c_uint, # nlevels + ctypes.c_uint, # flags + ctypes.c_void_p) # pixels + +def create_texture(slot, format, width, height, nlevels, flags, pixels): + assert pixels.typecode == TEXTURE_FORMAT_TYPECODE[format] + assert len(pixels) == width * height * max(1, nlevels) * TEXTURE_FORMAT_NELEMS[format] + return _create_texture(slot, format, width, height, nlevels, flags, _voidp(pixels)) + +_create_triangles = _lib.rk_create_triangles +_create_triangles.restype = ctypes.c_void_p +_create_triangles.argtypes = ( + ctypes.c_uint, # nvertices + ctypes.c_void_p) # vertices + +def create_triangles(vertices): + assert len(vertices) % 9 == 0 + return _create_triangles(len(vertices) // 3, _floatp(vertices)) + +_create_vertices = _lib.rk_create_vertices +_create_vertices.restype = ctypes.c_void_p +_create_vertices.argtypes = ( + ctypes.c_char_p, # format + ctypes.c_uint, # nvertices + ctypes.c_void_p, # vertices + ctypes.c_uint, # nindices + ctypes.c_void_p) # indices + +def create_vertices(format, nvertices, vertices, indices): + return _create_vertices(format, nvertices, _ubytep(vertices), len(indices), _ushortp(indices)) + +create_batch = _lib.rk_create_batch +create_batch.restype = ctypes.c_void_p +create_batch.argtypes = ( + ctypes.c_void_p, # vertices + ctypes.c_uint, # max_size + ctypes.c_char_p) # params_format + +begin_frame = _lib.rk_begin_frame + +select_shader = _lib.rk_select_shader +select_shader.argtypes = ( + ctypes.c_void_p,) # shader set_input_float = _lib.rk_set_input_float set_input_float.argtypes = ( @@ -280,11 +334,6 @@ def set_input_mat4(input, value): assert len(value) == 16 _set_input_mat4(input, _mat4(value)) -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 @@ -294,56 +343,10 @@ def set_param_vec3(param, value): assert len(value) == 3 _set_param_vec3(param, _vec3(value)) -_create_texture = _lib.rk_create_texture -_create_texture.restype = ctypes.c_void_p -_create_texture.argtypes = ( - ctypes.c_uint, # slot - ctypes.c_char_p, # input - ctypes.c_uint, # format - ctypes.c_uint, # width - ctypes.c_uint, # height - ctypes.c_uint, # nlevels - ctypes.c_uint, # flags - ctypes.c_void_p) # pixels - -def create_texture(slot, input, format, width, height, nlevels, flags, pixels): - assert pixels.typecode == TEXTURE_FORMAT_TYPECODE[format] - assert len(pixels) == width * height * max(1, nlevels) * TEXTURE_FORMAT_NELEMS[format] - return _create_texture(slot, input, format, width, height, nlevels, flags, _voidp(pixels)) - -_create_triangles = _lib.rk_create_triangles -_create_triangles.restype = ctypes.c_void_p -_create_triangles.argtypes = ( - ctypes.c_uint, # nvertices - ctypes.c_void_p) # vertices - -def create_triangles(vertices): - assert len(vertices) % 9 == 0 - return _create_triangles(len(vertices) // 3, _floatp(vertices)) - -_create_vertices = _lib.rk_create_vertices -_create_vertices.restype = ctypes.c_void_p -_create_vertices.argtypes = ( - ctypes.c_char_p, # format - ctypes.c_uint, # nvertices - ctypes.c_void_p, # vertices - ctypes.c_uint, # nindices - ctypes.c_void_p) # indices - -def create_vertices(format, nvertices, vertices, indices): - return _create_vertices(format, nvertices, _ubytep(vertices), len(indices), _ushortp(indices)) - -create_batch = _lib.rk_create_batch -create_batch.restype = ctypes.c_void_p -create_batch.argtypes = ( - ctypes.c_uint, # max_size - ctypes.c_char_p) # params_format - -begin_frame = _lib.rk_begin_frame - select_texture = _lib.rk_select_texture select_texture.argtypes = ( - ctypes.c_void_p,) # texture + ctypes.c_void_p, # texture + ctypes.c_void_p) # sampler draw_triangles = _lib.rk_draw_triangles draw_triangles.argtypes = ( diff --git a/cpp/opengl/render_opengles.cpp b/cpp/opengl/render_opengles.cpp index 9ad7881..7db4cea 100644 --- a/cpp/opengl/render_opengles.cpp +++ b/cpp/opengl/render_opengles.cpp @@ -122,88 +122,37 @@ rk_shader_t rk_load_shader( return shader; } -void rk_select_shader( - rk_shader_t _shader) { - rk_shader * const shader = reinterpret_cast(_shader); - if (shader) { - rk_current_shader = shader; - glUseProgram(shader->program); - } -} - rk_input_t rk_resolve_input( + rk_shader_t _shader, char const * name) { - if (!rk_current_shader || !name) { + rk_shader const * const shader = reinterpret_cast(_shader); + if (!shader || !name) { return nullptr; } - GLint const uniform = glGetUniformLocation(rk_current_shader->program, name); + GLint const uniform = glGetUniformLocation(shader->program, name); return reinterpret_cast(uniform + 1); } -void rk_set_input_float( - rk_input_t _input, - float value) { - GLint const input = reinterpret_cast(_input) - 1; - if (rk_current_shader && input > -1) { - glUniform1f(input, value); - } -} - -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) { - glUniform3fv(input, 1, glm::value_ptr(value)); - } -} - -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) { - glUniformMatrix3fv(input, 1, GL_FALSE, glm::value_ptr(value)); - } -} - -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) { - glUniformMatrix4fv(input, 1, GL_FALSE, glm::value_ptr(value)); - } -} - rk_param_t rk_resolve_param( + rk_shader_t _shader, char const * name) { - if (!rk_current_shader || !name) { + rk_shader const * const shader = reinterpret_cast(_shader); + if (!shader || !name) { return nullptr; } - GLint const location = glGetAttribLocation(rk_current_shader->program, name); + GLint const location = glGetAttribLocation(shader->program, name); return reinterpret_cast(location + 1); } -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) { - glVertexAttrib3fv(param, glm::value_ptr(value)); - } -} - rk_texture_t rk_create_texture( rk_uint slot, - char const * input, rk_texture_format format, rk_uint width, rk_uint height, rk_uint nlevels, rk_texture_flags flags, void const * pixels) { - if (!input || width == 0 || height == 0 || !pixels || !rk_current_shader) { + if (!width || !height || !pixels) { return nullptr; } GLint internal_format; @@ -279,10 +228,6 @@ rk_texture_t rk_create_texture( } texture->slot = slot; texture->nlevels = nlevels; - texture->sampler = glGetUniformLocation(rk_current_shader->program, input); - if (texture->sampler == -1) { - printf("[RK_ENGINE] glGetUniformLocation(%s) failed\n", input); - } glBindTexture(target, 0); return texture; } @@ -290,7 +235,7 @@ rk_texture_t rk_create_texture( rk_triangles_t rk_create_triangles( rk_uint nvertices, rk_vec3 const * vertices) { - if (nvertices == 0 || !vertices || !rk_current_shader) { + if (!nvertices || !vertices) { return nullptr; } rk_triangles * const triangles = new rk_triangles; @@ -313,7 +258,7 @@ rk_vertices_t rk_create_vertices( void const * _vertices, rk_uint nindices, rk_ushort const * indices) { - if (!format || !nvertices || !_vertices || !nindices || !indices || !rk_current_shader) { + if (!format || !nvertices || !_vertices || !nindices || !indices) { return nullptr; } rk_uint vertex_size = 0; @@ -407,10 +352,13 @@ static void rk_pack_vec3_int10( #undef _convert } +//TODO: multiple batches per vertices rk_batch_t rk_create_batch( + rk_vertices_t _vertices, rk_uint max_size, rk_param_format const * params_format) { - if (!max_size || !params_format || max_size > RK_BATCH_MAX_SIZE || !rk_current_shader || !rk_current_vertices) { + rk_vertices const * const vertices = reinterpret_cast(_vertices); + if (!vertices || !max_size || !params_format || max_size > RK_BATCH_MAX_SIZE) { rk_printf("rk_create_batch(): invalid parameters."); return nullptr; } @@ -448,9 +396,10 @@ rk_batch_t rk_create_batch( batch->packers = new rk_packer[nparams]; batch->params = new rk_ubyte[max_size * packed_size]; glGenBuffers(1, &batch->params_buffer); - rk_uint layout = rk_current_vertices->layout; + rk_uint layout = vertices->layout; rk_packer * packer = batch->packers; rk_uint offset = 0; + glBindVertexArray(vertices->array); for (rk_param_format const * f = params_format; *f; ++f, ++layout, ++packer) { GLboolean const normalize = (*f & RK_PARAM_FORMAT_NORMALIZE) != 0; glEnableVertexAttribArray(layout); @@ -483,6 +432,7 @@ rk_batch_t rk_create_batch( } glVertexBindingDivisor(RK_PARAMS_BINDING, 1); glBindVertexBuffer(RK_PARAMS_BINDING, batch->params_buffer, 0, batch->packed_size); + glBindVertexArray(0); } if (rk_MultiDrawElementsIndirect) { glGenBuffers(1, &batch->commands_buffer); @@ -494,19 +444,73 @@ void rk_begin_frame() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } +void rk_select_shader( + rk_shader_t _shader) { + rk_shader * const shader = reinterpret_cast(_shader); + if (shader) { + rk_current_shader = shader; + glUseProgram(shader->program); + } +} + +void rk_set_input_float( + rk_input_t _input, + float value) { + GLint const input = reinterpret_cast(_input) - 1; + if (rk_current_shader && input > -1) { + glUniform1f(input, value); + } +} + +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) { + glUniform3fv(input, 1, glm::value_ptr(value)); + } +} + +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) { + glUniformMatrix3fv(input, 1, GL_FALSE, glm::value_ptr(value)); + } +} + +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) { + glUniformMatrix4fv(input, 1, GL_FALSE, glm::value_ptr(value)); + } +} + +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) { + glVertexAttrib3fv(param, glm::value_ptr(value)); + } +} + void rk_select_texture( - rk_texture_t _texture) { + rk_texture_t _texture, + rk_input_t _sampler) { rk_texture const * const texture = reinterpret_cast(_texture); - if (texture) { + GLint const sampler = reinterpret_cast(_sampler) - 1; + if (texture && sampler > -1 && rk_current_shader) { glActiveTexture(GL_TEXTURE0 + texture->slot); if (texture->nlevels) { glBindTexture(GL_TEXTURE_2D_ARRAY, texture->texture); } else { glBindTexture(GL_TEXTURE_2D, texture->texture); } - if (texture->sampler > -1) { - glUniform1i(texture->sampler, texture->slot); - } + glUniform1i(sampler, texture->slot); } } @@ -523,7 +527,7 @@ RK_EXPORT void rk_draw_triangles( void rk_select_vertices( rk_vertices_t _vertices) { rk_vertices * const vertices = reinterpret_cast(_vertices); - if (vertices && rk_current_shader) { + if (vertices) { glBindVertexArray(vertices->array); rk_current_vertices = vertices; } diff --git a/cpp/opengl/render_opengles.hpp b/cpp/opengl/render_opengles.hpp index 763b143..98f068d 100644 --- a/cpp/opengl/render_opengles.hpp +++ b/cpp/opengl/render_opengles.hpp @@ -36,7 +36,6 @@ struct rk_shader { struct rk_texture { rk_uint slot; rk_uint nlevels; - GLint sampler; GLuint texture; }; diff --git a/cpp/render.hpp b/cpp/render.hpp index 2e81ffa..3369800 100644 --- a/cpp/render.hpp +++ b/cpp/render.hpp @@ -22,10 +22,10 @@ typedef rk_handle_t rk_window_t; typedef rk_handle_t rk_shader_t; typedef rk_handle_t rk_input_t; +typedef rk_handle_t rk_param_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)) @@ -92,38 +92,16 @@ RK_EXPORT rk_shader_t rk_load_shader( rk_uint const frag_nlines, char const ** const frag_lines); -RK_EXPORT void rk_select_shader( - rk_shader_t _shader); - RK_EXPORT rk_input_t rk_resolve_input( + rk_shader_t shader, char const * name); -RK_EXPORT void rk_set_input_float( - rk_input_t input, - float value); - -RK_EXPORT void rk_set_input_vec3( - rk_input_t input, - rk_vec3 const & value); - -RK_EXPORT void rk_set_input_mat3( - rk_input_t input, - rk_mat3 const & value); - -RK_EXPORT void rk_set_input_mat4( - rk_input_t input, - rk_mat4 const & value); - RK_EXPORT rk_param_t rk_resolve_param( + rk_shader_t shader, char const * name); -RK_EXPORT void rk_set_param_vec3( - rk_param_t param, - rk_vec3 const & value); - RK_EXPORT rk_texture_t rk_create_texture( rk_uint slot, - char const * input, rk_texture_format format, rk_uint width, rk_uint height, @@ -143,13 +121,38 @@ RK_EXPORT rk_vertices_t rk_create_vertices( rk_ushort const * indices); RK_EXPORT rk_batch_t rk_create_batch( + rk_vertices_t vertices, rk_uint max_size, rk_param_format const * params_format); RK_EXPORT void rk_begin_frame(); +RK_EXPORT void rk_select_shader( + rk_shader_t _shader); + +RK_EXPORT void rk_set_input_float( + rk_input_t input, + float value); + +RK_EXPORT void rk_set_input_vec3( + rk_input_t input, + rk_vec3 const & value); + +RK_EXPORT void rk_set_input_mat3( + rk_input_t input, + rk_mat3 const & value); + +RK_EXPORT void rk_set_input_mat4( + rk_input_t input, + rk_mat4 const & value); + +RK_EXPORT void rk_set_param_vec3( + rk_param_t param, + rk_vec3 const & value); + RK_EXPORT void rk_select_texture( - rk_texture_t texture); + rk_texture_t texture, + rk_input_t sampler); RK_EXPORT void rk_draw_triangles( rk_triangles_t triangles);