diff --git a/res/ft_shaders.farc b/res/ft_shaders.farc index b7bb0e4..c97a9a1 100644 Binary files a/res/ft_shaders.farc and b/res/ft_shaders.farc differ diff --git a/src/DivaGL/GL/array_buffer.cpp b/src/DivaGL/GL/array_buffer.cpp index 49f6d5c..d3030f0 100644 --- a/src/DivaGL/GL/array_buffer.cpp +++ b/src/DivaGL/GL/array_buffer.cpp @@ -82,30 +82,6 @@ namespace GL { return 0; } - void* ArrayBuffer::MapMemory(size_t offset, size_t length) { - if (!buffer) - return 0; - - void* data; - if (GL_VERSION_4_5) - data = glMapNamedBufferRange(buffer, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - else { - gl_state_bind_array_buffer(buffer); - data = glMapBufferRange(GL_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - } - - if (data) - return data; - - if (GL_VERSION_4_5) - glUnmapNamedBuffer(buffer); - else { - glUnmapBuffer(GL_ARRAY_BUFFER); - gl_state_bind_array_buffer(0); - } - return 0; - } - void ArrayBuffer::UnmapMemory() { if (!buffer) return; diff --git a/src/DivaGL/GL/array_buffer.hpp b/src/DivaGL/GL/array_buffer.hpp index 86f547f..8b1401b 100644 --- a/src/DivaGL/GL/array_buffer.hpp +++ b/src/DivaGL/GL/array_buffer.hpp @@ -31,7 +31,6 @@ namespace GL { void Create(size_t size, const void* data, bool dynamic = false); void Destroy(); void* MapMemory(); - void* MapMemory(size_t offset, size_t length); void UnmapMemory(); void WriteMemory(size_t offset, size_t size, const void* data); diff --git a/src/DivaGL/GL/element_array_buffer.cpp b/src/DivaGL/GL/element_array_buffer.cpp index 0a8345c..a0ec967 100644 --- a/src/DivaGL/GL/element_array_buffer.cpp +++ b/src/DivaGL/GL/element_array_buffer.cpp @@ -82,30 +82,6 @@ namespace GL { return 0; } - void* ElementArrayBuffer::MapMemory(size_t offset, size_t length) { - if (!buffer) - return 0; - - void* data; - if (GL_VERSION_4_5) - data = glMapNamedBufferRange(buffer, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - else { - gl_state_bind_element_array_buffer(buffer); - data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - } - - if (data) - return data; - - if (GL_VERSION_4_5) - glUnmapNamedBuffer(buffer); - else { - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - gl_state_bind_element_array_buffer(0); - } - return 0; - } - void ElementArrayBuffer::UnmapMemory() { if (!buffer) return; diff --git a/src/DivaGL/GL/element_array_buffer.hpp b/src/DivaGL/GL/element_array_buffer.hpp index 6dd0ea4..3ea7e60 100644 --- a/src/DivaGL/GL/element_array_buffer.hpp +++ b/src/DivaGL/GL/element_array_buffer.hpp @@ -18,6 +18,10 @@ namespace GL { } + inline ElementArrayBuffer(GLuint buffer) : buffer(buffer) { + + } + inline ~ElementArrayBuffer() { } @@ -27,7 +31,6 @@ namespace GL { void Create(size_t size, const void* data, bool dynamic = false); void Destroy(); void* MapMemory(); - void* MapMemory(size_t offset, size_t length); void UnmapMemory(); void WriteMemory(size_t offset, size_t size, const void* data); diff --git a/src/DivaGL/GL/shader_storage_buffer.cpp b/src/DivaGL/GL/shader_storage_buffer.cpp index b15979d..e8e28f6 100644 --- a/src/DivaGL/GL/shader_storage_buffer.cpp +++ b/src/DivaGL/GL/shader_storage_buffer.cpp @@ -82,30 +82,6 @@ namespace GL { return 0; } - void* ShaderStorageBuffer::MapMemory(size_t offset, size_t length) { - if (!buffer) - return 0; - - void* data; - if (GL_VERSION_4_5) - data = glMapNamedBufferRange(buffer, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - else { - gl_state_bind_shader_storage_buffer(buffer); - data = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - } - - if (data) - return data; - - if (GL_VERSION_4_5) - glUnmapNamedBuffer(buffer); - else { - glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - gl_state_bind_shader_storage_buffer(0); - } - return 0; - } - void ShaderStorageBuffer::UnmapMemory() { if (!buffer) return; diff --git a/src/DivaGL/GL/shader_storage_buffer.hpp b/src/DivaGL/GL/shader_storage_buffer.hpp index efc666d..2f6b4a1 100644 --- a/src/DivaGL/GL/shader_storage_buffer.hpp +++ b/src/DivaGL/GL/shader_storage_buffer.hpp @@ -18,6 +18,10 @@ namespace GL { } + inline ShaderStorageBuffer(GLuint buffer) : buffer(buffer) { + + } + inline ~ShaderStorageBuffer() { } @@ -27,7 +31,6 @@ namespace GL { void Create(size_t size, const void* data, bool dynamic = false); void Destroy(); void* MapMemory(); - void* MapMemory(size_t offset, size_t length); void UnmapMemory(); void WriteMemory(size_t offset, size_t size, const void* data); diff --git a/src/DivaGL/GL/uniform_buffer.cpp b/src/DivaGL/GL/uniform_buffer.cpp index 00c631d..44bdfa3 100644 --- a/src/DivaGL/GL/uniform_buffer.cpp +++ b/src/DivaGL/GL/uniform_buffer.cpp @@ -82,30 +82,6 @@ namespace GL { return 0; } - void* UniformBuffer::MapMemory(size_t offset, size_t length) { - if (!buffer) - return 0; - - void* data; - if (GL_VERSION_4_5) - data = glMapNamedBufferRange(buffer, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - else { - gl_state_bind_uniform_buffer(buffer); - data = glMapBufferRange(GL_UNIFORM_BUFFER, (GLintptr)offset, (GLsizeiptr)length, GL_WRITE_ONLY); - } - - if (data) - return data; - - if (GL_VERSION_4_5) - glUnmapNamedBuffer(buffer); - else { - glUnmapBuffer(GL_UNIFORM_BUFFER); - gl_state_bind_uniform_buffer(0); - } - return 0; - } - void UniformBuffer::UnmapMemory() { if (!buffer) return; diff --git a/src/DivaGL/GL/uniform_buffer.hpp b/src/DivaGL/GL/uniform_buffer.hpp index 24ac5b5..4e3247c 100644 --- a/src/DivaGL/GL/uniform_buffer.hpp +++ b/src/DivaGL/GL/uniform_buffer.hpp @@ -18,6 +18,10 @@ namespace GL { } + inline UniformBuffer(GLuint buffer) : buffer(buffer) { + + } + inline ~UniformBuffer() { } @@ -27,7 +31,6 @@ namespace GL { void Create(size_t size, const void* data, bool dynamic = false); void Destroy(); void* MapMemory(); - void* MapMemory(size_t offset, size_t length); void UnmapMemory(); void WriteMemory(size_t offset, size_t size, const void* data); diff --git a/src/DivaGL/effect.cpp b/src/DivaGL/effect.cpp index 52be7a8..8564a8f 100644 --- a/src/DivaGL/effect.cpp +++ b/src/DivaGL/effect.cpp @@ -1961,7 +1961,7 @@ void water_particle::draw(mat4* mat) { shaders_ft.set(SHADER_FT_W_PTCL); gl_state_bind_vertex_array(rctx->common_vao); - water_particle_scene_ubo.Bind(5); + water_particle_scene_ubo.Bind(0); ssbo.Bind(0); texture* tex = texture_manager_get_texture(splash_tex_id); if (tex) diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index a60d16c..68e26f3 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -1989,11 +1989,6 @@ namespace mdl { uniform_value_reset(); gl_state_get(); - rctx->obj_shader_ubo.Bind(0); - rctx->obj_scene_ubo.Bind(1); - rctx->obj_batch_ubo.Bind(2); - rctx->obj_skinning_ubo.Bind(4); - switch (type) { case OBJ_TYPE_TRANSLUCENT: case OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS: @@ -2149,11 +2144,6 @@ namespace mdl { uniform_value_reset(); gl_state_get(); - rctx->obj_shader_ubo.Bind(0); - rctx->obj_scene_ubo.Bind(1); - rctx->obj_batch_ubo.Bind(2); - rctx->obj_skinning_ubo.Bind(4); - switch (type) { case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp index 1639dbc..07d6656 100644 --- a/src/DivaGL/mdl/draw_object.cpp +++ b/src/DivaGL/mdl/draw_object.cpp @@ -56,6 +56,10 @@ namespace mdl { rctx->obj_shader_ubo.WriteMemory(rctx->obj_shader); rctx->obj_batch_ubo.WriteMemory(rctx->obj_batch); + rctx->obj_shader_ubo.Bind(0); + rctx->obj_scene_ubo.Bind(1); + rctx->obj_batch_ubo.Bind(2); + if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP && index_format == OBJ_INDEX_U16) shaders_ft.draw_range_elements(GL_TRIANGLE_STRIP, start, end, count, GL_UNSIGNED_SHORT, (void*)indices); @@ -206,7 +210,9 @@ namespace mdl { g_joint_transforms[2] = mat.row2; } - rctx->obj_skinning_ubo.WriteMemory(rctx->obj_skinning); + rctx->obj_skinning_ssbo.WriteMemory(rctx->obj_skinning); + + rctx->obj_skinning_ssbo.Bind(0); rctx->obj_batch.set_transforms(mat4_identity, rctx->view_mat, rctx->proj_mat); diff --git a/src/DivaGL/render_context.cpp b/src/DivaGL/render_context.cpp index 0d8b134..2fc969f 100644 --- a/src/DivaGL/render_context.cpp +++ b/src/DivaGL/render_context.cpp @@ -349,7 +349,7 @@ samplers(), render_samplers(), sprite_samplers(), screen_width(), screen_height( obj_shader_ubo.Create(sizeof(obj_shader_shader_data)); obj_scene_ubo.Create(sizeof(obj_scene_shader_data)); obj_batch_ubo.Create(sizeof(obj_batch_shader_data)); - obj_skinning_ubo.Create(sizeof(obj_skinning_shader_data)); + obj_skinning_ssbo.Create(sizeof(obj_skinning_shader_data)); static const vec4 border_color = 0.0f; @@ -449,7 +449,7 @@ render_context::~render_context() { glDeleteSamplers(4, render_samplers); glDeleteSamplers(18, samplers); - obj_skinning_ubo.Destroy(); + obj_skinning_ssbo.Destroy(); obj_batch_ubo.Destroy(); obj_scene_ubo.Destroy(); obj_shader_ubo.Destroy(); diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp index 94334bb..4a5c096 100644 --- a/src/DivaGL/render_context.hpp +++ b/src/DivaGL/render_context.hpp @@ -9,6 +9,7 @@ #include "../KKdLib/mat.hpp" #include "../KKdLib/vec.hpp" #include "GL/array_buffer.hpp" +#include "GL/shader_storage_buffer.hpp" #include "GL/uniform_buffer.hpp" #include "light_param/fog.hpp" #include "light_param/light.hpp" @@ -411,7 +412,7 @@ struct render_context { GL::UniformBuffer obj_shader_ubo; GL::UniformBuffer obj_scene_ubo; GL::UniformBuffer obj_batch_ubo; - GL::UniformBuffer obj_skinning_ubo; + GL::ShaderStorageBuffer obj_skinning_ssbo; texture* empty_texture_2d; texture* empty_texture_cube_map; diff --git a/src/DivaGL/shader.cpp b/src/DivaGL/shader.cpp index e2cec5f..f7ca2b4 100644 --- a/src/DivaGL/shader.cpp +++ b/src/DivaGL/shader.cpp @@ -25,7 +25,7 @@ static GLuint shader_compile(const char* vert, const char* frag, const char* vp, static GLuint shader_compile_binary(const char* vert, const char* frag, const char* vp, const char* fp, program_binary* bin, GLsizei* buffer_size, void** binary); static bool shader_load_binary_shader(program_binary* bin, GLuint* program, const char* vp, const char* fp); -static void shader_update_data(shader_set_data* set); +static bool shader_update_data(shader_set_data* set); int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { set->curr_program = 0; @@ -62,104 +62,79 @@ int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { return 0; } -bool shader::parse_define(const char* data, char** temp, size_t* temp_size) { +static void parse_define_inner(std::string& temp) { + size_t off = 0; + while (true) { + size_t pos_set = temp.find("set = ", off); + size_t pos_binding = temp.find("binding = ", off); + if (pos_set == -1 || pos_binding == -1) + break; + + temp.erase(pos_set, pos_binding - pos_set); + off = pos_set + 10; + } +} + +bool shader::parse_define(const char* data, std::string& temp) { if (!data) return false; const char* def = strstr(data, "//DEF\n"); - if (!def) { - size_t len = utf8_length(data); - if (len + 1 > *temp_size) { - free_def(*temp); - *temp_size = len + 1; - *temp = force_malloc(*temp_size); - } + if (def) { + temp.clear(); - memcpy(*temp, data, len); - (*temp)[len] = 0; - return true; + size_t len_a = def - data; + def += 5; + if (*def == '\n') + def++; + + size_t len_b = utf8_length(def); + + size_t pos = 0; + temp.insert(pos, data, len_a); + pos += len_a; + temp.insert(pos, def, len_b); + pos += len_b; } + else + temp.assign(data); - size_t len_a = def - data; - def += 5; - if (*def == '\n') - def++; - - size_t len_b = utf8_length(def); - size_t len = 0; - len += len_a + len_b; - - if (len + 1 > *temp_size) { - free_def(*temp); - *temp_size = len + 1; - *temp = force_malloc(*temp_size); - } - - size_t pos = 0; - memcpy(*temp + pos, data, len_a); - pos += len_a; - memcpy(*temp + pos, def, len_b); - pos += len_b; - (*temp)[pos] = 0; + parse_define_inner(temp); return true; } bool shader::parse_define(const char* data, int32_t num_uniform, - int32_t* uniform_value, char** temp, size_t* temp_size) { + int32_t* uniform_value, std::string& temp) { if (!data) return false; const char* def = strstr(data, "//DEF\n"); - if (!def) { - size_t len = utf8_length(data); - if (len + 1 > *temp_size) { - free_def(*temp); - *temp_size = len + 1; - *temp = force_malloc(*temp_size); + if (def) { + temp.clear(); + + size_t len_a = def - data; + def += 5; + if (*def == '\n') + def++; + + size_t len_b = utf8_length(def); + + size_t pos = 0; + temp.insert(pos, data, len_a); + pos += len_a; + for (int32_t i = 0; i < num_uniform; i++) { + char t[0x100]; + int32_t len = sprintf_s(t, sizeof(t), "#define _%d %d\n", i, uniform_value[i]); + temp.insert(pos, t, len); + pos += len; } - - memcpy(*temp, data, len); - (*temp)[len] = 0; - return true; + temp.insert(pos, def, len_b); + pos += len_b; } + else + temp.assign(data); - const int32_t s = min_def(0x100, num_uniform); - - size_t t_len[0x100]; - char t[0x100] = {}; - - for (int32_t i = 0; i < s; i++) { - sprintf_s(t, sizeof(t), "#define _%d %d\n", i, uniform_value[i]); - t_len[i] = utf8_length(t); - } - - size_t len_a = def - data; - def += 5; - size_t len_b = utf8_length(def); - size_t len = 0; - for (int32_t i = 0; i < s; i++) - len += t_len[i]; - if (!len) - def++; - len += len_a + len_b; - - if (len + 1 > *temp_size) { - free_def(*temp); - *temp_size = len + 1; - *temp = force_malloc(*temp_size); - } - - size_t pos = 0; - memcpy(*temp + pos, data, len_a); - pos += len_a; - for (int32_t i = 0; i < s; i++) { - sprintf_s(t, sizeof(t), "#define _%d %d\n", i, uniform_value[i]); - memcpy(*temp + pos, t, t_len[i]); - pos += t_len[i]; - } - memcpy(*temp + pos, def, len_b); - pos += len_b; - (*temp)[pos] = 0; + parse_define_inner(temp); return true; } @@ -288,7 +263,9 @@ void shader_set_data::disable_primitive_restart() { } void shader_set_data::draw_arrays(GLenum mode, GLint first, GLsizei count) { - shader_update_data(this); + if (!shader_update_data(this)) + return; + glDrawArraysDLL(mode, first, count); } @@ -317,7 +294,9 @@ void shader_set_data::draw_elements(GLenum mode, break; } - shader_update_data(this); + if (!shader_update_data(this)) + return; + glDrawElementsDLL(mode, count, type, indices); switch (mode) { @@ -352,7 +331,9 @@ void shader_set_data::draw_range_elements(GLenum mode, break; } - shader_update_data(this); + if (!shader_update_data(this)) + return; + glDrawRangeElements(mode, start, end, count, type, indices); switch (mode) { @@ -411,10 +392,8 @@ void shader_set_data::load(farc* f, bool ignore_cache, GLsizei buffer_size = 0x100000; void* binary = force_malloc(buffer_size); - size_t temp_vert_size = 0x10000; - char* temp_vert = force_malloc(temp_vert_size); - size_t temp_frag_size = 0x10000; - char* temp_frag = force_malloc(temp_frag_size); + std::string temp_vert; + std::string temp_frag; std::vector vec_vert; std::vector vec_frag; std::vector program_data_binary; @@ -589,18 +568,18 @@ void shader_set_data::load(farc* f, bool ignore_cache, if (!bin || !bin->binary_format || !bin->length || !shader_load_binary_shader(bin, &programs[k], vert_buf, frag_buf)) { - bool vert_succ = shader::parse_define(vert_data, num_uniform, - vec_vert_data, &temp_vert, &temp_vert_size); - bool frag_succ = shader::parse_define(frag_data, num_uniform, - vec_frag_data, &temp_frag, &temp_frag_size); + bool vert_succ = shader::parse_define(vert_data, + num_uniform, vec_vert_data, temp_vert); + bool frag_succ = shader::parse_define(frag_data, + num_uniform, vec_frag_data, temp_frag); if (ignore_cache) - programs[k] = shader_compile(vert_succ ? temp_vert : 0, - frag_succ ? temp_frag : 0, vert_buf, frag_buf); + programs[k] = shader_compile(vert_succ ? temp_vert.c_str() : 0, + frag_succ ? temp_frag.c_str() : 0, vert_buf, frag_buf); else { program_data_binary.push_back({}); - programs[k] = shader_compile_binary(vert_succ ? temp_vert : 0, - frag_succ ? temp_frag : 0, vert_buf, frag_buf, + programs[k] = shader_compile_binary(vert_succ ? temp_vert.c_str() : 0, + frag_succ ? temp_frag.c_str() : 0, vert_buf, frag_buf, &program_data_binary.back(), &buffer_size, &binary); } shader_cache_changed |= programs[k] ? true : false; @@ -631,16 +610,16 @@ void shader_set_data::load(farc* f, bool ignore_cache, if (!bin || !bin->binary_format || !bin->length || !shader_load_binary_shader(bin, &programs[0], vert_buf, frag_buf)) { - bool vert_succ = shader::parse_define(vert_data, &temp_vert, &temp_vert_size); - bool frag_succ = shader::parse_define(frag_data, &temp_frag, &temp_frag_size); + bool vert_succ = shader::parse_define(vert_data, temp_vert); + bool frag_succ = shader::parse_define(frag_data, temp_frag); if (ignore_cache) - programs[0] = shader_compile(vert_succ ? temp_vert : 0, - frag_succ ? temp_frag : 0, vert_buf, frag_buf); + programs[0] = shader_compile(vert_succ ? temp_vert.c_str() : 0, + frag_succ ? temp_frag.c_str() : 0, vert_buf, frag_buf); else { program_data_binary.push_back({}); - programs[0] = shader_compile_binary(vert_succ ? temp_vert : 0, - frag_succ ? temp_frag : 0, vert_buf, frag_buf, + programs[0] = shader_compile_binary(vert_succ ? temp_vert.c_str() : 0, + frag_succ ? temp_frag.c_str() : 0, vert_buf, frag_buf, &program_data_binary.back(), &buffer_size, &binary); } shader_cache_changed |= programs[0] ? true : false; @@ -710,8 +689,6 @@ void shader_set_data::load(farc* f, bool ignore_cache, } } free_def(binary); - free_def(temp_vert); - free_def(temp_frag); if (shader_cache_changed) shader_cache_farc.write(temp_buf, FARC_FArC, FARC_NONE, true, false); @@ -1010,9 +987,9 @@ static bool shader_load_binary_shader(program_binary* bin, GLuint* program, cons return true; } -static void shader_update_data(shader_set_data* set) { - if (!set) - return; +static bool shader_update_data(shader_set_data* set) { + if (!set || !set->curr_program) + return false; if (set->primitive_restart) { gl_state_enable_primitive_restart(); @@ -1020,4 +997,6 @@ static void shader_update_data(shader_set_data* set) { } else gl_state_disable_primitive_restart(); + + return true; } diff --git a/src/DivaGL/shader.hpp b/src/DivaGL/shader.hpp index 588515a..ac91761 100644 --- a/src/DivaGL/shader.hpp +++ b/src/DivaGL/shader.hpp @@ -61,9 +61,9 @@ struct shader { int32_t bind(shader_set_data* set, uint32_t sub_index); - static bool parse_define(const char* data, char** temp, size_t* temp_size); + static bool parse_define(const char* data, std::string& temp); static bool parse_define(const char* data, int32_t num_uniform, - int32_t* uniform_value, char** temp, size_t* temp_size); + int32_t* uniform_value, std::string& temp); static char* parse_include(char* data, farc* f); static void unbind(); }; diff --git a/src/DivaGL/shader_ft.cpp b/src/DivaGL/shader_ft.cpp index 1b747b5..3d66d03 100644 --- a/src/DivaGL/shader_ft.cpp +++ b/src/DivaGL/shader_ft.cpp @@ -1468,7 +1468,7 @@ static void glass_eye_set(glass_eye_struct* glass_eye) { glass_eye_batch.g_tex_scale = temp; rctx->glass_eye_batch_ubo.WriteMemory(glass_eye_batch); - rctx->glass_eye_batch_ubo.Bind(5); + rctx->glass_eye_batch_ubo.Bind(3); } static void shader_bind_blinn(shader_set_data* set, shader* shad) {