From de9fec234ae0fc8707acc81d8973bdfce23e4110 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Wed, 30 Apr 2025 12:02:57 +0300 Subject: [PATCH] `gl_rend_state` massive overhaul. Created `render_data_context` --- src/AFTModsShared/types.hpp | 2 +- src/AFTModsShared/uniform.cpp | 4 - src/AFTModsShared/uniform.hpp | 4 - src/DivaGL/DivaGL.vcxproj | 2 + src/DivaGL/GL/array_buffer.cpp | 75 +- src/DivaGL/GL/array_buffer.hpp | 26 +- src/DivaGL/GL/element_array_buffer.cpp | 75 +- src/DivaGL/GL/element_array_buffer.hpp | 26 +- src/DivaGL/GL/shader_storage_buffer.cpp | 85 +- src/DivaGL/GL/shader_storage_buffer.hpp | 26 +- src/DivaGL/GL/uniform_buffer.cpp | 75 +- src/DivaGL/GL/uniform_buffer.hpp | 26 +- src/DivaGL/Glitter/effect_inst.cpp | 6 +- src/DivaGL/Glitter/file_reader.cpp | 22 +- src/DivaGL/Glitter/glitter.cpp | 18 +- src/DivaGL/Glitter/glitter.hpp | 47 +- src/DivaGL/Glitter/particle_manager.cpp | 26 +- src/DivaGL/Glitter/render_scene.cpp | 255 ++- src/DivaGL/Glitter/scene.cpp | 11 +- src/DivaGL/camera.cpp | 127 +- src/DivaGL/camera.hpp | 41 + src/DivaGL/clear_color.cpp | 6 +- src/DivaGL/clear_color.hpp | 2 +- src/DivaGL/data_test/rob_osage_test.cpp | 2 +- src/DivaGL/effect.cpp | 651 ++++---- src/DivaGL/effect.hpp | 10 +- src/DivaGL/gl_rend_state.cpp | 1985 ++++++++++++++++++----- src/DivaGL/gl_rend_state.hpp | 205 +-- src/DivaGL/gl_state.cpp | 110 ++ src/DivaGL/gl_state.hpp | 39 + src/DivaGL/graphics/color_change_dw.cpp | 12 +- src/DivaGL/hook.cpp | 63 +- src/DivaGL/light_param.cpp | 15 +- src/DivaGL/light_param.hpp | 3 +- src/DivaGL/mdl/disp_manager.cpp | 345 ++-- src/DivaGL/mdl/disp_manager.hpp | 38 +- src/DivaGL/mdl/draw_object.cpp | 926 ++++++----- src/DivaGL/mdl/draw_object.hpp | 37 +- src/DivaGL/object.cpp | 22 +- src/DivaGL/render.cpp | 871 +++++----- src/DivaGL/render.hpp | 50 +- src/DivaGL/render_context.cpp | 820 +++++----- src/DivaGL/render_context.hpp | 137 +- src/DivaGL/render_manager.cpp | 1864 +++++++++++---------- src/DivaGL/render_manager.hpp | 42 +- src/DivaGL/render_texture.cpp | 30 +- src/DivaGL/render_texture.hpp | 8 +- src/DivaGL/renderer/dof.cpp | 241 +-- src/DivaGL/renderer/dof.hpp | 22 +- src/DivaGL/renderer/fbo.cpp | 5 +- src/DivaGL/renderer/fbo.hpp | 4 - src/DivaGL/renderer/transparency.cpp | 55 +- src/DivaGL/renderer/transparency.hpp | 6 +- src/DivaGL/rob/rob.cpp | 10 +- src/DivaGL/screen_shot.cpp | 48 +- src/DivaGL/shader.cpp | 138 +- src/DivaGL/shader.hpp | 20 +- src/DivaGL/shader_ft.cpp | 230 +-- src/DivaGL/shadow.cpp | 44 +- src/DivaGL/shadow.hpp | 3 + src/DivaGL/shared.cpp | 8 +- src/DivaGL/shared.hpp | 2 +- src/DivaGL/sprite.cpp | 178 +- src/DivaGL/sprite.hpp | 3 +- src/DivaGL/texture.cpp | 8 +- src/DivaGL/wrap.cpp | 16 +- src/DivaGL/wrap.hpp | 15 + src/KKdLib | 2 +- 68 files changed, 6077 insertions(+), 4253 deletions(-) create mode 100644 src/DivaGL/gl_state.cpp create mode 100644 src/DivaGL/gl_state.hpp diff --git a/src/AFTModsShared/types.hpp b/src/AFTModsShared/types.hpp index e273ea1..57ed9b0 100644 --- a/src/AFTModsShared/types.hpp +++ b/src/AFTModsShared/types.hpp @@ -294,7 +294,7 @@ namespace prj { this->begin = str; this->end = str + utf16_length(str); } - + inline wstring_range(const wchar_t* str, size_t length) { this->begin = str; this->end = str + length; diff --git a/src/AFTModsShared/uniform.cpp b/src/AFTModsShared/uniform.cpp index 33fb947..318f537 100644 --- a/src/AFTModsShared/uniform.cpp +++ b/src/AFTModsShared/uniform.cpp @@ -4,7 +4,3 @@ */ #include "uniform.hpp" - -uniform_value* uniform = (uniform_value*)0x000000014CC57AF0; - -void(FASTCALL* uniform_value_reset)() = (void(FASTCALL*)())0x0000000140443400; diff --git a/src/AFTModsShared/uniform.hpp b/src/AFTModsShared/uniform.hpp index c446360..a6db9d4 100644 --- a/src/AFTModsShared/uniform.hpp +++ b/src/AFTModsShared/uniform.hpp @@ -88,7 +88,3 @@ enum uniform_name { struct uniform_value { int32_t arr[U_MAX]; }; - -extern uniform_value* uniform; - -extern void(FASTCALL* uniform_value_reset)(); diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj index a715329..2016d24 100644 --- a/src/DivaGL/DivaGL.vcxproj +++ b/src/DivaGL/DivaGL.vcxproj @@ -148,6 +148,7 @@ + @@ -196,6 +197,7 @@ + diff --git a/src/DivaGL/GL/array_buffer.cpp b/src/DivaGL/GL/array_buffer.cpp index aa612d4..5310ce4 100644 --- a/src/DivaGL/GL/array_buffer.cpp +++ b/src/DivaGL/GL/array_buffer.cpp @@ -5,13 +5,10 @@ #include "array_buffer.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" namespace GL { - void ArrayBuffer::Bind(bool force) { - gl_rend_state.bind_array_buffer(buffer, force); - } - - void ArrayBuffer::Create(size_t size) { + void ArrayBuffer::Create(gl_state_struct& gl_st, size_t size) { if (buffer) return; @@ -21,7 +18,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_array_buffer(buffer, true); + gl_st.bind_array_buffer(buffer); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ARRAY_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); @@ -30,7 +27,7 @@ namespace GL { } } - void ArrayBuffer::Create(size_t size, const void* data, bool dynamic) { + void ArrayBuffer::Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic) { if (buffer) return; @@ -41,7 +38,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_array_buffer(buffer, true); + gl_st.bind_array_buffer(buffer); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ARRAY_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); @@ -58,7 +55,7 @@ namespace GL { } } - void* ArrayBuffer::MapMemory() { + void* ArrayBuffer::MapMemory(gl_state_struct& gl_st) { if (!buffer) return 0; @@ -66,7 +63,7 @@ namespace GL { if (DIVA_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_rend_state.bind_array_buffer(buffer); + gl_st.bind_array_buffer(buffer); data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); } @@ -77,12 +74,36 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_ARRAY_BUFFER); - gl_rend_state.bind_array_buffer(0); + gl_st.bind_array_buffer(0); } return 0; } - void ArrayBuffer::UnmapMemory() { + void* ArrayBuffer::MapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return 0; + + void* data; + if (DIVA_GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + p_gl_rend_st.bind_array_buffer(buffer); + data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + p_gl_rend_st.bind_array_buffer(0); + } + return 0; + } + + void ArrayBuffer::UnmapMemory(gl_state_struct& gl_st) { if (!buffer) return; @@ -90,18 +111,42 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_ARRAY_BUFFER); - gl_rend_state.bind_array_buffer(0); + gl_st.bind_array_buffer(0); } } - void ArrayBuffer::WriteMemory(size_t offset, size_t size, const void* data) { + void ArrayBuffer::UnmapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + p_gl_rend_st.bind_array_buffer(0); + } + } + + void ArrayBuffer::WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data) { if (!buffer || !size) return; if (DIVA_GL_VERSION_4_5) glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); else { - gl_rend_state.bind_array_buffer(buffer); + gl_st.bind_array_buffer(buffer); + glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + void ArrayBuffer::WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data) { + if (!buffer || !size) + return; + + if (DIVA_GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + p_gl_rend_st.bind_array_buffer(buffer); glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); } } diff --git a/src/DivaGL/GL/array_buffer.hpp b/src/DivaGL/GL/array_buffer.hpp index 8b1401b..1ef4f48 100644 --- a/src/DivaGL/GL/array_buffer.hpp +++ b/src/DivaGL/GL/array_buffer.hpp @@ -8,6 +8,9 @@ #include "../../KKdLib/default.hpp" #include "../wrap.hpp" +struct gl_state_struct; +struct p_gl_rend_state; + namespace GL { struct ArrayBuffer { private: @@ -26,13 +29,15 @@ namespace GL { } - void Bind(bool force = false); - void Create(size_t size); - void Create(size_t size, const void* data, bool dynamic = false); + void Create(gl_state_struct& gl_st, size_t size); + void Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic = false); void Destroy(); - void* MapMemory(); - void UnmapMemory(); - void WriteMemory(size_t offset, size_t size, const void* data); + void* MapMemory(gl_state_struct& gl_st); + void* MapMemory(p_gl_rend_state& p_gl_rend_st); + void UnmapMemory(gl_state_struct& gl_st); + void UnmapMemory(p_gl_rend_state& p_gl_rend_st); + void WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data); + void WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data); inline bool IsNull() { return !buffer; @@ -43,8 +48,13 @@ namespace GL { } template - inline void WriteMemory(T& data) { - WriteMemory(0, sizeof(T), &data); + inline void WriteMemory(gl_state_struct& gl_st, T& data) { + WriteMemory(gl_st, 0, sizeof(T), &data); + } + + template + inline void WriteMemory(p_gl_rend_state& p_gl_rend_st, T& data) { + WriteMemory(p_gl_rend_st, 0, sizeof(T), &data); } inline operator GLuint() const { diff --git a/src/DivaGL/GL/element_array_buffer.cpp b/src/DivaGL/GL/element_array_buffer.cpp index 2660a24..62074e2 100644 --- a/src/DivaGL/GL/element_array_buffer.cpp +++ b/src/DivaGL/GL/element_array_buffer.cpp @@ -5,13 +5,10 @@ #include "element_array_buffer.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" namespace GL { - void ElementArrayBuffer::Bind(bool force) { - gl_rend_state.bind_element_array_buffer(buffer, force); - } - - void ElementArrayBuffer::Create(size_t size) { + void ElementArrayBuffer::Create(gl_state_struct& gl_st, size_t size) { if (buffer) return; @@ -21,7 +18,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_element_array_buffer(buffer, true); + gl_st.bind_element_array_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); @@ -30,7 +27,7 @@ namespace GL { } } - void ElementArrayBuffer::Create(size_t size, const void* data, bool dynamic) { + void ElementArrayBuffer::Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic) { if (buffer) return; @@ -41,7 +38,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_element_array_buffer(buffer, true); + gl_st.bind_element_array_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); @@ -58,7 +55,7 @@ namespace GL { } } - void* ElementArrayBuffer::MapMemory() { + void* ElementArrayBuffer::MapMemory(gl_state_struct& gl_st) { if (!buffer) return 0; @@ -66,7 +63,7 @@ namespace GL { if (DIVA_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_rend_state.bind_element_array_buffer(buffer); + gl_st.bind_element_array_buffer(buffer); data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); } @@ -77,12 +74,36 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - gl_rend_state.bind_element_array_buffer(0); + gl_st.bind_element_array_buffer(0); } return 0; } - void ElementArrayBuffer::UnmapMemory() { + void* ElementArrayBuffer::MapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return 0; + + void* data; + if (DIVA_GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + p_gl_rend_st.bind_element_array_buffer(buffer); + data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + p_gl_rend_st.bind_element_array_buffer(0); + } + return 0; + } + + void ElementArrayBuffer::UnmapMemory(gl_state_struct& gl_st) { if (!buffer) return; @@ -90,18 +111,42 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - gl_rend_state.bind_element_array_buffer(0); + gl_st.bind_element_array_buffer(0); } } - void ElementArrayBuffer::WriteMemory(size_t offset, size_t size, const void* data) { + void ElementArrayBuffer::UnmapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + p_gl_rend_st.bind_element_array_buffer(0); + } + } + + void ElementArrayBuffer::WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data) { if (!buffer || !size) return; if (DIVA_GL_VERSION_4_5) glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); else { - gl_rend_state.bind_element_array_buffer(buffer); + gl_st.bind_element_array_buffer(buffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + void ElementArrayBuffer::WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data) { + if (!buffer || !size) + return; + + if (DIVA_GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + p_gl_rend_st.bind_element_array_buffer(buffer); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); } } diff --git a/src/DivaGL/GL/element_array_buffer.hpp b/src/DivaGL/GL/element_array_buffer.hpp index 3ea7e60..2b422c0 100644 --- a/src/DivaGL/GL/element_array_buffer.hpp +++ b/src/DivaGL/GL/element_array_buffer.hpp @@ -8,6 +8,9 @@ #include "../../KKdLib/default.hpp" #include "../wrap.hpp" +struct gl_state_struct; +struct p_gl_rend_state; + namespace GL { struct ElementArrayBuffer { private: @@ -26,13 +29,15 @@ namespace GL { } - void Bind(bool force = false); - void Create(size_t size); - void Create(size_t size, const void* data, bool dynamic = false); + void Create(gl_state_struct& gl_st, size_t size); + void Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic = false); void Destroy(); - void* MapMemory(); - void UnmapMemory(); - void WriteMemory(size_t offset, size_t size, const void* data); + void* MapMemory(gl_state_struct& gl_st); + void* MapMemory(p_gl_rend_state& p_gl_rend_st); + void UnmapMemory(gl_state_struct& gl_st); + void UnmapMemory(p_gl_rend_state& p_gl_rend_st); + void WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data); + void WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data); inline bool IsNull() { return !buffer; @@ -43,8 +48,13 @@ namespace GL { } template - inline void WriteMemory(T& data) { - WriteMemory(0, sizeof(T), &data); + inline void WriteMemory(gl_state_struct& gl_st, T& data) { + WriteMemory(gl_st, 0, sizeof(T), &data); + } + + template + inline void WriteMemory(p_gl_rend_state& p_gl_rend_st, T& data) { + WriteMemory(p_gl_rend_st, 0, sizeof(T), &data); } inline operator GLuint() const { diff --git a/src/DivaGL/GL/shader_storage_buffer.cpp b/src/DivaGL/GL/shader_storage_buffer.cpp index c909f27..0ab0ba3 100644 --- a/src/DivaGL/GL/shader_storage_buffer.cpp +++ b/src/DivaGL/GL/shader_storage_buffer.cpp @@ -5,14 +5,11 @@ #include "shader_storage_buffer.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" namespace GL { - void ShaderStorageBuffer::Bind(int32_t index, bool force) { - gl_rend_state.bind_shader_storage_buffer_base(index, buffer, force); - } - - void ShaderStorageBuffer::Create(size_t size) { - if (!DIVA_GL_VERSION_4_3 || buffer) + void ShaderStorageBuffer::Create(gl_state_struct& gl_st, size_t size) { + if (buffer) return; if (DIVA_GL_VERSION_4_5) { @@ -21,7 +18,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_shader_storage_buffer(buffer, true); + gl_st.bind_shader_storage_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); @@ -30,8 +27,8 @@ namespace GL { } } - void ShaderStorageBuffer::Create(size_t size, const void* data, bool dynamic) { - if (!DIVA_GL_VERSION_4_3 || buffer) + void ShaderStorageBuffer::Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic) { + if (buffer) return; if (DIVA_GL_VERSION_4_5) { @@ -41,7 +38,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_shader_storage_buffer(buffer, true); + gl_st.bind_shader_storage_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); @@ -58,15 +55,15 @@ namespace GL { } } - void* ShaderStorageBuffer::MapMemory() { - if (!DIVA_GL_VERSION_4_3 || !buffer) + void* ShaderStorageBuffer::MapMemory(gl_state_struct& gl_st) { + if (!buffer) return 0; void* data; if (DIVA_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_rend_state.bind_shader_storage_buffer(buffer); + gl_st.bind_shader_storage_buffer(buffer); data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); } @@ -77,31 +74,79 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - gl_rend_state.bind_shader_storage_buffer(0); + gl_st.bind_shader_storage_buffer(0); } return 0; } - void ShaderStorageBuffer::UnmapMemory() { - if (!DIVA_GL_VERSION_4_3 || !buffer) + void* ShaderStorageBuffer::MapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return 0; + + void* data; + if (DIVA_GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + p_gl_rend_st.bind_shader_storage_buffer(buffer); + data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + p_gl_rend_st.bind_shader_storage_buffer(0); + } + return 0; + } + + void ShaderStorageBuffer::UnmapMemory(gl_state_struct& gl_st) { + if (!buffer) return; if (DIVA_GL_VERSION_4_5) glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - gl_rend_state.bind_shader_storage_buffer(0); + gl_st.bind_shader_storage_buffer(0); } } - void ShaderStorageBuffer::WriteMemory(size_t offset, size_t size, const void* data) { - if (!DIVA_GL_VERSION_4_3 || !buffer || !size) + void ShaderStorageBuffer::UnmapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + p_gl_rend_st.bind_shader_storage_buffer(0); + } + } + + void ShaderStorageBuffer::WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data) { + if (!buffer || !size) return; if (DIVA_GL_VERSION_4_5) glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); else { - gl_rend_state.bind_shader_storage_buffer(buffer); + gl_st.bind_shader_storage_buffer(buffer); + glBufferSubData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + void ShaderStorageBuffer::WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data) { + if (!buffer || !size) + return; + + if (DIVA_GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + p_gl_rend_st.bind_shader_storage_buffer(buffer); glBufferSubData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); } } diff --git a/src/DivaGL/GL/shader_storage_buffer.hpp b/src/DivaGL/GL/shader_storage_buffer.hpp index 2f6b4a1..a02e23b 100644 --- a/src/DivaGL/GL/shader_storage_buffer.hpp +++ b/src/DivaGL/GL/shader_storage_buffer.hpp @@ -8,6 +8,9 @@ #include "../../KKdLib/default.hpp" #include "../wrap.hpp" +struct gl_state_struct; +struct p_gl_rend_state; + namespace GL { struct ShaderStorageBuffer { private: @@ -26,13 +29,15 @@ namespace GL { } - void Bind(int32_t index, bool force = false); - void Create(size_t size); - void Create(size_t size, const void* data, bool dynamic = false); + void Create(gl_state_struct& gl_st, size_t size); + void Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic = false); void Destroy(); - void* MapMemory(); - void UnmapMemory(); - void WriteMemory(size_t offset, size_t size, const void* data); + void* MapMemory(gl_state_struct& gl_st); + void* MapMemory(p_gl_rend_state& p_gl_rend_st); + void UnmapMemory(gl_state_struct& gl_st); + void UnmapMemory(p_gl_rend_state& p_gl_rend_st); + void WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data); + void WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data); inline bool IsNull() { return !buffer; @@ -43,8 +48,13 @@ namespace GL { } template - inline void WriteMemory(T& data) { - WriteMemory(0, sizeof(T), &data); + inline void WriteMemory(gl_state_struct& gl_st, T& data) { + WriteMemory(gl_st, 0, sizeof(T), &data); + } + + template + inline void WriteMemory(p_gl_rend_state& p_gl_rend_st, T& data) { + WriteMemory(p_gl_rend_st, 0, sizeof(T), &data); } inline operator GLuint() const { diff --git a/src/DivaGL/GL/uniform_buffer.cpp b/src/DivaGL/GL/uniform_buffer.cpp index 7da0f5e..2837fda 100644 --- a/src/DivaGL/GL/uniform_buffer.cpp +++ b/src/DivaGL/GL/uniform_buffer.cpp @@ -5,13 +5,10 @@ #include "uniform_buffer.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" namespace GL { - void UniformBuffer::Bind(int32_t index, bool force) { - gl_rend_state.bind_uniform_buffer_base(index, buffer, force); - } - - void UniformBuffer::Create(size_t size) { + void UniformBuffer::Create(gl_state_struct& gl_st, size_t size) { if (buffer) return; @@ -21,7 +18,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_uniform_buffer(buffer, true); + gl_st.bind_uniform_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_UNIFORM_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); @@ -30,7 +27,7 @@ namespace GL { } } - void UniformBuffer::Create(size_t size, const void* data, bool dynamic) { + void UniformBuffer::Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic) { if (buffer) return; @@ -41,7 +38,7 @@ namespace GL { } else { glGenBuffers(1, &buffer); - gl_rend_state.bind_uniform_buffer(buffer, true); + gl_st.bind_uniform_buffer(buffer, true); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_UNIFORM_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); @@ -58,7 +55,7 @@ namespace GL { } } - void* UniformBuffer::MapMemory() { + void* UniformBuffer::MapMemory(gl_state_struct& gl_st) { if (!buffer) return 0; @@ -66,7 +63,7 @@ namespace GL { if (DIVA_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_rend_state.bind_uniform_buffer(buffer); + gl_st.bind_uniform_buffer(buffer); data = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); } @@ -77,12 +74,36 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_UNIFORM_BUFFER); - gl_rend_state.bind_uniform_buffer(0); + gl_st.bind_uniform_buffer(0); } return 0; } - void UniformBuffer::UnmapMemory() { + void* UniformBuffer::MapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return 0; + + void* data; + if (DIVA_GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + p_gl_rend_st.bind_uniform_buffer(buffer); + data = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_UNIFORM_BUFFER); + p_gl_rend_st.bind_uniform_buffer(0); + } + return 0; + } + + void UniformBuffer::UnmapMemory(gl_state_struct& gl_st) { if (!buffer) return; @@ -90,18 +111,42 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_UNIFORM_BUFFER); - gl_rend_state.bind_uniform_buffer(0); + gl_st.bind_uniform_buffer(0); } } - void UniformBuffer::WriteMemory(size_t offset, size_t size, const void* data) { + void UniformBuffer::UnmapMemory(p_gl_rend_state& p_gl_rend_st) { + if (!buffer) + return; + + if (DIVA_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_UNIFORM_BUFFER); + p_gl_rend_st.bind_uniform_buffer(0); + } + } + + void UniformBuffer::WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data) { if (!buffer || !size) return; if (DIVA_GL_VERSION_4_5) glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); else { - gl_rend_state.bind_uniform_buffer(buffer); + gl_st.bind_uniform_buffer(buffer); + glBufferSubData(GL_UNIFORM_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + void UniformBuffer::WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data) { + if (!buffer || !size) + return; + + if (DIVA_GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + p_gl_rend_st.bind_uniform_buffer(buffer); glBufferSubData(GL_UNIFORM_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); } } diff --git a/src/DivaGL/GL/uniform_buffer.hpp b/src/DivaGL/GL/uniform_buffer.hpp index 4e3247c..adf10c9 100644 --- a/src/DivaGL/GL/uniform_buffer.hpp +++ b/src/DivaGL/GL/uniform_buffer.hpp @@ -8,6 +8,9 @@ #include "../../KKdLib/default.hpp" #include "../wrap.hpp" +struct gl_state_struct; +struct p_gl_rend_state; + namespace GL { struct UniformBuffer { private: @@ -26,13 +29,15 @@ namespace GL { } - void Bind(int32_t index, bool force = false); - void Create(size_t size); - void Create(size_t size, const void* data, bool dynamic = false); + void Create(gl_state_struct& gl_st, size_t size); + void Create(gl_state_struct& gl_st, size_t size, const void* data, bool dynamic = false); void Destroy(); - void* MapMemory(); - void UnmapMemory(); - void WriteMemory(size_t offset, size_t size, const void* data); + void* MapMemory(gl_state_struct& gl_st); + void* MapMemory(p_gl_rend_state& p_gl_rend_st); + void UnmapMemory(gl_state_struct& gl_st); + void UnmapMemory(p_gl_rend_state& p_gl_rend_st); + void WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data); + void WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data); inline bool IsNull() { return !buffer; @@ -43,8 +48,13 @@ namespace GL { } template - inline void WriteMemory(T& data) { - WriteMemory(0, sizeof(T), &data); + inline void WriteMemory(gl_state_struct& gl_st, T& data) { + WriteMemory(gl_st, 0, sizeof(T), &data); + } + + template + inline void WriteMemory(p_gl_rend_state& p_gl_rend_st, T& data) { + WriteMemory(p_gl_rend_st, 0, sizeof(T), &data); } inline operator GLuint() const { diff --git a/src/DivaGL/Glitter/effect_inst.cpp b/src/DivaGL/Glitter/effect_inst.cpp index a41f055..99253ee 100644 --- a/src/DivaGL/Glitter/effect_inst.cpp +++ b/src/DivaGL/Glitter/effect_inst.cpp @@ -277,8 +277,8 @@ namespace Glitter { i->CtrlInit(this, delta_frame); } - void EffectInstX::Disp(DispType disp_type) { - render_scene.Disp(disp_type); + void EffectInstX::Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { + render_scene.Disp(rend_data_ctx, disp_type, cam); } void EffectInstX::DispMesh() { @@ -501,7 +501,7 @@ namespace Glitter { void EffectInstX::GetExtAnim() { if (!ext_anim) return; - + if (!(flags & EFFECT_INST_EXT_ANIM) && !(flags & EFFECT_INST_EXT_ANIM_MAT) || (flags & EFFECT_INST_EXT_ANIM_END) || (flags & EFFECT_INST_EXT_ANIM_SET_ONCE) && (flags & EFFECT_INST_EXT_ANIM_TRANS)) diff --git a/src/DivaGL/Glitter/file_reader.cpp b/src/DivaGL/Glitter/file_reader.cpp index b695e44..6ea068c 100644 --- a/src/DivaGL/Glitter/file_reader.cpp +++ b/src/DivaGL/Glitter/file_reader.cpp @@ -8,7 +8,7 @@ #include "../../KKdLib/farc.hpp" #include "../rob/rob.hpp" #if SHARED_GLITTER_BUFFER -#include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #endif namespace Glitter { @@ -110,7 +110,7 @@ namespace Glitter { static const GLsizei buffer_size = sizeof(Buffer); - effect_group->vbo.Create(buffer_size * max_count); + effect_group->vbo.Create(gl_state, buffer_size * max_count); if (max_count_quad) { size_t count = max_count_quad / 4 * 5; @@ -123,7 +123,7 @@ namespace Glitter { ebo_data[i + 4] = 0xFFFFFFFF; } - effect_group->ebo.Create(sizeof(uint32_t) * count, ebo_data); + effect_group->ebo.Create(gl_state, sizeof(uint32_t) * count, ebo_data); free_def(ebo_data); } else @@ -151,10 +151,10 @@ namespace Glitter { k->buffer = buffer; glGenVertexArrays(1, &k->vao); - gl_rend_state.bind_vertex_array(k->vao, true); - gl_rend_state.bind_array_buffer(vbo, true); + gl_state.bind_vertex_array(k->vao, true); + gl_state.bind_array_buffer(vbo, true); if (k->data.type == PARTICLE_QUAD) - gl_rend_state.bind_element_array_buffer(ebo, true); + gl_state.bind_element_array_buffer(ebo, true); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, @@ -174,9 +174,11 @@ namespace Glitter { } } - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.bind_element_array_buffer(0); + if (offset) { + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_element_array_buffer(0); + } } else { free_def(effect_group->buffer); @@ -888,7 +890,7 @@ namespace Glitter { emit->data.rotation_add_random = *(vec3*)(d + 48); d += 60; - + switch (emit->data.type) { case EMITTER_BOX: emit->data.box.size = *(vec3*)d; diff --git a/src/DivaGL/Glitter/glitter.cpp b/src/DivaGL/Glitter/glitter.cpp index ee46528..7b55497 100644 --- a/src/DivaGL/Glitter/glitter.cpp +++ b/src/DivaGL/Glitter/glitter.cpp @@ -4,7 +4,7 @@ */ #include "glitter.hpp" -#include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../wrap.hpp" #include @@ -21,12 +21,12 @@ namespace Glitter { buffer = (Buffer*)_operator_new(sizeof(Buffer) * max_count); glGenVertexArrays(1, &vao); - gl_rend_state.bind_vertex_array(vao, true); + gl_state.bind_vertex_array(vao, true); static const GLsizei buffer_size = sizeof(Buffer); - vbo.Create(buffer_size * max_count); - vbo.Bind(true); + vbo.Create(gl_state, buffer_size * max_count); + gl_state.bind_array_buffer(vbo, true); if (is_quad) { size_t count = max_count / 4 * 5; @@ -39,8 +39,8 @@ namespace Glitter { ebo_data[i + 4] = 0xFFFFFFFF; } - ebo.Create(sizeof(uint32_t) * count, ebo_data); - ebo.Bind(true); + ebo.Create(gl_state, sizeof(uint32_t) * count, ebo_data); + gl_state.bind_array_buffer(ebo, true); _operator_delete(ebo_data); } @@ -54,10 +54,10 @@ namespace Glitter { glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(Buffer, color)); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); if (is_quad) - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_element_array_buffer(0); } void DeleteBuffer(Buffer*& buffer, GLuint& vao, GL::ArrayBuffer& vbo, GL::ElementArrayBuffer& ebo) { diff --git a/src/DivaGL/Glitter/glitter.hpp b/src/DivaGL/Glitter/glitter.hpp index 70e989e..855159f 100644 --- a/src/DivaGL/Glitter/glitter.hpp +++ b/src/DivaGL/Glitter/glitter.hpp @@ -21,6 +21,9 @@ #define SHARED_GLITTER_BUFFER (1) +struct cam_data; +struct render_data_context; + namespace Glitter { enum CurveFlag { CURVE_RANDOM_RANGE = 0x01, @@ -32,7 +35,7 @@ namespace Glitter { CURVE_BAKED = 0x40, CURVE_BAKED_FULL = 0x80, }; - + enum CurveType { CURVE_TRANSLATION_X = 0, CURVE_TRANSLATION_Y = 1, @@ -259,7 +262,7 @@ namespace Glitter { PARTICLE_LOCAL = 0x10000, PARTICLE_EMISSION = 0x20000, }; - + enum ParticleInstFlag { PARTICLE_INST_NONE = 0x00, PARTICLE_INST_ENDED = 0x01, @@ -273,7 +276,7 @@ namespace Glitter { PARTICLE_MANAGER_READ_FILES = 0x08, PARTICLE_MANAGER_LOCAL = 0x20, }; - + enum ParticleSubFlag { PARTICLE_SUB_NONE = 0x00000000, PARTICLE_SUB_UV_2ND_ADD = 0x00400000, @@ -298,7 +301,7 @@ namespace Glitter { PIVOT_BOTTOM_CENTER = 7, PIVOT_BOTTOM_RIGHT = 8, }; - + enum SceneFlag { SCENE_NONE = 0x00, SCENE_FLAG_1 = 0x01, @@ -455,7 +458,7 @@ namespace Glitter { prj::string name; Animation animation; }; - + class ItemBaseX { public: AnimationX animation; @@ -494,7 +497,7 @@ namespace Glitter { NodeX& operator=(const NodeX& node); }; - + class EffectX : public NodeX { public: struct ExtAnim { @@ -537,7 +540,7 @@ namespace Glitter { EffectX& operator=(const EffectX& eff); }; - + struct EffectGroup { void* __vftable; prj::vector effects; @@ -610,8 +613,8 @@ namespace Glitter { void CalcDisp(); void CalcDisp(RenderGroup* rend_group); - void Disp(Glitter::DispType disp_type); - void Disp(RenderGroup* rend_group); + void Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); + void Disp(render_data_context& rend_data_ctx, RenderGroup* rend_group, const cam_data& cam); static void CalcDispLine(RenderGroup* rend_group); static void CalcDispLocus(RenderGroup* rend_group); @@ -652,8 +655,8 @@ namespace Glitter { bool CanDisp(DispType disp_type, bool a3); void CheckUseCamera(); void Ctrl(float_t delta_frame, bool copy_mats); - void Disp(DispType disp_type); - void Disp(RenderGroupX* rend_group); + void Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); + void Disp(render_data_context& rend_data_ctx, RenderGroupX* rend_group, const cam_data& cam); void DispMesh(); void DispMesh(RenderGroupX* rend_group); size_t GetCtrlCount(ParticleType type); @@ -664,7 +667,7 @@ namespace Glitter { static void CalcDispQuadSetPivot(Pivot pivot, float_t w, float_t h, float_t& v00, float_t& v01, float_t& v10, float_t& v11); }; - + struct EffectInstX { bool init; EffectX* effect; @@ -729,7 +732,7 @@ namespace Glitter { void CtrlFlags(float_t delta_frame); void CtrlInit(float_t delta_frame); void CtrlMat(); - void Disp(DispType disp_type); + void Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); void DispMesh(); void Emit(float_t delta_frame, float_t emission); void EmitInit(float_t delta_frame, float_t emission); @@ -910,7 +913,7 @@ namespace Glitter { bool UnpackParticle(void* data, ParticleX* ptcl, uint32_t ptcl_version, EffectX* eff, EffectGroupX* eff_group); }; - + struct LocusHistory { struct Data { vec3 translation; @@ -943,9 +946,9 @@ namespace Glitter { void Append(RenderElementX* rend_elem, ParticleInstX* ptcl_inst); }; - + typedef prj::vector> DrawListData; - + class Particle : ItemBase { public: struct Data { @@ -1266,7 +1269,7 @@ namespace Glitter { static mat4 RotateToPrevPosition(RenderGroupX* rend_group, RenderElementX* rend_elem, vec3* vec); }; - + struct RenderElement { bool alive; uint8_t uv_counter; @@ -1353,7 +1356,7 @@ namespace Glitter { operator uint32_t() const { return (counter << 8) || index; } }; - + struct Scene { void* __vftable; prj::vector effects; @@ -1365,7 +1368,7 @@ namespace Glitter { RenderScene render_scene; void CalcDisp(); - void Disp(DispType disp_type); + void Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); }; struct SceneEffectX { @@ -1392,7 +1395,7 @@ namespace Glitter { void CheckUpdate(float_t delta_frame); bool Copy(EffectInstX* eff_inst, SceneX* dst); void Ctrl(float_t delta_frame); - void Disp(DispType disp_type); + void Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); void DispMesh(); size_t GetCtrlCount(ParticleType ptcl_type); size_t GetDispCount(ParticleType ptcl_type); @@ -1433,7 +1436,7 @@ namespace Glitter { uint32_t texture_counter; void CalcDisp(); - void DispScenes(DispType disp_type); + void DispScenes(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); }; class GltParticleManagerX : app::Task { @@ -1469,7 +1472,7 @@ namespace Glitter { void CheckSceneHasLocalEffect(SceneX* sc); void CtrlScenes(); void DecrementInitBuffersByCount(int32_t count = 1); - void DispScenes(DispType disp_type); + void DispScenes(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam); void FreeEffects(); void FreeSceneEffect(SceneCounter scene_counter, bool force_kill = true); void FreeSceneEffect(uint32_t effect_group_hash, uint32_t effect_hash, bool force_kill = true); diff --git a/src/DivaGL/Glitter/particle_manager.cpp b/src/DivaGL/Glitter/particle_manager.cpp index 7423ed1..1c252b0 100644 --- a/src/DivaGL/Glitter/particle_manager.cpp +++ b/src/DivaGL/Glitter/particle_manager.cpp @@ -4,7 +4,7 @@ */ #include "glitter.hpp" -#include "../gl_rend_state.hpp" +#include "../render_context.hpp" #include namespace Glitter { @@ -20,18 +20,18 @@ namespace Glitter { i->CalcDisp(); } - void GltParticleManager::DispScenes(DispType disp_type) { + void GltParticleManager::DispScenes(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { if (flags & PARTICLE_MANAGER_NOT_DISP) return; for (Scene*& i : scenes) if (i) - i->Disp(disp_type); + i->Disp(rend_data_ctx, disp_type, cam); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.disable_blend(); - gl_rend_state.enable_cull_face(); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_depth_test(); } GltParticleManagerX::GltParticleManagerX() : frame_rate(), @@ -262,18 +262,18 @@ namespace Glitter { init_buffers = max_def(init_buffers - count, 0); } - void GltParticleManagerX::DispScenes(DispType disp_type) { + void GltParticleManagerX::DispScenes(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { if (flags & PARTICLE_MANAGER_NOT_DISP) return; for (SceneX*& i : scenes) if (i) - i->Disp(disp_type); + i->Disp(rend_data_ctx, disp_type, cam); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.disable_blend(); - gl_rend_state.enable_cull_face(); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_depth_test(); } void GltParticleManagerX::FreeEffects() { diff --git a/src/DivaGL/Glitter/render_scene.cpp b/src/DivaGL/Glitter/render_scene.cpp index cbbe651..2a8120a 100644 --- a/src/DivaGL/Glitter/render_scene.cpp +++ b/src/DivaGL/Glitter/render_scene.cpp @@ -5,6 +5,7 @@ #include "glitter.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../render_context.hpp" #include "../shader_ft.hpp" #include "../wrap.hpp" @@ -60,7 +61,7 @@ namespace Glitter { } } - void RenderScene::Disp(Glitter::DispType disp_type) { + void RenderScene::Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { bool (FASTCALL * RenderGroup_CannotDisp)(RenderGroup * rend_group) = (bool(FASTCALL*)(RenderGroup * rend_group))0x00000001403A7120; @@ -72,11 +73,11 @@ namespace Glitter { if (RenderGroup_CannotDisp(rend_group) || rend_group->disp_type != disp_type) continue; - Disp(rend_group); + Disp(rend_data_ctx, rend_group, cam); } } - void RenderScene::Disp(RenderGroup* rend_group) { + void RenderScene::Disp(render_data_context& rend_data_ctx, RenderGroup* rend_group, const cam_data& cam) { switch (rend_group->type) { case PARTICLE_QUAD: case PARTICLE_LINE: @@ -89,15 +90,10 @@ namespace Glitter { if (!rend_group->vao || rend_group->disp < 1) return; - mat4 cam_view; - mat4 cam_projection; - mat4_transpose(&camera_data.view, &cam_view); - mat4_transpose(&camera_data.projection, &cam_projection); - mat4 mat; mat4_transpose(&rend_group->mat_draw, &mat); - mat4_mul(&mat, &cam_view, &mat); - mat4_mul(&mat, &cam_projection, &mat); + mat4_mul(&mat, &cam.get_view_mat(), &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); float_t emission = 1.0f; if (rend_group->flags & PARTICLE_EMISSION || rend_group->blend_mode == PARTICLE_BLEND_TYPICAL) @@ -112,7 +108,7 @@ namespace Glitter { shader_data.g_glitter_blend_color = 1.0f; shader_data.g_state_material_diffuse = 0.0f; shader_data.g_state_material_emission = { emission, emission, emission, 1.0f }; - rctx->glitter_batch_ubo.WriteMemory(shader_data); + rctx->glitter_batch_ubo.WriteMemory(rend_data_ctx.state, shader_data); GLenum blend_src; GLenum blend_dst; @@ -137,8 +133,8 @@ namespace Glitter { break; } - gl_rend_state.set_blend_func(blend_src, blend_dst); - gl_rend_state.set_blend_equation(GL_FUNC_ADD); + rend_data_ctx.state.set_blend_func(blend_src, blend_dst); + rend_data_ctx.state.set_blend_equation(GL_FUNC_ADD); GLuint texture = rctx->empty_texture_2d->glid; GLuint mask_texture = rctx->empty_texture_2d->glid; @@ -147,117 +143,116 @@ namespace Glitter { if (rend_group->mask_texture) { mask_texture = rend_group->mask_texture; - uniform->arr[U_TEXTURE_COUNT] = 2; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 2; switch (rend_group->mask_blend_mode) { default: - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; break; case PARTICLE_BLEND_MULTIPLY: - uniform->arr[U_TEXTURE_BLEND] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 1; break; case PARTICLE_BLEND_ADD: - uniform->arr[U_TEXTURE_BLEND] = 2; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 2; break; } } else { - uniform->arr[U_TEXTURE_COUNT] = 1; - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; } } else { - uniform->arr[U_TEXTURE_COUNT] = 0; - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; } - gl_rend_state.active_bind_texture_2d(0, texture); - gl_rend_state.active_bind_texture_2d(1, mask_texture); + rend_data_ctx.state.active_bind_texture_2d(0, texture); + rend_data_ctx.state.active_bind_texture_2d(1, mask_texture); switch (rend_group->type) { case PARTICLE_QUAD: switch (rend_group->fog_type) { default: - uniform->arr[U_FOG_STAGE] = 0; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 0; break; case Glitter::FOG_DEPTH: - uniform->arr[U_FOG_STAGE] = 1; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 1; break; case Glitter::FOG_HEIGHT: - uniform->arr[U_FOG_STAGE] = 2; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 2; break; } - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_depth_test(); if (alpha_test) { - uniform->arr[U_ALPHA_TEST] = 1; - rctx->set_batch_alpha_threshold(0.5f); - uniform->arr[U_ALPHA_BLEND] = 1; - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 1; + rend_data_ctx.set_batch_alpha_threshold(0.5f); + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 1; + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } else if (rend_group->disp_type) { - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 2; - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.enable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 2; + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); } else { - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 0; - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 0; + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } if (rend_group->draw_type == DIRECTION_BILLBOARD) { - gl_rend_state.enable_cull_face(); - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); } else - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_cull_face(); break; case PARTICLE_LINE: - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 2; - uniform->arr[U_FOG_STAGE] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 2; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 0; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.enable_blend(); - gl_rend_state.enable_cull_face(); - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; case PARTICLE_LOCUS: - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 2; - uniform->arr[U_FOG_STAGE] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 2; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 0; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.enable_blend(); - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); break; } - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx->set_glitter_render_data(); - rctx->glitter_batch_ubo.Bind(3); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_GLITTER_PT); + rend_data_ctx.set_glitter_render_data_state(); + rend_data_ctx.state.bind_uniform_buffer_base(3, rctx->glitter_batch_ubo); switch (rend_group->type) { case PARTICLE_QUAD: - gl_rend_state.bind_vertex_array(rend_group->vao); - shaders_ft.enable_primitive_restart(); - shaders_ft.draw_elements(GL_TRIANGLE_STRIP, (GLsizei)(5 * rend_group->disp - 1), GL_UNSIGNED_INT, 0); - shaders_ft.disable_primitive_restart(); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.draw_elements(GL_TRIANGLE_STRIP, + (GLsizei)(5 * rend_group->disp - 1), GL_UNSIGNED_INT, 0); break; case PARTICLE_LINE: - gl_rend_state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); for (std::pair& i : *rend_group->draw_list) - shaders_ft.draw_arrays(GL_LINE_STRIP, i.first, i.second); + rend_data_ctx.state.draw_arrays(GL_LINE_STRIP, i.first, i.second); break; case PARTICLE_LOCUS: - gl_rend_state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); for (std::pair& i : *rend_group->draw_list) - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, i.first, i.second); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, i.first, i.second); break; } } @@ -345,7 +340,7 @@ namespace Glitter { } rend_group->disp = disp; - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); } void RenderScene::CalcDispLocus(RenderGroup* rend_group) { @@ -505,7 +500,7 @@ namespace Glitter { } rend_group->disp = disp; - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); } void RenderScene::CalcDispQuad(RenderGroup* rend_group) { @@ -703,7 +698,7 @@ namespace Glitter { } rend_group->disp = disp; - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); } void RenderScene::CalcDispQuadNormal( @@ -930,7 +925,7 @@ namespace Glitter { } rend_group->disp = disp; - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); } void RenderScene::CalcDispLocusSetPivot(Pivot pivot, @@ -1169,7 +1164,7 @@ namespace Glitter { rend_group->disp = disp; #if !SHARED_GLITTER_BUFFER - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); #endif } @@ -1326,7 +1321,7 @@ namespace Glitter { rend_group->disp = disp; #if !SHARED_GLITTER_BUFFER - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); #endif } @@ -1518,7 +1513,7 @@ namespace Glitter { rend_group->disp = disp; #if !SHARED_GLITTER_BUFFER - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); #endif } @@ -1732,7 +1727,7 @@ namespace Glitter { rend_group->disp = disp; #if !SHARED_GLITTER_BUFFER - rend_group->vbo.WriteMemory(0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); + rend_group->vbo.WriteMemory(gl_state, 0, (buf - rend_group->buffer) * sizeof(Buffer), rend_group->buffer); #endif } @@ -1778,7 +1773,7 @@ namespace Glitter { } } - void RenderSceneX::Disp(DispType disp_type) { + void RenderSceneX::Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { for (RenderGroupX* i : groups) { if (!i) continue; @@ -1787,11 +1782,11 @@ namespace Glitter { if ((rend_group)->disp_type != disp_type || rend_group->CannotDisp()) continue; - Disp(rend_group); + Disp(rend_data_ctx, rend_group, cam); } } - void RenderSceneX::Disp(RenderGroupX* rend_group) { + void RenderSceneX::Disp(render_data_context& rend_data_ctx, RenderGroupX* rend_group, const cam_data& cam) { switch (rend_group->type) { case PARTICLE_QUAD: case PARTICLE_LINE: @@ -1805,16 +1800,9 @@ namespace Glitter { if (!rend_group->vao || rend_group->disp < 1) return; - mat4 cam_view; - mat4 cam_projection; - mat4_transpose(&camera_data.view, &cam_view); - if (reflect_draw) - mat4_mul(&reflect_mat, &cam_view, &cam_view); - mat4_transpose(&camera_data.projection, &cam_projection); - mat4 mat; - mat4_mul(&rend_group->mat_draw, &cam_view, &mat); - mat4_mul(&mat, &cam_projection, &mat); + mat4_mul(&rend_group->mat_draw, &cam.get_view_mat(), &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); float_t emission = 1.0f; if (rend_group->flags & PARTICLE_EMISSION || rend_group->blend_mode == PARTICLE_BLEND_TYPICAL) @@ -1829,7 +1817,7 @@ namespace Glitter { shader_data.g_glitter_blend_color = 1.0f; shader_data.g_state_material_diffuse = 0.0f; shader_data.g_state_material_emission = { emission, emission, emission, 1.0f }; - rctx->glitter_batch_ubo.WriteMemory(shader_data); + rctx->glitter_batch_ubo.WriteMemory(rend_data_ctx.state, shader_data); GLenum blend_src; GLenum blend_dst; @@ -1854,8 +1842,8 @@ namespace Glitter { break; } - gl_rend_state.set_blend_func(blend_src, blend_dst); - gl_rend_state.set_blend_equation(GL_FUNC_ADD); + rend_data_ctx.state.set_blend_func(blend_src, blend_dst); + rend_data_ctx.state.set_blend_equation(GL_FUNC_ADD); GLuint texture = rctx->empty_texture_2d->glid; GLuint mask_texture = rctx->empty_texture_2d->glid; @@ -1864,95 +1852,94 @@ namespace Glitter { if (rend_group->mask_texture) { mask_texture = rend_group->mask_texture; - uniform->arr[U_TEXTURE_COUNT] = 2; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 2; switch (rend_group->mask_blend_mode) { default: - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; break; case PARTICLE_BLEND_MULTIPLY: - uniform->arr[U_TEXTURE_BLEND] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 1; break; case PARTICLE_BLEND_ADD: - uniform->arr[U_TEXTURE_BLEND] = 2; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 2; break; } } else { - uniform->arr[U_TEXTURE_COUNT] = 1; - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; } } else { - uniform->arr[U_TEXTURE_COUNT] = 0; - uniform->arr[U_TEXTURE_BLEND] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = 0; } - gl_rend_state.active_bind_texture_2d(0, texture); - gl_rend_state.active_bind_texture_2d(1, mask_texture); + rend_data_ctx.state.active_bind_texture_2d(0, texture); + rend_data_ctx.state.active_bind_texture_2d(1, mask_texture); switch (rend_group->fog_type) { default: - uniform->arr[U_FOG_STAGE] = 0; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 0; break; case Glitter::FOG_DEPTH: - uniform->arr[U_FOG_STAGE] = 1; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 1; break; case Glitter::FOG_HEIGHT: - uniform->arr[U_FOG_STAGE] = 2; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = 2; break; } if (!(rend_group->flags & PARTICLE_DEPTH_TEST)) - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_depth_test(); else - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.disable_depth_test(); if (alpha_test) { - uniform->arr[U_ALPHA_TEST] = 1; - rctx->set_batch_alpha_threshold(0.5f); - uniform->arr[U_ALPHA_BLEND] = rend_group->disp_type ? 3 : 1; - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 1; + rend_data_ctx.set_batch_alpha_threshold(0.5f); + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = rend_group->disp_type ? 3 : 1; + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } else if (rend_group->disp_type) { - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 2; - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.enable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 2; + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); } else { - uniform->arr[U_ALPHA_TEST] = 0; - uniform->arr[U_ALPHA_BLEND] = 0; - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_BLEND] = 0; + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } if (rend_group->draw_type == DIRECTION_BILLBOARD && !rend_group->use_culling) { - gl_rend_state.enable_cull_face(); - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); } else - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_cull_face(); - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx->set_glitter_render_data(); - rctx->glitter_batch_ubo.Bind(3); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_GLITTER_PT); + rend_data_ctx.set_glitter_render_data_state(); + rend_data_ctx.state.bind_uniform_buffer_base(3, rctx->glitter_batch_ubo); switch (rend_group->type) { case PARTICLE_QUAD: - gl_rend_state.bind_vertex_array(rend_group->vao); - shaders_ft.enable_primitive_restart(); - shaders_ft.draw_elements(GL_TRIANGLE_STRIP, (GLsizei)(5 * rend_group->disp - 1), GL_UNSIGNED_INT, 0); - shaders_ft.disable_primitive_restart(); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.draw_elements(GL_TRIANGLE_STRIP, + (GLsizei)(5 * rend_group->disp - 1), GL_UNSIGNED_INT, 0); break; case PARTICLE_LINE: - gl_rend_state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); for (std::pair& i : rend_group->draw_list) - shaders_ft.draw_arrays(GL_LINE_STRIP, i.first, i.second); + rend_data_ctx.state.draw_arrays(GL_LINE_STRIP, i.first, i.second); break; case PARTICLE_LOCUS: - gl_rend_state.bind_vertex_array(rend_group->vao); + rend_data_ctx.state.bind_vertex_array(rend_group->vao); for (std::pair& i : rend_group->draw_list) - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, i.first, i.second); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, i.first, i.second); break; } } diff --git a/src/DivaGL/Glitter/scene.cpp b/src/DivaGL/Glitter/scene.cpp index 1bad80c..c947ce8 100644 --- a/src/DivaGL/Glitter/scene.cpp +++ b/src/DivaGL/Glitter/scene.cpp @@ -4,11 +4,12 @@ */ #include "glitter.hpp" +#include "../gl_state.hpp" namespace Glitter { - void Scene::Disp(DispType disp_type) { + void Scene::Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { if (!(flags & SCENE_NOT_DISP)) - render_scene.Disp(disp_type); + render_scene.Disp(rend_data_ctx, disp_type, cam); } void Scene::CalcDisp() { @@ -60,7 +61,7 @@ namespace Glitter { } if (disp) - effect_group->vbo.WriteMemory(0, effect_group->max_count * sizeof(Buffer), effect_group->buffer); + effect_group->vbo.WriteMemory(gl_state, 0, effect_group->max_count * sizeof(Buffer), effect_group->buffer); #endif } @@ -137,13 +138,13 @@ namespace Glitter { } } - void SceneX::Disp(DispType disp_type) { + void SceneX::Disp(render_data_context& rend_data_ctx, DispType disp_type, const cam_data& cam) { if (flags & SCENE_NOT_DISP) return; for (SceneEffectX& i : effects) if (i.ptr && i.disp) - i.ptr->Disp(disp_type); + i.ptr->Disp(rend_data_ctx, disp_type, cam); } void SceneX::DispMesh() { diff --git a/src/DivaGL/camera.cpp b/src/DivaGL/camera.cpp index a91a67e..c0c1a6f 100644 --- a/src/DivaGL/camera.cpp +++ b/src/DivaGL/camera.cpp @@ -4,10 +4,121 @@ */ #include "camera.hpp" -#include "render.hpp" #include "../AFTModsShared/resolution_mode.hpp" +#include "render.hpp" +#include "render_context.hpp" #include +cam_data::cam_data() : view_point(0.0f, 0.0f, 1.0f), interest(), up(0.0f, 1.0f, 0.0f), +fov(30.0f * DEG_TO_RAD_FLOAT), aspect(4.0f / 3.0f), min_distance(1.0f), max_distance(200.0f), +view_mat(), proj_mat(), view_proj_mat(), persp_scale(), persp_offset() { + +} + +void cam_data::calc_ortho_proj_mat(float_t left, float_t right, + float_t bottom, float_t top, const vec2& scale, const vec2& offset) { + mat4_ortho_offset(left, right, bottom, top, min_distance, max_distance, &scale, &offset, &proj_mat); +} + +void cam_data::calc_persp_proj_mat() { + mat4_persp(fov, aspect, min_distance, max_distance, &proj_mat); + persp_scale = 1.0f; + persp_offset = 0.0f; +} + +void cam_data::calc_persp_proj_mat_offset(const vec2& persp_scale, const vec2& persp_offset) { + mat4_persp_offset(fov, aspect, min_distance, max_distance, &persp_scale, &persp_offset, &proj_mat); + this->persp_scale = persp_scale; + this->persp_offset = persp_offset; +} + +void cam_data::calc_view_mat() { + mat4_look_at(&view_point, &interest, &up, &view_mat); +} + +void cam_data::calc_view_proj_mat() { + mat4_mul(&view_mat, &proj_mat, &view_proj_mat); +} + +void cam_data::get() { + view_point = camera_data.view_point; + interest = camera_data.interest; + up = camera_data.up; + fov = camera_data.fov * DEG_TO_RAD_FLOAT; + aspect = (float_t)camera_data.aspect; + min_distance = camera_data.min_distance; + max_distance = camera_data.max_distance; + mat4_transpose(&camera_data.view, &view_mat); + mat4_transpose(&camera_data.projection, &proj_mat); + mat4_transpose(&camera_data.view_projection, &view_proj_mat); + persp_scale = 1.0f; + persp_offset = 0.0f; +} + +float_t cam_data::get_aspect() const { + return aspect; +} + +float_t cam_data::get_fov() const { + return fov; +} + +const vec3& cam_data::get_interest() const { + return interest; +} + +float_t cam_data::get_min_distance() const { + return min_distance; +} + +float_t cam_data::get_max_distance() const { + return max_distance; +} + +const mat4& cam_data::get_proj_mat() const { + return proj_mat; +} + +const mat4& cam_data::get_view_mat() const { + return view_mat; +} + +const vec3& cam_data::get_view_point() const { + return view_point; +} + +const mat4& cam_data::get_view_proj_mat() const { + return view_proj_mat; +} + +void cam_data::set_aspect(float_t value) { + aspect = value; +} + +void cam_data::set_fov(float_t value) { + fov = value; +} + +void cam_data::set_interest(const vec3& value) { + interest = value; +} + +void cam_data::set_min_distance(float_t value) { + min_distance = value; +} + +void cam_data::set_max_distance(float_t value) { + max_distance = value; +} + +void cam_data::set_up(const vec3& value) { + up = value; +} + +void cam_data::set_view_point(const vec3& value) { + view_point = value; +} + static void (FASTCALL* camera_struct__update_view)(camera_struct& cam) = (void (FASTCALL*)(camera_struct & cam))0x00000001401F7690; @@ -58,10 +169,13 @@ HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) { mat4_mul(&spr_3d_view, &spr_3d_proj, &spr_3d_proj); mat4_transpose(&spr_3d_proj, &camera_data.view_projection_aet_3d); - render_get()->calc_projection_matrix(&camera_data.projection, camera_data.fov, - (float_t)camera_data.aspect, camera_data.min_distance, camera_data.max_distance, - camera_data.proj_left_offset, camera_data.proj_right_offset, - camera_data.proj_bottom_offset, camera_data.proj_top_offset); + vec2 persp_scale = 1.0f; + vec2 persp_offset = render_get()->get_taa_offset(); + mat4 proj; + mat4_persp_offset(camera_data.fov * DEG_TO_RAD_FLOAT, (float_t)camera_data.aspect, + camera_data.min_distance, camera_data.max_distance, &persp_scale, &persp_offset, &proj); + mat4_transpose(&proj, &camera_data.projection); + camera_data.fov_horizontal_rad = tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT); } @@ -71,6 +185,9 @@ HOOK(void, FASTCALL, camera_update, 0x00000001401F8970) { camera_data.fast_change_hist1 = camera_data.fast_change_hist0; camera_data.fast_change_hist0 = camera_data.fast_change; camera_data.fast_change = false; + + extern render_context* rctx; + rctx->render_manager_cam.get(); } void camera_patch() { diff --git a/src/DivaGL/camera.hpp b/src/DivaGL/camera.hpp index e4f0dbc..ce61b4d 100644 --- a/src/DivaGL/camera.hpp +++ b/src/DivaGL/camera.hpp @@ -8,4 +8,45 @@ #include "../KKdLib/default.hpp" #include "../AFTModsShared/camera.hpp" +struct cam_data { + vec3 view_point; + vec3 interest; + vec3 up; + float_t fov; + float_t aspect; + float_t min_distance; + float_t max_distance; + mat4 view_mat; + mat4 proj_mat; + mat4 view_proj_mat; + vec2 persp_scale; + vec2 persp_offset; + + cam_data(); + + void calc_ortho_proj_mat(float_t left, float_t right, + float_t bottom, float_t top, const vec2& scale, const vec2& offset); + void calc_persp_proj_mat(); + void calc_persp_proj_mat_offset(const vec2& persp_scale, const vec2& persp_offset); + void calc_view_mat(); + void calc_view_proj_mat(); + void get(); + float_t get_aspect() const; + float_t get_fov() const; + const vec3& get_interest() const; + float_t get_min_distance() const; + float_t get_max_distance() const; + const mat4& get_proj_mat() const; + const mat4& get_view_mat() const; + const vec3& get_view_point() const; + const mat4& get_view_proj_mat() const; + void set_aspect(float_t value); + void set_fov(float_t value); + void set_interest(const vec3& value); + void set_min_distance(float_t value); + void set_max_distance(float_t value); + void set_up(const vec3& value); + void set_view_point(const vec3& value); +}; + extern void camera_patch(); diff --git a/src/DivaGL/clear_color.cpp b/src/DivaGL/clear_color.cpp index 4c323f7..1560296 100644 --- a/src/DivaGL/clear_color.cpp +++ b/src/DivaGL/clear_color.cpp @@ -4,11 +4,11 @@ */ #include "clear_color.hpp" -#include "wrap.hpp" +#include "gl_rend_state.hpp" color4u8& clear_color = *(color4u8*)0x0000000140EC57C8; -void clear_color_set_gl() { +void clear_color_set_gl(p_gl_rend_state& p_gl_rend_st) { vec4 color = clear_color; - glClearColorDLL(color.x, color.y, color.z, color.w); + p_gl_rend_st.clear_color(color.x, color.y, color.z, color.w); } diff --git a/src/DivaGL/clear_color.hpp b/src/DivaGL/clear_color.hpp index b79cb71..6d3eedc 100644 --- a/src/DivaGL/clear_color.hpp +++ b/src/DivaGL/clear_color.hpp @@ -10,4 +10,4 @@ extern color4u8& clear_color; -extern void clear_color_set_gl(); +extern void clear_color_set_gl(struct p_gl_rend_state& p_gl_rend_st); diff --git a/src/DivaGL/data_test/rob_osage_test.cpp b/src/DivaGL/data_test/rob_osage_test.cpp index 7797259..0739a04 100644 --- a/src/DivaGL/data_test/rob_osage_test.cpp +++ b/src/DivaGL/data_test/rob_osage_test.cpp @@ -981,7 +981,7 @@ void RobOsageTest::disp_coli() { return; disp_coli_cls_list(ex_node, cls_param); - + if (osg && osg->rob.nodes.size() >= 1) { RobOsageNode* j_begin = osg->rob.nodes.data() + 1; RobOsageNode* j_end = osg->rob.nodes.data() + osg->rob.nodes.size(); diff --git a/src/DivaGL/effect.cpp b/src/DivaGL/effect.cpp index 393d70d..7381ee5 100644 --- a/src/DivaGL/effect.cpp +++ b/src/DivaGL/effect.cpp @@ -15,6 +15,7 @@ #include "rob/rob.hpp" #include "auth_3d.hpp" #include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "render_context.hpp" #include "render_manager.hpp" #include "render_texture.hpp" @@ -87,7 +88,7 @@ struct EffectFogRing { prj::vector stage_indices; FrameRateControl* frame_rate_control; - void draw(); + void draw(render_data_context& rend_data_ctx, const cam_data& cam); }; static_assert(sizeof(EffectFogRing) == 0x2E0, "\"EffectFogRing\" struct should have a size of 0x2E0"); @@ -165,9 +166,9 @@ struct EffectRipple { int32_t current_stage_index; prj::vector stage_indices; - void draw(); + void draw(render_data_context& rend_data_ctx, const cam_data& cam); - void sub_1403584A0(RenderTexture* rt); + void sub_1403584A0(render_data_context& rend_data_ctx, RenderTexture* rt); }; static_assert(sizeof(EffectRipple) == 0xC20, "\"EffectRipple\" struct should have a size of 0xC20"); @@ -252,7 +253,8 @@ struct star_catalog_milky_way { float_t longitude_offset_degs_10, float_t latitude_offset_degs_10); void create_default_sphere(); void delete_buffers(); - void draw(const mat4& vp, const mat4& model, texture* tex, GL::UniformBuffer& scene_ubo); + void draw(render_data_context& rend_data_ctx, + const mat4& vp, const mat4& model, texture* tex, GL::UniformBuffer& scene_ubo); }; static_assert(sizeof(star_catalog_milky_way) == 0x34, "\"star_catalog_milky_way\" struct should have a size of 0x34"); @@ -271,7 +273,7 @@ struct star_catalog { uint32_t star_b_tex; uint32_t milky_way_tex_id; - void draw(); + void draw(render_data_context& rend_data_ctx, const cam_data& cam); void free(); bool init(); }; @@ -314,7 +316,7 @@ struct water_particle { ripple_struct ripple; float_t ripple_emission; - void draw(mat4* mat); + void draw(render_data_context& rend_data_ctx, const cam_data& cam, mat4* mat); }; static_assert(sizeof(water_particle) == 0xA8, "\"water_particle\" struct should have a size of 0xA8"); @@ -431,29 +433,29 @@ struct EffectStorage { GL::ShaderStorageBuffer ssbo; EffectStorage() : vao() { - + } - void Bind(int32_t index, bool force = false) { + void Bind(p_gl_rend_state& p_gl_rend_st, int32_t index) { if (DIVA_GL_VERSION_4_3) - ssbo.Bind(index, force); + p_gl_rend_st.bind_shader_storage_buffer_base(index, ssbo); else - gl_rend_state.bind_vertex_array(vao); + p_gl_rend_st.bind_vertex_array(vao); } - void Create(size_t size, size_t count, const EffectStorageAttrib* attribs) { + void Create(gl_state_struct& gl_st, size_t size, size_t count, const EffectStorageAttrib* attribs) { if (DIVA_GL_VERSION_4_3) { - ssbo.Create(size * count); + ssbo.Create(gl_st, size * count); return; } else if (vao || !attribs) return; glGenVertexArrays(1, &vao); - gl_rend_state.bind_vertex_array(vao, true); + gl_st.bind_vertex_array(vao, true); - vbo.Create(size * count); - vbo.Bind(true); + vbo.Create(gl_st, size * count); + gl_st.bind_array_buffer(true); const EffectStorageAttrib* attrib = attribs; while (attrib->index != -1) { @@ -464,24 +466,24 @@ struct EffectStorage { attrib++; } - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_st.bind_array_buffer(0); + gl_st.bind_vertex_array(0); } - void Create(size_t size, size_t count, const EffectStorageAttrib* attribs, + void Create(gl_state_struct& gl_st, size_t size, size_t count, const EffectStorageAttrib* attribs, const void* data, bool dynamic = false) { if (DIVA_GL_VERSION_4_3) { - ssbo.Create(size * count, data, dynamic); + ssbo.Create(gl_st, size * count, data, dynamic); return; } else if (vao || !attribs) return; glGenVertexArrays(1, &vao); - gl_rend_state.bind_vertex_array(vao, true); + gl_st.bind_vertex_array(vao, true); - vbo.Create(size * count, data, true); - vbo.Bind(true); + vbo.Create(gl_st, size * count, data, true); + gl_st.bind_array_buffer(vbo, true); const EffectStorageAttrib* attrib = attribs; while (attrib->index != -1) { @@ -492,8 +494,8 @@ struct EffectStorage { attrib++; } - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_st.bind_array_buffer(0); + gl_st.bind_vertex_array(0); } void Destroy() { @@ -517,25 +519,46 @@ struct EffectStorage { glDrawArraysInstanced(mode, first, 6, count / 6); } - void* MapMemory() { + void* MapMemory(gl_state_struct& gl_st) { if (DIVA_GL_VERSION_4_3) - return ssbo.MapMemory(); + return ssbo.MapMemory(gl_st); else - return vbo.MapMemory(); + return vbo.MapMemory(gl_st); } - void UnmapMemory() { + void* MapMemory(p_gl_rend_state& p_gl_rend_st) { if (DIVA_GL_VERSION_4_3) - ssbo.UnmapMemory(); + return ssbo.MapMemory(p_gl_rend_st); else - vbo.UnmapMemory(); + return vbo.MapMemory(p_gl_rend_st); } - void WriteMemory(size_t offset, size_t size, const void* data) { + void UnmapMemory(gl_state_struct& gl_st) { if (DIVA_GL_VERSION_4_3) - ssbo.WriteMemory(offset, size, data); + ssbo.UnmapMemory(gl_st); else - vbo.WriteMemory(offset, size, data); + vbo.UnmapMemory(gl_st); + } + + void UnmapMemory(p_gl_rend_state& p_gl_rend_st) { + if (DIVA_GL_VERSION_4_3) + ssbo.UnmapMemory(p_gl_rend_st); + else + vbo.UnmapMemory(p_gl_rend_st); + } + + void WriteMemory(gl_state_struct& gl_st, size_t offset, size_t size, const void* data) { + if (DIVA_GL_VERSION_4_3) + ssbo.WriteMemory(gl_st, offset, size, data); + else + vbo.WriteMemory(gl_st, offset, size, data); + } + + void WriteMemory(p_gl_rend_state& p_gl_rend_st, size_t offset, size_t size, const void* data) { + if (DIVA_GL_VERSION_4_3) + ssbo.WriteMemory(p_gl_rend_st, offset, size, data); + else + vbo.WriteMemory(p_gl_rend_st, offset, size, data); } }; @@ -632,13 +655,16 @@ extern render_context* rctx; static void TaskEffectAuth3D__SetVisibility(size_t This, bool value); -static void draw_fog_particle(EffectFogRing* data, mat4* mat); +static void draw_fog_particle(render_data_context& rend_data_ctx, + EffectFogRing* data, const cam_data& cam, mat4* mat); -static void draw_ripple_particles(ripple_struct* data, mat4* mat); +static void draw_ripple_particles(render_data_context& rend_data_ctx, + ripple_struct* data, const cam_data& cam, mat4* mat); -static void draw_water_particle(water_particle* data, mat4* mat); +static void draw_water_particle(render_data_context& rend_data_ctx, + water_particle* data, const cam_data& cam, mat4* mat); -static int32_t leaf_particle_disp(); +static int32_t leaf_particle_disp(render_data_context& rend_data_ctx); static int32_t particle_disp(particle_vertex_data* vtx_data, particle_rot_data* data, int32_t count); @@ -654,7 +680,7 @@ static particle_data* snow_particle_emit_fallen(); static vec3 snow_particle_get_random_velocity(); static void snow_particle_free(); -void leaf_particle_draw() { +void leaf_particle_draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!stage_param_data_leaf_current || !leaf_ptcl_data || !leaf_particle_enable || !stage_param_data_leaf_set) return; @@ -663,7 +689,7 @@ void leaf_particle_draw() { if (!tex) return; - int32_t count = leaf_particle_disp(); + int32_t count = leaf_particle_disp(rend_data_ctx); if (!count) return; @@ -671,27 +697,28 @@ void leaf_particle_draw() { leaf_particle_scene_shader_data shader_data = {}; mat4 temp; - mat4_transpose(&rctx->vp_mat, &temp); + mat4_transpose(&cam.view_proj_mat, &temp); shader_data.g_transform[0] = temp.row0; shader_data.g_transform[1] = temp.row1; shader_data.g_transform[2] = temp.row2; shader_data.g_transform[3] = temp.row3; - camera_data.get_view_point(shader_data.g_view_pos); + *(vec3*)&shader_data.g_view_pos = cam.get_view_point(); + shader_data.g_view_pos = 0.0f; shader_data.g_color = stage_param_data_leaf_current->color; - rctx->get_scene_light(&shader_data.g_light_env_stage_diffuse, + rend_data_ctx.get_scene_light(&shader_data.g_light_env_stage_diffuse, &shader_data.g_light_env_stage_specular, &shader_data.g_lit_dir, &shader_data.g_lit_luce, 0, 0); - leaf_particle_scene_ubo.WriteMemory(shader_data); + leaf_particle_scene_ubo.WriteMemory(rend_data_ctx.state, shader_data); - gl_rend_state.active_bind_texture_2d(0, tex->glid); - shaders_ft.set(SHADER_FT_LEAF_PT); - leaf_particle_scene_ubo.Bind(0); - gl_rend_state.bind_vertex_array(leaf_ptcl_vao); - shaders_ft.draw_elements(GL_TRIANGLES, count / 4 * 6, GL_UNSIGNED_INT, 0); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_LEAF_PT); + rend_data_ctx.state.bind_uniform_buffer_base(0, leaf_particle_scene_ubo); + rend_data_ctx.state.bind_vertex_array(leaf_ptcl_vao); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, count / 4 * 6, GL_UNSIGNED_INT, 0); + rend_data_ctx.state.bind_vertex_array(0); } -void rain_particle_draw() { +void rain_particle_draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!stage_param_data_rain_current || !rain_particle_enable || !stage_param_data_rain_set) return; @@ -708,26 +735,26 @@ void rain_particle_draw() { rain_particle_scene_shader_data scene_shader_data = {}; mat4 temp; - mat4_transpose(&rctx->view_mat, &temp); + mat4_transpose(&cam.view_mat, &temp); scene_shader_data.g_view[0] = temp.row0; scene_shader_data.g_view[1] = temp.row1; scene_shader_data.g_view[2] = temp.row2; scene_shader_data.g_view[3] = temp.row3; - mat4_transpose(&rctx->proj_mat, &temp); + mat4_transpose(&cam.proj_mat, &temp); scene_shader_data.g_proj[0] = temp.row0; scene_shader_data.g_proj[1] = temp.row1; scene_shader_data.g_proj[2] = temp.row2; scene_shader_data.g_proj[3] = temp.row3; scene_shader_data.g_range_scale = { range_scale.x, range_scale.y, range_scale.z, 0.0f }; scene_shader_data.g_range_offset = { range_offset.x, range_offset.y, range_offset.z, 0.0f }; - rain_particle_scene_ubo.WriteMemory(scene_shader_data); + rain_particle_scene_ubo.WriteMemory(rend_data_ctx.state, scene_shader_data); - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.active_bind_texture_2d(0, tex->glid); - shaders_ft.set(SHADER_FT_RAIN); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_RAIN); float_t tangent_sign = -rain->psize.x; float_t tangent_size = -rain->psize.y * (float_t)(1.0 / 30.0); @@ -737,10 +764,10 @@ void rain_particle_draw() { vec4 color = rain->color; float_t color_a = color.w; - gl_rend_state.bind_vertex_array(rctx->common_vao); - rain_particle_scene_ubo.Bind(0); - rain_particle_batch_ubo.Bind(1); - rain_storage.Bind(0); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.bind_uniform_buffer_base(0, rain_particle_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rain_particle_batch_ubo); + rain_storage.Bind(rend_data_ctx.state, 0); for (int32_t i = 0; i < 8; i++, first += count) { particle_data& data = rain_ptcl_data[i]; vec3 pos_offset = *(vec3*)&data.position / range; @@ -751,26 +778,26 @@ void rain_particle_draw() { batch_shader_data.g_pos_offset = { pos_offset.x, pos_offset.y, pos_offset.z, 0.075f }; batch_shader_data.g_tangent = { tangent.x, tangent.y, tangent.z, tangent_sign }; batch_shader_data.g_color = color; - rain_particle_batch_ubo.WriteMemory(batch_shader_data); + rain_particle_batch_ubo.WriteMemory(rend_data_ctx.state, batch_shader_data); rain_storage.Draw(GL_TRIANGLES, first, count); } - gl_rend_state.bind_vertex_array(0); - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } -void particle_draw() { +void particle_draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!ptcl_data) return; - particle_vertex_data* vtx_data = (particle_vertex_data*)ptcl_vbo.MapMemory(); + particle_vertex_data* vtx_data = (particle_vertex_data*)ptcl_vbo.MapMemory(rend_data_ctx.state); if (!vtx_data) return; int32_t count = particle_disp(vtx_data, ptcl_data, ptcl_count); - ptcl_vbo.UnmapMemory(); + ptcl_vbo.UnmapMemory(rend_data_ctx.state); if (!count) return; @@ -779,24 +806,25 @@ void particle_draw() { particle_scene_shader_data shader_data = {}; mat4 temp; - mat4_transpose(&rctx->vp_mat, &temp); + mat4_transpose(&cam.view_proj_mat, &temp); shader_data.g_transform[0] = temp.row0; shader_data.g_transform[1] = temp.row1; shader_data.g_transform[2] = temp.row2; shader_data.g_transform[3] = temp.row3; - camera_data.get_view_point(shader_data.g_view_pos); + *(vec3*)&shader_data.g_view_pos = cam.get_view_point(); + shader_data.g_view_pos = 0.0f; light_chara.get_diffuse(shader_data.g_light_env_chara_diffuse); light_chara.get_specular(shader_data.g_light_env_chara_specular); - particle_scene_ubo.WriteMemory(shader_data); + particle_scene_ubo.WriteMemory(rend_data_ctx.state, shader_data); - shaders_ft.set(SHADER_FT_PARTICL); - particle_scene_ubo.Bind(0); - gl_rend_state.bind_vertex_array(ptcl_vao); - shaders_ft.draw_arrays(GL_TRIANGLES, 0, count); - gl_rend_state.bind_vertex_array(0); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_PARTICL); + rend_data_ctx.state.bind_uniform_buffer_base(0, particle_scene_ubo); + rend_data_ctx.state.bind_vertex_array(ptcl_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLES, 0, count); + rend_data_ctx.state.bind_vertex_array(0); } -void snow_particle_draw() { +void snow_particle_draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!stage_param_data_snow_current || !snow_particle_enable || !stage_param_data_snow_set) return; @@ -805,25 +833,24 @@ void snow_particle_draw() { return; stage_param_data_snow* snow = stage_param_data_snow_current; - draw_pass_set_camera(); + rend_data_ctx.set_batch_scene_camera(cam); - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); - float_t point_attenuation = powf(tanf((float_t)camera_data.fov - * 0.5f * DEG_TO_RAD_FLOAT) * 3.4f, 2.0f) * 0.1f; + float_t point_attenuation = powf(tanf(cam.get_fov() * 0.5f) * 3.4f, 2.0f) * 0.1f; snow_particle_scene_shader_data snow_scene = {}; mat4 temp; - mat4_transpose(&rctx->vp_mat, &temp); + mat4_transpose(&cam.view_proj_mat, &temp); snow_scene.g_transform[0] = temp.row0; snow_scene.g_transform[1] = temp.row1; snow_scene.g_transform[2] = temp.row2; snow_scene.g_transform[3] = temp.row3; - mat4_transpose(&rctx->view_mat, &temp); + mat4_transpose(&cam.view_mat, &temp); snow_scene.g_view_world_row2 = temp.row2; snow_scene.g_size_in_projection.x = 1.0f / (float_t)render_get()->render_width[0]; snow_scene.g_size_in_projection.y = 1.0f / (float_t)render_get()->render_height[0]; @@ -836,40 +863,39 @@ void snow_particle_draw() { snow_scene.g_range_offset.x = snow->offset_gpu.x - snow->range_gpu.x * 0.5f; snow_scene.g_range_offset.y = snow->offset_gpu.y; snow_scene.g_range_offset.z = snow->offset_gpu.z - snow->range_gpu.z * 0.5f; - snow_particle_scene_ubo.WriteMemory(snow_scene); + snow_particle_scene_ubo.WriteMemory(rend_data_ctx.state, snow_scene); snow_particle_batch_shader_data snow_batch = {}; snow_batch.g_color = snow->color; snow_batch.start_vertex_location.x = 0; - snow_particle_batch_ubo.WriteMemory(snow_batch); + snow_particle_batch_ubo.WriteMemory(rend_data_ctx.state, snow_batch); - gl_rend_state.active_bind_texture_2d(0, tex->glid); - gl_rend_state.active_bind_texture_2d(1, render_get()->rend_texture[0].GetDepthTex()); - gl_rend_state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); + rend_data_ctx.state.active_bind_texture_2d(1, render_get()->rend_texture[0].GetDepthTex()); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); - uniform->arr[U_SNOW_PARTICLE] = 0; - shaders_ft.set(SHADER_FT_SNOW_PT); - snow_particle_scene_ubo.Bind(0); - snow_particle_batch_ubo.Bind(1); + rend_data_ctx.shader_flags.arr[U_SNOW_PARTICLE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SNOW_PT); + rend_data_ctx.state.bind_uniform_buffer_base(0, snow_particle_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, snow_particle_batch_ubo); - snow_storage.Bind(0); + snow_storage.Bind(rend_data_ctx.state, 0); snow_storage.Draw(GL_TRIANGLES, 0, snow->num_snow * 6); - snow_fallen_storage.Bind(0); + snow_fallen_storage.Bind(rend_data_ctx.state, 0); snow_fallen_storage.Draw(GL_TRIANGLES, 0, (GLsizei)(snow_ptcl_fallen_count * 6)); - uniform->arr[U_SNOW_PARTICLE] = 1; - shaders_ft.set(SHADER_FT_SNOW_PT); - snow_particle_scene_ubo.Bind(0); - snow_particle_batch_ubo.Bind(1); + rend_data_ctx.shader_flags.arr[U_SNOW_PARTICLE] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SNOW_PT); + rend_data_ctx.state.bind_uniform_buffer_base(0, snow_particle_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, snow_particle_batch_ubo); - point_attenuation = powf(tanf((float_t)camera_data.fov - * 0.5f * DEG_TO_RAD_FLOAT) * 3.4f, 2.0f) * 0.06f; + point_attenuation = powf(tanf(cam.get_fov() * 0.5f) * 3.4f, 2.0f) * 0.06f; snow_scene.g_state_point_attenuation = { 0.0f, 0.0f, point_attenuation, 0.0f }; - snow_particle_scene_ubo.WriteMemory(snow_scene); + snow_particle_scene_ubo.WriteMemory(rend_data_ctx.state, snow_scene); - snow_gpu_storage.Bind(0); + snow_gpu_storage.Bind(rend_data_ctx.state, 0); int32_t count = snow->num_snow_gpu / 4; count = min_def(count, (int32_t)snow_ptcl_count / 4) * 6; @@ -885,22 +911,22 @@ void snow_particle_draw() { snow_batch.g_pos_offset = { pos_offset.x, pos_offset.y, pos_offset.z, 0.0f }; snow_batch.g_color = color; snow_batch.start_vertex_location.x = first; - snow_particle_batch_ubo.WriteMemory(snow_batch); + snow_particle_batch_ubo.WriteMemory(rend_data_ctx.state, snow_batch); snow_gpu_storage.Draw(GL_TRIANGLES, first, count); first += count; } - gl_rend_state.active_bind_texture_2d(1, 0); - gl_rend_state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.active_bind_texture_2d(1, 0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); - gl_rend_state.disable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.disable_blend(); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); } -void star_catalog_draw() { - star_catalog_data.draw(); +void star_catalog_draw(render_data_context& rend_data_ctx, const cam_data& cam) { + star_catalog_data.draw(rend_data_ctx, cam); } HOOK(void, FASTCALL, TaskEffectAuth3D__SetCurrentStageIndex, 0x00000001403459F0, size_t This, int32_t stage_index) { @@ -952,7 +978,7 @@ HOOK(void, FASTCALL, EffectFogRing__set_stage_indices, 0x0000000140348790, { 2, sizeof(fog_ring_vertex_data::size ), offsetof(fog_ring_vertex_data, size ), }, { (uint32_t)-1 }, }; - elem->second.Create(sizeof(fog_ring_vertex_data), fog_ring->max_ptcls, attribs); + elem->second.Create(gl_state, sizeof(fog_ring_vertex_data), fog_ring->max_ptcls, attribs); } HOOK(void, FASTCALL, EffectFogRing__calc_vert, 0x000000001403495B0, EffectFogRing* fog_ring) { @@ -965,7 +991,7 @@ HOOK(void, FASTCALL, EffectFogRing__calc_vert, 0x000000001403495B0, EffectFogRin float_t density = fog_ring->density; fog_ring_data* ptcl_data = fog_ring->ptcl_data; - fog_ring_vertex_data* ptcl_vtx_data = (fog_ring_vertex_data*)storage.MapMemory(); + fog_ring_vertex_data* ptcl_vtx_data = (fog_ring_vertex_data*)storage.MapMemory(gl_state); if (!ptcl_vtx_data) { fog_ring->num_vtx = 0; return; @@ -984,13 +1010,14 @@ HOOK(void, FASTCALL, EffectFogRing__calc_vert, 0x000000001403495B0, EffectFogRin ptcl_vtx_data->size = size; } - storage.UnmapMemory(); + storage.UnmapMemory(gl_state); fog_ring->num_vtx = (int32_t)(fog_ring->num_ptcls * 6LL); } -HOOK(void, FASTCALL, EffectFogRing__draw_static, 0x0000000140349940, void* data) { - ((EffectFogRing*)data)->draw(); +HOOK(void, FASTCALL, EffectFogRing__draw_static, 0x0000000140349940, + render_data_context& rend_data_ctx, void* data, const cam_data& cam) { + ((EffectFogRing*)data)->draw(rend_data_ctx, cam); } HOOK(void, FASTCALL, leaf_particle_free, 0x000000014034BB30) { @@ -1051,10 +1078,10 @@ HOOK(void, FASTCALL, leaf_particle_init, 0x000000014034C530, bool change_stage) if (!leaf_ptcl_vao) glGenVertexArrays(1, &leaf_ptcl_vao); - leaf_ptcl_vbo.Create(buffer_size * leaf_ptcl_vtx_count); - leaf_ptcl_vbo.Bind(); + leaf_ptcl_vbo.Create(gl_state, buffer_size * leaf_ptcl_vtx_count); + gl_state.bind_array_buffer(leaf_ptcl_vbo, true); - gl_rend_state.bind_vertex_array(leaf_ptcl_vao); + gl_state.bind_vertex_array(leaf_ptcl_vao); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(leaf_particle_vertex_data, position)); @@ -1065,15 +1092,15 @@ HOOK(void, FASTCALL, leaf_particle_init, 0x000000014034C530, bool change_stage) glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(leaf_particle_vertex_data, normal)); - leaf_ptcl_ebo.Create(sizeof(uint32_t) * ebo_count, ebo_data); - leaf_ptcl_ebo.Bind(); + leaf_ptcl_ebo.Create(gl_state, sizeof(uint32_t) * ebo_count, ebo_data); + gl_state.bind_element_array_buffer(leaf_ptcl_ebo, true); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_element_array_buffer(0); free_def(ebo_data); - leaf_particle_scene_ubo.Create(sizeof(leaf_particle_scene_shader_data)); + leaf_particle_scene_ubo.Create(gl_state, sizeof(leaf_particle_scene_shader_data)); } HOOK(void, FASTCALL, particle_free, 0x0000000140351600) { @@ -1118,10 +1145,10 @@ HOOK(void, FASTCALL, particle_init, 0x0000000140351C50, vec3* offset) { if (!ptcl_vao) glGenVertexArrays(1, &ptcl_vao); - ptcl_vbo.Create(buffer_size * ptcl_vtx_count); - ptcl_vbo.Bind(); + ptcl_vbo.Create(gl_state, buffer_size * ptcl_vtx_count); + gl_state.bind_array_buffer(ptcl_vbo, true); - gl_rend_state.bind_vertex_array(ptcl_vao); + gl_state.bind_vertex_array(ptcl_vao); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(particle_vertex_data, position)); @@ -1135,10 +1162,10 @@ HOOK(void, FASTCALL, particle_init, 0x0000000140351C50, vec3* offset) { glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(particle_vertex_data, normal)); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); - particle_scene_ubo.Create(sizeof(particle_scene_shader_data)); + particle_scene_ubo.Create(gl_state, sizeof(particle_scene_shader_data)); } HOOK(bool, FASTCALL, TaskEffectRain__dest, 0x0000000140353DA0, size_t task_eff_rain) { @@ -1194,12 +1221,12 @@ HOOK(void, FASTCALL, rain_particle_init, 0x00000001403546A0, bool change_stage) { 0, sizeof(vec3), 0, }, { (uint32_t)-1 }, }; - rain_storage.Create(sizeof(vec3), rain_ptcl_count, attribs, vtx_data); + rain_storage.Create(gl_state, sizeof(vec3), rain_ptcl_count, attribs, vtx_data); free_def(vtx_data); - rain_particle_scene_ubo.Create(sizeof(rain_particle_scene_shader_data)); - rain_particle_batch_ubo.Create(sizeof(rain_particle_batch_shader_data)); + rain_particle_scene_ubo.Create(gl_state, sizeof(rain_particle_scene_shader_data)); + rain_particle_batch_ubo.Create(gl_state, sizeof(rain_particle_batch_shader_data)); } HOOK(bool, FASTCALL, TaskEffectRipple__dest, 0x0000000140358600, size_t task_effect_ripple) { @@ -1213,8 +1240,9 @@ HOOK(bool, FASTCALL, TaskEffectRipple__init, 0x00000001403596B0, size_t task_eff return originalTaskEffectRipple__init(task_effect_ripple); } -HOOK(void, FASTCALL, EffectRipple__draw_static, 0x000000014035AA50, void* data) { - ((EffectRipple*)data)->draw(); +HOOK(void, FASTCALL, EffectRipple__draw_static, 0x000000014035AA50, + render_data_context& rend_data_ctx, void* data, const cam_data& cam) { + ((EffectRipple*)data)->draw(rend_data_ctx, cam); } HOOK(void, FASTCALL, EffectRipple__disp_particles, 0x000000014035AD80, @@ -1324,7 +1352,7 @@ HOOK(void, FASTCALL, snow_particle_ctrl, 0x000000014035CA20) { snow_particle_data_kill_fallen(snow_ptcl_fallen, true); } - snow_particle_vertex_data* vtx_data = (snow_particle_vertex_data*)snow_storage.MapMemory(); + snow_particle_vertex_data* vtx_data = (snow_particle_vertex_data*)snow_storage.MapMemory(gl_state); if (vtx_data) { particle_data* snow_ptcl = snow_ptcl_data; for (int32_t i = snow->num_snow; i; i--, snow_ptcl++, vtx_data++) { @@ -1333,9 +1361,10 @@ HOOK(void, FASTCALL, snow_particle_ctrl, 0x000000014035CA20) { vtx_data->alpha = snow_ptcl->alpha; } } - snow_storage.UnmapMemory(); + snow_storage.UnmapMemory(gl_state); - snow_particle_vertex_data* fallen_vtx_data = (snow_particle_vertex_data*)snow_fallen_storage.MapMemory(); + snow_particle_vertex_data* fallen_vtx_data + = (snow_particle_vertex_data*)snow_fallen_storage.MapMemory(gl_state); if (fallen_vtx_data) { particle_data* snow_ptcl_fallen = snow_ptcl_fallen_data; for (size_t i = snow_ptcl_fallen_count; i; i--, snow_ptcl_fallen++, fallen_vtx_data++) { @@ -1344,7 +1373,7 @@ HOOK(void, FASTCALL, snow_particle_ctrl, 0x000000014035CA20) { fallen_vtx_data->alpha = snow_ptcl_fallen->alpha; } } - snow_fallen_storage.UnmapMemory(); + snow_fallen_storage.UnmapMemory(gl_state); } HOOK(void, FASTCALL, snow_particle_init, 0x000000014035DD30, bool change_stage) { @@ -1438,13 +1467,13 @@ HOOK(void, FASTCALL, snow_particle_init, 0x000000014035DD30, bool change_stage) if (change_stage) { snow_storage.Destroy(); - snow_storage.Create(sizeof(snow_particle_vertex_data), snow->num_snow, attribs); + snow_storage.Create(gl_state, sizeof(snow_particle_vertex_data), snow->num_snow, attribs); return; } snow_particle_free(); - snow_storage.Create(sizeof(snow_particle_vertex_data), snow->num_snow, attribs); + snow_storage.Create(gl_state, sizeof(snow_particle_vertex_data), snow->num_snow, attribs); snow_particle_gpu_vertex_data* vtx_data = force_malloc(snow_ptcl_count); @@ -1457,14 +1486,14 @@ HOOK(void, FASTCALL, snow_particle_init, 0x000000014035DD30, bool change_stage) vtx_data -= snow_ptcl_count; - snow_gpu_storage.Create(sizeof(snow_particle_gpu_vertex_data), snow_ptcl_count, gpu_attribs, vtx_data); + snow_gpu_storage.Create(gl_state, sizeof(snow_particle_gpu_vertex_data), snow_ptcl_count, gpu_attribs, vtx_data); free_def(vtx_data); - snow_fallen_storage.Create(sizeof(snow_particle_vertex_data), snow_ptcl_fallen_count, attribs); + snow_fallen_storage.Create(gl_state, sizeof(snow_particle_vertex_data), snow_ptcl_fallen_count, attribs); - snow_particle_scene_ubo.Create(sizeof(snow_particle_scene_shader_data)); - snow_particle_batch_ubo.Create(sizeof(snow_particle_batch_shader_data)); + snow_particle_scene_ubo.Create(gl_state, sizeof(snow_particle_scene_shader_data)); + snow_particle_batch_ubo.Create(gl_state, sizeof(snow_particle_batch_shader_data)); } HOOK(void, FASTCALL, water_particle__free, 0x0000000140363F00, water_particle* water_ptcl) { @@ -1502,7 +1531,7 @@ HOOK(void, FASTCALL, water_particle__disp, 0x0000000140364090, water_particle* w HOOK(void, FASTCALL, water_particle__set, 0x0000000140364F20, water_particle* water_ptcl, splash_particle* splash, int32_t splash_tex_id) { originalwater_particle__set(water_ptcl, splash, splash_tex_id); - + auto elem = water_particle_storage.find(water_ptcl); if (elem == water_particle_storage.end()) { water_particle_storage.push_back({ water_ptcl, {} }); @@ -1518,11 +1547,11 @@ HOOK(void, FASTCALL, water_particle__set, 0x0000000140364F20, { 2, sizeof(water_particle_vertex_data::color ), offsetof(water_particle_vertex_data, color ), }, { (uint32_t)-1 }, }; - elem->second.Create(sizeof(water_particle_vertex_data), water_ptcl->splash_count, attribs); + elem->second.Create(gl_state, sizeof(water_particle_vertex_data), water_ptcl->splash_count, attribs); } HOOK(bool, FASTCALL, TaskEffectSplash__init, 0x00000001403655A0, size_t task_effect_splash) { - water_particle_scene_ubo.Create(sizeof(water_particle_scene_shader_data)); + water_particle_scene_ubo.Create(gl_state, sizeof(water_particle_scene_shader_data)); return originalTaskEffectSplash__init(task_effect_splash); } @@ -1568,35 +1597,36 @@ void effect_patch() { INSTALL_HOOK(star_catalog__init); } -void EffectFogRing::draw() { +void EffectFogRing::draw(render_data_context& rend_data_ctx, const cam_data& cam) { draw_state.set_fog_height(false); if (!enable || !display) return; draw_state.set_fog_height(true); RenderTexture& rt = render_manager.get_render_texture(8); - rt.Bind(); - gl_rend_state.set_viewport(0, 0, + rt.Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, rt.color_texture->get_width_align_mip_level(), rt.color_texture->get_height_align_mip_level()); - glClearColorDLL(density_offset, density_offset, density_offset, 1.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(density_offset, density_offset, density_offset, 1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) - disp_manager->draw(mdl::OBJ_TYPE_USER); - gl_rend_state.bind_framebuffer(0); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_USER, cam); + rend_data_ctx.state.bind_framebuffer(0); render_manager.set_effect_texture(rt.color_texture); gl_get_error_print(); } -static void sub_1403B6F60(texture* a1, texture* a2, texture* a3, EffectRipple::Params& params) { +static void sub_1403B6F60(render_data_context& rend_data_ctx, + texture* a1, texture* a2, texture* a3, EffectRipple::Params& params) { if (!a1 || !a1->glid || !a2 || !a2->glid || !a3 || !a3->glid) return; int32_t width = a2->width; int32_t height = a2->height; - gl_rend_state_rect viewport_rect = gl_rend_state.get_viewport(); - gl_rend_state.set_viewport(1, 1, width - 2, height - 2); + gl_rend_state_rect viewport_rect = rend_data_ctx.state.get_viewport(); + rend_data_ctx.state.set_viewport(1, 1, width - 2, height - 2); ripple_scene_shader_data ripple_scene = {}; ripple_scene.g_transform = { @@ -1604,42 +1634,43 @@ static void sub_1403B6F60(texture* a1, texture* a2, texture* a3, EffectRipple::P (float_t)width / (float_t)(width - 2), (float_t)height / (float_t)(height - 2) }; ripple_scene.g_texcoord = { 1.0f, 0.0f, 0.0f, 0.0f }; - ripple_scene_ubo.WriteMemory(ripple_scene); + ripple_scene_ubo.WriteMemory(rend_data_ctx.state, ripple_scene); ripple_batch_shader_data ripple_batch = {}; ripple_batch.g_params = { params.wake_attn, params.speed, params.field_8, params.field_C }; - ripple_batch_ubo.WriteMemory(ripple_batch); + ripple_batch_ubo.WriteMemory(rend_data_ctx.state, ripple_batch); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.set(SHADER_FT_RIPPLE); - ripple_scene_ubo.Bind(0); - ripple_batch_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, a2->glid); - gl_rend_state.active_bind_texture_2d(1, a3->glid); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.active_bind_texture_2d(1, 0); - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_RIPPLE); + rend_data_ctx.state.bind_uniform_buffer_base(0, ripple_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, ripple_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, a2->glid); + rend_data_ctx.state.active_bind_texture_2d(1, a3->glid); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.active_bind_texture_2d(1, 0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.bind_vertex_array(0); - gl_rend_state.set_viewport(viewport_rect); + rend_data_ctx.state.set_viewport(viewport_rect); } -static void sub_1403B6ED0(RenderTexture* a1, RenderTexture* a2, RenderTexture* a3, EffectRipple::Params& params) { - a1->Bind(); +static void sub_1403B6ED0(render_data_context& rend_data_ctx, RenderTexture* a1, + RenderTexture* a2, RenderTexture* a3, EffectRipple::Params& params) { + a1->Bind(rend_data_ctx.state); if (a1->color_texture->internal_format == GL_RGBA32F || a1->color_texture->internal_format == GL_RGBA16F) - uniform->arr[U_RIPPLE] = 1; + rend_data_ctx.shader_flags.arr[U_RIPPLE] = 1; else - uniform->arr[U_RIPPLE] = 0; - sub_1403B6F60(a1->color_texture, a2->color_texture, a3->color_texture, params); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.shader_flags.arr[U_RIPPLE] = 0; + sub_1403B6F60(rend_data_ctx, a1->color_texture, a2->color_texture, a3->color_texture, params); + rend_data_ctx.state.bind_framebuffer(0); } -void EffectRipple::draw() { +void EffectRipple::draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!stage_set) return; - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_cull_face(); RenderTexture* rt[3]; for (int32_t i = 0, j = 2; i < 3; i++, j++) @@ -1651,24 +1682,24 @@ void EffectRipple::draw() { if (counter >= 3) counter = 0; - rt[(counter + 1) % 3]->Bind(); + rt[(counter + 1) % 3]->Bind(rend_data_ctx.state); - gl_rend_state_rect viewport_rect = gl_rend_state.get_viewport(); + gl_rend_state_rect viewport_rect = rend_data_ctx.state.get_viewport(); int32_t width = rt[0]->GetWidth(); int32_t height = rt[0]->GetHeight(); - gl_rend_state.set_viewport(1, 1, width - 2, height - 2); + rend_data_ctx.state.set_viewport(1, 1, width - 2, height - 2); - draw_pass_set_camera(); - glClearDLL(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.set_batch_scene_camera(cam); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); if (disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) { - gl_rend_state.active_bind_texture_2d(7, rt[counter % 3]->GetColorTex()); - disp_manager->draw(mdl::OBJ_TYPE_USER); - gl_rend_state.active_bind_texture_2d(7, 0); + rend_data_ctx.state.active_bind_texture_2d(7, rt[counter % 3]->GetColorTex()); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_USER, cam); + rend_data_ctx.state.active_bind_texture_2d(7, 0); } - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.bind_framebuffer(0); params.field_8 = 0.0005f; params.field_C = 0.97f; @@ -1677,11 +1708,11 @@ void EffectRipple::draw() { params.field_C = 0.999f; } - sub_1403B6ED0(rt[(counter + 2) % 3], rt[(counter + 1) % 3], rt[counter % 3], params); + sub_1403B6ED0(rend_data_ctx, rt[(counter + 2) % 3], rt[(counter + 1) % 3], rt[counter % 3], params); - gl_rend_state.set_viewport(viewport_rect); + rend_data_ctx.state.set_viewport(viewport_rect); - sub_1403584A0(rt[(counter + 2) % 3]); + sub_1403584A0(rend_data_ctx, rt[(counter + 2) % 3]); this->counter = counter; } @@ -1695,10 +1726,10 @@ void EffectRipple::draw() { update = false; - gl_rend_state.enable_cull_face(); + rend_data_ctx.state.enable_cull_face(); } -void EffectRipple::sub_1403584A0(RenderTexture* rt) { +void EffectRipple::sub_1403584A0(render_data_context& rend_data_ctx, RenderTexture* rt) { if (ripple_tex_id == -1) return; @@ -1707,10 +1738,10 @@ void EffectRipple::sub_1403584A0(RenderTexture* rt) { return; field_BB8.SetColorDepthTextures(ripple_tex->glid); - field_BB8.Bind(); + field_BB8.Bind(rend_data_ctx.state); - image_filter_scale(&field_BB8, rt->color_texture); - gl_rend_state.bind_framebuffer(0); + image_filter_scale(rend_data_ctx, &field_BB8, rt->color_texture); + rend_data_ctx.state.bind_framebuffer(0); } void star_catalog_milky_way::create_buffers(int32_t subdivs, float_t uv_rec_scale_u, float_t uv_rec_scale_v, @@ -1722,9 +1753,9 @@ void star_catalog_milky_way::create_buffers(int32_t subdivs, float_t uv_rec_scal const int32_t vtx_count = (subdivs - 1) * sectors_count + 2; restart_index = (uint16_t)0xFFFFFFFF; - gl_rend_state.bind_vertex_array(0); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_element_array_buffer(0); const float_t rec_longitude_degs_10 = 1.0f / (float_t)longitude_degs_10; const float_t rec_latitude_degs_10 = 1.0f / (float_t)latitude_degs_10; @@ -1799,10 +1830,10 @@ void star_catalog_milky_way::create_buffers(int32_t subdivs, float_t uv_rec_scal if (!vao) glGenVertexArrays(1, &vao); - vbo.Create((size_t)buffer_size * vtx_count, vtx_data); - vbo.Bind(); + vbo.Create(gl_state, (size_t)buffer_size * vtx_count, vtx_data); + gl_state.bind_array_buffer(vbo, true); - gl_rend_state.bind_vertex_array(vao); + gl_state.bind_vertex_array(vao); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(star_catalog_vertex, position)); @@ -1810,12 +1841,12 @@ void star_catalog_milky_way::create_buffers(int32_t subdivs, float_t uv_rec_scal glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(star_catalog_vertex, texcoord)); - ebo.Create(sizeof(uint16_t) * ebo_count, ebo_data); - ebo.Bind(); + ebo.Create(gl_state, sizeof(uint16_t) * ebo_count, ebo_data); + gl_state.bind_element_array_buffer(ebo, true); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_element_array_buffer(0); free_def(vtx_data); free_def(ebo_data); @@ -1847,7 +1878,8 @@ void star_catalog_milky_way::delete_buffers() { } } -void star_catalog_milky_way::draw(const mat4& vp, const mat4& mat, texture* tex, GL::UniformBuffer& scene_ubo) { +void star_catalog_milky_way::draw(render_data_context& rend_data_ctx, + const mat4& vp, const mat4& mat, texture* tex, GL::UniformBuffer& scene_ubo) { if (!vao) return; @@ -1889,34 +1921,32 @@ void star_catalog_milky_way::draw(const mat4& vp, const mat4& mat, texture* tex, scene_shader_data.g_transform[1] = temp.row1; scene_shader_data.g_transform[2] = temp.row2; scene_shader_data.g_transform[3] = temp.row3; - scene_ubo.WriteMemory(scene_shader_data); + scene_ubo.WriteMemory(rend_data_ctx.state, scene_shader_data); - gl_rend_state.enable_cull_face(); - gl_rend_state.disable_blend(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.active_bind_texture_2d(0, tex->glid); - gl_rend_state.bind_sampler(0, star_sampler); - gl_rend_state.enable_primitive_restart(); - gl_rend_state.set_primitive_restart_index(restart_index); - uniform->arr[U_STAR] = 1; - shaders_ft.set(SHADER_FT_STAR); - - gl_rend_state.bind_vertex_array(vao); - scene_ubo.Bind(0); - shaders_ft.draw_elements(GL_TRIANGLE_STRIP, idx_count, GL_UNSIGNED_SHORT, 0); - gl_rend_state.bind_vertex_array(0); - - gl_rend_state.bind_sampler(0, 0); - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.disable_primitive_restart(); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.enable_blend(); - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); + rend_data_ctx.state.bind_sampler(0, star_sampler); + rend_data_ctx.state.enable_primitive_restart(); + rend_data_ctx.state.set_primitive_restart_index(restart_index); + rend_data_ctx.shader_flags.arr[U_STAR] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_STAR); + rend_data_ctx.state.bind_vertex_array(vao); + rend_data_ctx.state.bind_uniform_buffer_base(0, scene_ubo); + rend_data_ctx.state.draw_elements(GL_TRIANGLE_STRIP, idx_count, GL_UNSIGNED_SHORT, 0); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.bind_sampler(0, 0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.disable_primitive_restart(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); } -void star_catalog::draw() { +void star_catalog::draw(render_data_context& rend_data_ctx, const cam_data& cam) { if (!stage_param_data_ptr || !enable) return; @@ -1932,23 +1962,23 @@ void star_catalog::draw() { stage_param_data.utc, stage_param_data.rotation_y_deg * DEG_TO_RAD_FLOAT); - const mat4& view = rctx->view_mat; + const mat4& view = cam.view_mat; model.row3.x = vec3::dot(-*(vec3*)&view.row0, *(vec3*)&view.row3) + model.row3.x; model.row3.y = vec3::dot(-*(vec3*)&view.row1, *(vec3*)&view.row3) + model.row3.y; model.row3.z = vec3::dot(-*(vec3*)&view.row2, *(vec3*)&view.row3) + model.row3.z; - mat4 proj = rctx->proj_mat; + mat4 proj = cam.proj_mat; proj.row0.z = proj.row0.w; proj.row1.z = proj.row1.w; proj.row2.z = proj.row2.w; proj.row3.z = proj.row3.w; mat4 vp; - mat4_mul(&rctx->view_mat, &proj, &vp); + mat4_mul(&cam.view_mat, &proj, &vp); texture* milky_way_tex = texture_manager_get_texture(milky_way_tex_id); if (milky_way_tex) - milky_way.draw(vp, model, milky_way_tex, stars_scene_ubo); + milky_way.draw(rend_data_ctx, vp, model, milky_way_tex, stars_scene_ubo); star_catalog_scene_shader_data scene_shader_data = {}; mat4 temp; @@ -1958,15 +1988,15 @@ void star_catalog::draw() { scene_shader_data.g_transform[1] = temp.row1; scene_shader_data.g_transform[2] = temp.row2; scene_shader_data.g_transform[3] = temp.row3; - stars_scene_ubo.WriteMemory(scene_shader_data); + stars_scene_ubo.WriteMemory(rend_data_ctx.state, scene_shader_data); - uniform->arr[U_STAR] = 0; - shaders_ft.set(SHADER_FT_STAR); - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_ONE, GL_ONE); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(false); - gl_rend_state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.shader_flags.arr[U_STAR] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_STAR); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ONE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(false); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); for (int32_t i = 0; i < 2; i++) { stage_param_data_star_modifiers& modifiers = stage_param_data.modifiers[i]; @@ -1979,22 +2009,22 @@ void star_catalog::draw() { modifiers.pos_scale, modifiers.pos_scale * modifiers.offset_scale }; batch_shader_data.g_thresholds = { modifiers.threshold * modifiers.pos_scale, 0.0f, 0.0f, 0.0f }; - stars_batch_ubo.WriteMemory(batch_shader_data); + stars_batch_ubo.WriteMemory(rend_data_ctx.state, batch_shader_data); - stars_scene_ubo.Bind(0); - stars_batch_ubo.Bind(1); - stars_storage.Bind(0); + rend_data_ctx.state.bind_uniform_buffer_base(0, stars_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, stars_batch_ubo); + stars_storage.Bind(rend_data_ctx.state, 0); if (i) { - gl_rend_state.active_bind_texture_2d(0, star_b_tex->glid); + rend_data_ctx.state.active_bind_texture_2d(0, star_b_tex->glid); stars_storage.Draw(GL_TRIANGLES, 0, star_b_count * 6); } else { - gl_rend_state.active_bind_texture_2d(0, star_tex->glid); + rend_data_ctx.state.active_bind_texture_2d(0, star_tex->glid); stars_storage.Draw(GL_TRIANGLES, 0, star_count * 6); } } - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.bind_vertex_array(0); } @@ -2081,17 +2111,17 @@ bool star_catalog::init() { { 2, sizeof(stars_buffer_data::color ), offsetof(stars_buffer_data, color ), }, { (uint32_t)-1 }, }; - stars_storage.Create(sizeof(stars_buffer_data), vec.size(), attribs, vec.data()); + stars_storage.Create(gl_state, sizeof(stars_buffer_data), vec.size(), attribs, vec.data()); } milky_way.create_default_sphere(); - stars_scene_ubo.Create(sizeof(star_catalog_scene_shader_data)); - stars_batch_ubo.Create(sizeof(star_catalog_batch_shader_data)); + stars_scene_ubo.Create(gl_state, sizeof(star_catalog_scene_shader_data)); + stars_batch_ubo.Create(gl_state, sizeof(star_catalog_batch_shader_data)); return true; } -void water_particle::draw(mat4* mat) { +void water_particle::draw(render_data_context& rend_data_ctx, const cam_data& cam, mat4* mat) { if (count <= 0) return; @@ -2101,7 +2131,7 @@ void water_particle::draw(mat4* mat) { EffectStorage& storage = elem->second; - water_particle_vertex_data* vtx_data = (water_particle_vertex_data*)storage.MapMemory(); + water_particle_vertex_data* vtx_data = (water_particle_vertex_data*)storage.MapMemory(rend_data_ctx.state); if (!vtx_data) return; @@ -2111,18 +2141,18 @@ void water_particle::draw(mat4* mat) { vtx_data->color = ptcl_data->color; vtx_data->size = ptcl_data->size; } - storage.UnmapMemory(); + storage.UnmapMemory(rend_data_ctx.state); water_particle_scene_shader_data scene_shader_data = {}; mat4 temp; - mat4_mul(mat, &rctx->vp_mat, &temp); + mat4_mul(mat, &cam.view_proj_mat, &temp); mat4_transpose(&temp, &temp); scene_shader_data.g_transform[0] = temp.row0; scene_shader_data.g_transform[1] = temp.row1; scene_shader_data.g_transform[2] = temp.row2; scene_shader_data.g_transform[3] = temp.row3; - mat4_mul(mat, &rctx->view_mat, &temp); + mat4_mul(mat, &cam.view_mat, &temp); mat4_transpose(&temp, &temp); scene_shader_data.g_view_world_row2 = temp.row2; @@ -2131,22 +2161,22 @@ void water_particle::draw(mat4* mat) { scene_shader_data.g_size_in_projection.y = (float_t)(1.0 / 720.0); scene_shader_data.g_size_in_projection.z = 1.0; scene_shader_data.g_size_in_projection.w = 60.0; - water_particle_scene_ubo.WriteMemory(scene_shader_data); + water_particle_scene_ubo.WriteMemory(rend_data_ctx.state, scene_shader_data); - gl_rend_state.disable_cull_face(); - shaders_ft.set(SHADER_FT_W_PTCL); + rend_data_ctx.state.disable_cull_face(); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_W_PTCL); - gl_rend_state.bind_vertex_array(rctx->common_vao); - water_particle_scene_ubo.Bind(0); - storage.Bind(0); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.bind_uniform_buffer_base(0, water_particle_scene_ubo); + storage.Bind(rend_data_ctx.state, 0); texture* tex = texture_manager_get_texture(splash_tex_id); if (tex) - gl_rend_state.active_bind_texture_2d(0, tex->glid); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); storage.Draw(GL_TRIANGLES, 0, count * 6); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.bind_vertex_array(0); - shader::unbind(); - gl_rend_state.enable_cull_face(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.enable_cull_face(); } static void TaskEffectAuth3D__SetVisibility(size_t This, bool value) { @@ -2172,7 +2202,8 @@ static void TaskEffectAuth3D__SetVisibility(size_t This, bool value) { } } -static void draw_fog_particle(EffectFogRing* data, mat4* mat) { +static void draw_fog_particle(render_data_context& rend_data_ctx, + EffectFogRing* data, const cam_data& cam, mat4* mat) { if (!data->num_vtx) return; @@ -2182,24 +2213,25 @@ static void draw_fog_particle(EffectFogRing* data, mat4* mat) { EffectStorage& storage = elem->second; - shaders_ft.set(SHADER_FT_FOGPTCL); - gl_rend_state.enable_blend(); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_FOGPTCL); + rend_data_ctx.state.enable_blend(); texture* tex = texture_manager_get_texture(data->tex_id); if (tex) - gl_rend_state.active_bind_texture_2d(0, tex->glid); - gl_rend_state.bind_vertex_array(rctx->common_vao); - storage.Bind(0); + rend_data_ctx.state.active_bind_texture_2d(0, tex->glid); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + storage.Bind(rend_data_ctx.state, 0); storage.Draw(GL_TRIANGLES, 0, data->num_vtx); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.disable_blend(); - shader::unbind(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.disable_blend(); + shader::unbind(rend_data_ctx.state); } -static void draw_ripple_particles(ripple_struct* data, mat4* mat) { +static void draw_ripple_particles(render_data_context& rend_data_ctx, + ripple_struct* data, const cam_data& cam, mat4* mat) { if (data->count > 5000) return; - vec3* vtx_data = (vec3*)ripple_emit_storage.MapMemory(); + vec3* vtx_data = (vec3*)ripple_emit_storage.MapMemory(rend_data_ctx.state); if (!vtx_data) return; @@ -2209,7 +2241,7 @@ static void draw_ripple_particles(ripple_struct* data, mat4* mat) { for (size_t i = data->count; i; i--, vtx_data++, position++, color++) *vtx_data = { position->x, -position->z, (float_t)color->a * (float_t)(1.0 / 255.0) }; - ripple_emit_storage.UnmapMemory(); + ripple_emit_storage.UnmapMemory(rend_data_ctx.state); int32_t size = (int32_t)(data->size + 0.5f); @@ -2232,29 +2264,30 @@ static void draw_ripple_particles(ripple_struct* data, mat4* mat) { 1.0f / (float_t)width, 1.0f / (float_t)height, 0.0f, 0.0f }; - ripple_emit_scene_ubo.WriteMemory(shader_data); + ripple_emit_scene_ubo.WriteMemory(rend_data_ctx.state, shader_data); - uniform->arr[U_RIPPLE] = data->ripple_uniform; - uniform->arr[U_RIPPLE_EMIT] = data->ripple_emit_uniform; + rend_data_ctx.shader_flags.arr[U_RIPPLE] = data->ripple_uniform; + rend_data_ctx.shader_flags.arr[U_RIPPLE_EMIT] = data->ripple_emit_uniform; - gl_rend_state.begin_event("EffectRipple::Impl::draw_ripple_particles"); - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - gl_rend_state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.begin_event("EffectRipple::Impl::draw_ripple_particles"); + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); - shaders_ft.set(SHADER_FT_RIPEMIT); - ripple_emit_scene_ubo.Bind(0); - ripple_emit_storage.Bind(0); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_RIPEMIT); + rend_data_ctx.state.bind_uniform_buffer_base(0, ripple_emit_scene_ubo); + ripple_emit_storage.Bind(rend_data_ctx.state, 0); ripple_emit_storage.Draw(GL_TRIANGLES, 0, data->count * 6); - shader::unbind(); + shader::unbind(rend_data_ctx.state); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.end_event(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.end_event(); } -static void draw_water_particle(water_particle* data, mat4* mat) { - data->draw(mat); +static void draw_water_particle(render_data_context& rend_data_ctx, + water_particle* data, const cam_data& cam, mat4* mat) { + data->draw(rend_data_ctx, cam, mat); } static std::pair sub_1406427A0(vec3 x, vec3 y) { @@ -2267,7 +2300,7 @@ static std::pair sub_1406427A0(vec3 x, vec3 y) { return { t3 * x, t3 * t1 }; } -static int32_t leaf_particle_disp() { +static int32_t leaf_particle_disp(render_data_context& rend_data_ctx) { float_t size = leaf_ptcl_data[0].size; vec3 position[4]; @@ -2281,7 +2314,7 @@ static int32_t leaf_particle_disp() { normal[2] = sub_1406427A0(vec3(-0.2f, -0.2f, 1.0f), vec3(0.0f, 1.0f, 0.0f)).first; normal[3] = sub_1406427A0(vec3( 0.4f, -0.4f, 1.0f), vec3(0.0f, 1.0f, 0.0f)).first; - leaf_particle_vertex_data* vtx_data = (leaf_particle_vertex_data*)leaf_ptcl_vbo.MapMemory(); + leaf_particle_vertex_data* vtx_data = (leaf_particle_vertex_data*)leaf_ptcl_vbo.MapMemory(rend_data_ctx.state); if (!vtx_data) return 0; @@ -2359,7 +2392,7 @@ static int32_t leaf_particle_disp() { } } - leaf_ptcl_vbo.UnmapMemory(); + leaf_ptcl_vbo.UnmapMemory(rend_data_ctx.state); return vtx_count; } @@ -2431,16 +2464,16 @@ static void rain_particle_free() { } static void ripple_emit_init() { - ripple_batch_ubo.Create(sizeof(ripple_batch_shader_data)); - ripple_scene_ubo.Create(sizeof(ripple_scene_shader_data)); + ripple_batch_ubo.Create(gl_state, sizeof(ripple_batch_shader_data)); + ripple_scene_ubo.Create(gl_state, sizeof(ripple_scene_shader_data)); static const EffectStorageAttrib attribs[] = { { 0, sizeof(vec3), 0, }, { (uint32_t)-1 }, }; - ripple_emit_storage.Create(sizeof(vec3), ripple_emit_count, attribs); + ripple_emit_storage.Create(gl_state, sizeof(vec3), ripple_emit_count, attribs); - ripple_emit_scene_ubo.Create(sizeof(ripple_emit_scene_shader_data)); + ripple_emit_scene_ubo.Create(gl_state, sizeof(ripple_emit_scene_shader_data)); } static void ripple_emit_free() { diff --git a/src/DivaGL/effect.hpp b/src/DivaGL/effect.hpp index 25377b2..2d7d73d 100644 --- a/src/DivaGL/effect.hpp +++ b/src/DivaGL/effect.hpp @@ -43,10 +43,10 @@ struct particle_init_data { float_t scale_y; }; -extern void leaf_particle_draw(); -extern void rain_particle_draw(); -extern void particle_draw(); -extern void snow_particle_draw(); -extern void star_catalog_draw(); +extern void leaf_particle_draw(struct render_data_context& rend_data_ctx, const struct cam_data& cam); +extern void rain_particle_draw(struct render_data_context& rend_data_ctx, const struct cam_data& cam); +extern void particle_draw(struct render_data_context& rend_data_ctx, const struct cam_data& cam); +extern void snow_particle_draw(struct render_data_context& rend_data_ctx, const struct cam_data& cam); +extern void star_catalog_draw(struct render_data_context& rend_data_ctx, const struct cam_data& cam); extern void effect_patch(); diff --git a/src/DivaGL/gl_rend_state.cpp b/src/DivaGL/gl_rend_state.cpp index 9726502..e0f44ab 100644 --- a/src/DivaGL/gl_rend_state.cpp +++ b/src/DivaGL/gl_rend_state.cpp @@ -4,320 +4,1036 @@ */ #include "gl_rend_state.hpp" -#include "wrap.hpp" +#include "shared.hpp" -gl_rend_state_struct gl_rend_state; +enum gl_rend_state_update_flags : uint32_t { + GL_REND_STATE_UPDATE_PROGRAM = 1u << 0, + GL_REND_STATE_UPDATE_TEXTURE = 1u << 1, + GL_REND_STATE_UPDATE_ACTIVE_TEXTURE = 1u << 2, + GL_REND_STATE_UPDATE_SAMPLER = 1u << 3, + GL_REND_STATE_UPDATE_BLEND = 1u << 4, + GL_REND_STATE_UPDATE_BLEND_FUNC = 1u << 5, + GL_REND_STATE_UPDATE_BLEND_EQUATION = 1u << 6, + GL_REND_STATE_UPDATE_READ_FRAMEBUFFER = 1u << 7, + GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER = 1u << 8, + GL_REND_STATE_UPDATE_VERTEX_ARRAY = 1u << 9, + GL_REND_STATE_UPDATE_UNIFORM_BUFFER = 1u << 10, + GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER = 1u << 11, + GL_REND_STATE_UPDATE_COLOR_MASK = 1u << 12, + GL_REND_STATE_UPDATE_CULL_FACE = 1u << 13, + GL_REND_STATE_UPDATE_CULL_FACE_MODE = 1u << 14, + GL_REND_STATE_UPDATE_DEPTH_TEST = 1u << 15, + GL_REND_STATE_UPDATE_DEPTH_MASK = 1u << 16, + GL_REND_STATE_UPDATE_DEPTH_FUNC = 1u << 17, + GL_REND_STATE_UPDATE_LINE_WIDTH = 1u << 18, + GL_REND_STATE_UPDATE_MULTISAMPLE = 1u << 19, + GL_REND_STATE_UPDATE_PRIMITIVE_RESTART = 1u << 20, + GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX = 1u << 21, + GL_REND_STATE_UPDATE_SCISSOR_TEST = 1u << 22, + GL_REND_STATE_UPDATE_SCISSOR = 1u << 23, + GL_REND_STATE_UPDATE_STENCIL_TEST = 1u << 24, + GL_REND_STATE_UPDATE_STENCIL_MASK = 1u << 25, + GL_REND_STATE_UPDATE_STENCIL_FUNC = 1u << 26, + GL_REND_STATE_UPDATE_STENCIL_OP = 1u << 27, + GL_REND_STATE_UPDATE_VIEWPORT = 1u << 28, + GL_REND_STATE_UPDATE_CLEAR_COLOR = 1u << 29, + GL_REND_STATE_UPDATE_CLEAR_DEPTH = 1u << 30, + GL_REND_STATE_UPDATE_CLEAR_STENCIL = 1u << 31, +}; + +enum gl_rend_state_flags { + GL_REND_STATE_EXECUTE = 1u << 0, +}; + +struct gl_rend_state { + gl_rend_state_index index; + + GLuint curr_program; + GLuint program; + + GLuint curr_active_texture_index; + GLuint active_texture_index; + + int32_t texture_binding_start_index; + int32_t texture_binding_end_index; + GLuint curr_texture_binding_2d[32]; + GLuint texture_binding_2d[32]; + GLuint curr_texture_binding_cube_map[32]; + GLuint texture_binding_cube_map[32]; + + int32_t sampler_binding_start_index; + int32_t sampler_binding_end_index; + GLuint curr_sampler_binding[32]; + GLuint sampler_binding[32]; + + GLboolean curr_blend; + GLboolean blend; + GLenum curr_blend_src_rgb; + GLenum blend_src_rgb; + GLenum curr_blend_src_alpha; + GLenum blend_src_alpha; + GLenum curr_blend_dst_rgb; + GLenum blend_dst_rgb; + GLenum curr_blend_dst_alpha; + GLenum blend_dst_alpha; + GLenum curr_blend_mode_rgb; + GLenum blend_mode_rgb; + GLenum curr_blend_mode_alpha; + GLenum blend_mode_alpha; + + GLuint curr_read_framebuffer_binding; + GLuint read_framebuffer_binding; + GLuint curr_draw_framebuffer_binding; + GLuint draw_framebuffer_binding; + + GLuint curr_vertex_array_binding; + GLuint vertex_array_binding; + + GLuint array_buffer_binding; + GLuint element_array_buffer_binding; + + GLuint uniform_buffer_binding; + + int32_t uniform_buffer_start_index; + int32_t uniform_buffer_end_index; + GLuint curr_uniform_buffer_bindings[14]; + GLuint uniform_buffer_bindings[14]; + GLintptr curr_uniform_buffer_offsets[14]; + GLintptr uniform_buffer_offsets[14]; + GLsizeiptr curr_uniform_buffer_sizes[14]; + GLsizeiptr uniform_buffer_sizes[14]; + + GLuint shader_storage_buffer_binding; + + int32_t shader_storage_buffer_start_index; + int32_t shader_storage_buffer_end_index; + GLuint curr_shader_storage_buffer_bindings[14]; + GLuint shader_storage_buffer_bindings[14]; + GLintptr curr_shader_storage_buffer_offsets[14]; + GLintptr shader_storage_buffer_offsets[14]; + GLsizeiptr curr_shader_storage_buffer_sizes[14]; + GLsizeiptr shader_storage_buffer_sizes[14]; + + GLboolean curr_color_mask[4]; + GLboolean color_mask[4]; + + GLboolean curr_cull_face; + GLboolean cull_face; + GLenum curr_cull_face_mode; + GLenum cull_face_mode; + + GLboolean curr_depth_test; + GLboolean depth_test; + GLenum curr_depth_func; + GLenum depth_func; + GLboolean curr_depth_mask; + GLboolean depth_mask; + + GLfloat curr_line_width; + GLfloat line_width; + + GLboolean curr_multisample; + GLboolean multisample; + + GLboolean curr_primitive_restart; + GLboolean primitive_restart; + GLuint curr_primitive_restart_index; + GLuint primitive_restart_index; + + gl_rend_state_rect curr_scissor_box; + gl_rend_state_rect scissor_box; + GLboolean curr_scissor_test; + GLboolean scissor_test; + + GLboolean curr_stencil_test; + GLboolean stencil_test; + GLenum curr_stencil_func; + GLenum stencil_func; + GLenum curr_stencil_fail; + GLenum stencil_fail; + GLenum curr_stencil_dpfail; + GLenum stencil_dpfail; + GLenum curr_stencil_dppass; + GLenum stencil_dppass; + GLuint curr_stencil_mask; + GLuint stencil_mask; + GLint curr_stencil_ref; + GLint stencil_ref; + GLuint curr_stencil_value_mask; + GLuint stencil_value_mask; + + gl_rend_state_rect curr_viewport; + gl_rend_state_rect viewport; + + GLfloat curr_clear_color_value[4]; + GLfloat clear_color_value[4]; + + GLfloat curr_clear_depth_value; + GLfloat clear_depth_value; + + GLint curr_clear_stencil_value; + GLint clear_stencil_value; + + gl_rend_state_flags flags; + gl_rend_state_update_flags update_flags; + + void active_bind_texture_2d(int32_t index, GLuint texture); + void active_bind_texture_cube_map(int32_t index, GLuint texture); + void active_texture(int32_t index); + void begin_event(const char* message, int32_t length); + void bind_framebuffer(GLuint framebuffer); + void bind_read_framebuffer(GLuint framebuffer); + void bind_draw_framebuffer(GLuint framebuffer); + void bind_vertex_array(GLuint array); + void bind_array_buffer(GLuint buffer); + void bind_element_array_buffer(GLuint buffer); + void bind_uniform_buffer(GLuint buffer); + void bind_uniform_buffer_base(GLuint index, GLuint buffer); + void bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_shader_storage_buffer(GLuint buffer); + void bind_shader_storage_buffer_base(GLuint index, GLuint buffer); + void bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_texture_2d(GLuint texture); + void bind_texture_cube_map(GLuint texture); + void bind_sampler(int32_t index, GLuint sampler); + void blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLenum check_framebuffer_status(GLenum target); + void clear(GLbitfield mask); + void clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void clear_depth(GLfloat depth); + void clear_stencil(GLint stencil); + void copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + void copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void disable_blend(); + void disable_cull_face(); + void disable_depth_test(); + void disable_multisample(); + void disable_primitive_restart(); + void disable_scissor_test(); + void disable_stencil_test(); + void draw_arrays(GLenum mode, GLint first, GLsizei count); + void draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices); + void draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); + void enable_blend(); + void enable_cull_face(); + void enable_depth_test(); + void enable_multisample(); + void enable_primitive_restart(); + void enable_scissor_test(); + void enable_stencil_test(); + void end_event(); + void generate_mipmap(GLenum target); + void generate_texture_mipmap(GLuint texture); + void get(); + void get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha); + GLuint get_program(); + gl_rend_state_rect get_scissor(); + void get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height); + gl_rend_state_rect get_viewport(); + void get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height); + void set_blend_func(GLenum src, GLenum dst); + void set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha); + void set_blend_equation(GLenum mode); + void set_blend_equation_separate( + GLenum mode_rgb, GLenum mode_alpha); + void set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void set_cull_face_mode(GLenum mode); + void set_depth_func(GLenum func); + void set_depth_mask(GLboolean flag); + void set_line_width(GLfloat width); + void set_primitive_restart_index(GLuint index); + void set_scissor(const gl_rend_state_rect& rect); + void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height); + void set_stencil_func(GLenum func, GLint ref, GLuint mask); + void set_stencil_mask(GLuint mask); + void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass); + void set_viewport(const gl_rend_state_rect& rect); + void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height); + void update(); + void update_program(); + void update_active_texture(); + void update_curr_active_texture(); + void update_texture(); + void update_sampler(); + void update_blend(); + void update_blend_func(); + void update_blend_equation(); + void update_read_framebuffer(); + void update_draw_framebuffer(); + void update_vertex_array(); + void update_uniform_buffer(); + void update_shader_storage_buffer(); + void update_color_mask(); + void update_cull_face(); + void update_cull_face_mode(); + void update_depth_test(); + void update_depth_mask(); + void update_depth_func(); + void update_line_width(); + void update_multisample(); + void update_primitive_restart(); + void update_primitive_restart_index(); + void update_scissor_test(); + void update_scissor(); + void update_stencil_test(); + void update_stencil_mask(); + void update_stencil_func(); + void update_stencil_op(); + void update_viewport(); + void update_clear_color(); + void update_clear_depth(); + void update_clear_stencil(); + void use_program(GLuint program); +}; + +gl_rend_state gl_rend_state_data[GL_REND_STATE_COUNT] = { + { GL_REND_STATE_PRE_3D }, + { GL_REND_STATE_3D }, + { GL_REND_STATE_2D }, + { GL_REND_STATE_POST_2D }, +}; + +p_gl_rend_state::p_gl_rend_state(gl_rend_state_index index) : ptr(gl_rend_state_data[index]) { -void gl_rend_state_struct::active_bind_texture_2d(int32_t index, GLuint texture, bool force) { - if (force || texture_binding_2d[index] != texture) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } - glBindTextureDLL(GL_TEXTURE_2D, texture); - texture_binding_2d[index] = texture; - } } -void gl_rend_state_struct::active_bind_texture_cube_map(int32_t index, GLuint texture, bool force) { - if (force || texture_binding_cube_map[index] != texture) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } - glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture); - texture_binding_cube_map[index] = texture; - } +void p_gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) { + ptr.active_bind_texture_2d(index, texture); } -void gl_rend_state_struct::active_texture(size_t index, bool force) { - if (force || active_texture_index != index) { - glActiveTexture((GLenum)(GL_TEXTURE0 + index)); - active_texture_index = (GLuint)index; - } +void p_gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) { + ptr.active_bind_texture_cube_map(index, texture); } -void gl_rend_state_struct::bind_framebuffer(GLuint framebuffer, bool force) { - if (force || framebuffer_binding != framebuffer - || read_framebuffer_binding != framebuffer - || draw_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - framebuffer_binding = framebuffer; - read_framebuffer_binding = framebuffer; - draw_framebuffer_binding = framebuffer; - } +void p_gl_rend_state::active_texture(int32_t index) { + ptr.active_texture(index); } -void gl_rend_state_struct::bind_read_framebuffer(GLuint framebuffer, bool force) { - if (force || read_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); - read_framebuffer_binding = framebuffer; - } +void p_gl_rend_state::begin_event(const char* message, int32_t length) { + ptr.begin_event(message, length); } -void gl_rend_state_struct::bind_draw_framebuffer(GLuint framebuffer, bool force) { - if (force || draw_framebuffer_binding != framebuffer) { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); - draw_framebuffer_binding = framebuffer; - } +void p_gl_rend_state::bind_framebuffer(GLuint framebuffer) { + ptr.bind_framebuffer(framebuffer); } -void gl_rend_state_struct::bind_vertex_array(GLuint array, bool force) { - if (force || vertex_array_binding != array) { - glBindVertexArray(array); - vertex_array_binding = array; - } +void p_gl_rend_state::bind_read_framebuffer(GLuint framebuffer) { + ptr.bind_read_framebuffer(framebuffer); } -void gl_rend_state_struct::bind_array_buffer(GLuint buffer, bool force) { - if (force || array_buffer_binding != buffer) { +void p_gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) { + ptr.bind_draw_framebuffer(framebuffer); +} + +void p_gl_rend_state::bind_vertex_array(GLuint array) { + ptr.bind_vertex_array(array); +} + +void p_gl_rend_state::bind_array_buffer(GLuint buffer) { + ptr.bind_array_buffer(buffer); +} + +void p_gl_rend_state::bind_element_array_buffer(GLuint buffer) { + ptr.bind_element_array_buffer(buffer); +} + +void p_gl_rend_state::bind_uniform_buffer(GLuint buffer) { + ptr.bind_uniform_buffer(buffer); +} + +void p_gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) { + ptr.bind_uniform_buffer_base(index, buffer); +} + +void p_gl_rend_state::bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + ptr.bind_uniform_buffer_range(index, buffer, offset, size); +} + +void p_gl_rend_state::bind_shader_storage_buffer(GLuint buffer) { + ptr.bind_shader_storage_buffer(buffer); +} + +void p_gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) { + ptr.bind_shader_storage_buffer_base(index, buffer); +} + +void p_gl_rend_state::bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + ptr.bind_shader_storage_buffer_range(index, buffer, offset, size); +} + +void p_gl_rend_state::bind_texture_2d(GLuint texture) { + ptr.bind_texture_2d(texture); +} + +void p_gl_rend_state::bind_texture_cube_map(GLuint texture) { + ptr.bind_texture_cube_map(texture); +} + +void p_gl_rend_state::bind_sampler(int32_t index, GLuint sampler) { + ptr.bind_sampler(index, sampler); +} + +void p_gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + ptr.blit_framebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +GLenum p_gl_rend_state::check_framebuffer_status(GLenum target) { + return ptr.check_framebuffer_status(target); +} + +void p_gl_rend_state::clear(GLbitfield mask) { + ptr.clear(mask); +} + +void p_gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + ptr.clear_buffer(buffer, drawbuffer, value); +} + +void p_gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + ptr.clear_color(red, green, blue, alpha); +} + +void p_gl_rend_state::clear_depth(GLfloat depth) { + ptr.clear_depth(depth); +} + +void p_gl_rend_state::clear_stencil(GLint stencil) { + ptr.clear_stencil(stencil); +} + +void p_gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { + ptr.copy_image_sub_data(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, + dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); +} + +void p_gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height); +} + +void p_gl_rend_state::disable_blend() { + ptr.disable_blend(); +} + +void p_gl_rend_state::disable_cull_face() { + ptr.disable_cull_face(); +} + +void p_gl_rend_state::disable_depth_test() { + ptr.disable_depth_test(); +} + +void p_gl_rend_state::disable_multisample() { + ptr.disable_multisample(); +} + +void p_gl_rend_state::disable_primitive_restart() { + ptr.disable_primitive_restart(); +} + +void p_gl_rend_state::disable_scissor_test() { + ptr.disable_scissor_test(); +} + +void p_gl_rend_state::disable_stencil_test() { + ptr.disable_stencil_test(); +} + +void p_gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) { + ptr.draw_arrays(mode, first, count); +} + +void p_gl_rend_state::draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices) { + ptr.draw_elements(mode, count, type, indices); +} + +void p_gl_rend_state::draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { + ptr.draw_range_elements(mode, start, end, count, type, indices); +} + +void p_gl_rend_state::enable_blend() { + ptr.enable_blend(); +} + +void p_gl_rend_state::enable_cull_face() { + ptr.enable_cull_face(); +} + +void p_gl_rend_state::enable_depth_test() { + ptr.enable_depth_test(); +} + +void p_gl_rend_state::enable_multisample() { + ptr.enable_multisample(); +} + +void p_gl_rend_state::enable_primitive_restart() { + ptr.enable_primitive_restart(); +} + +void p_gl_rend_state::enable_scissor_test() { + ptr.enable_scissor_test(); +} + +void p_gl_rend_state::enable_stencil_test() { + ptr.enable_stencil_test(); +} + +void p_gl_rend_state::end_event() { + ptr.end_event(); +} + +void p_gl_rend_state::generate_mipmap(GLenum target) { + ptr.generate_mipmap(target); +} + +void p_gl_rend_state::generate_texture_mipmap(GLuint texture) { + ptr.generate_texture_mipmap(texture); +} + +void p_gl_rend_state::get() { + ptr.get(); +} + +void p_gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) { + ptr.get_clear_color(red, green, blue, alpha); +} + +GLuint p_gl_rend_state::get_program() { + return ptr.get_program(); +} + +gl_rend_state_rect p_gl_rend_state::get_scissor() { + return ptr.get_scissor(); +} + +void p_gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { + ptr.get_scissor(x, y, width, height); +} + +gl_rend_state_rect p_gl_rend_state::get_viewport() { + return ptr.get_viewport(); +} + +void p_gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { + ptr.get_viewport(x, y, width, height); +} + +void p_gl_rend_state::set_blend_func(GLenum src, GLenum dst) { + ptr.set_blend_func(src, dst); +} + +void p_gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha) { + ptr.set_blend_func_separate(src_rgb, dst_rgb, src_alpha, dst_alpha); +} + +void p_gl_rend_state::set_blend_equation(GLenum mode) { + ptr.set_blend_equation(mode); +} + +void p_gl_rend_state::set_blend_equation_separate( + GLenum mode_rgb, GLenum mode_alpha) { + ptr.set_blend_equation_separate(mode_rgb, mode_alpha); +} + +void p_gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + ptr.set_color_mask(red, green, blue, alpha); +} + +void p_gl_rend_state::set_cull_face_mode(GLenum mode) { + ptr.set_cull_face_mode(mode); +} + +void p_gl_rend_state::set_depth_func(GLenum func) { + ptr.set_depth_func(func); +} + +void p_gl_rend_state::set_depth_mask(GLboolean flag) { + ptr.set_depth_mask(flag); +} + +void p_gl_rend_state::set_line_width(GLfloat width) { + ptr.set_line_width(width); +} + +void p_gl_rend_state::set_primitive_restart_index(GLuint index) { + ptr.set_primitive_restart_index(index); +} + +void p_gl_rend_state::set_scissor(const gl_rend_state_rect& rect) { + ptr.set_scissor(rect); +} + +void p_gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.set_scissor(x, y, width, height); +} + +void p_gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) { + ptr.set_stencil_func(func, ref, mask); +} + +void p_gl_rend_state::set_stencil_mask(GLuint mask) { + ptr.set_stencil_mask(mask); +} + +void p_gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) { + ptr.set_stencil_op(sfail, dpfail, dppass); +} + +void p_gl_rend_state::set_viewport(const gl_rend_state_rect& rect) { + ptr.set_viewport(rect); +} + +void p_gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + ptr.set_viewport(x, y, width, height); +} + +void p_gl_rend_state::update() { + ptr.update(); +} + +void p_gl_rend_state::use_program(GLuint program) { + ptr.use_program(program); +} + +inline void gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) { + active_texture(index); + bind_texture_2d(texture); +} + +inline void gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) { + active_texture(index); + bind_texture_cube_map(texture); +} + +inline void gl_rend_state::active_texture(int32_t index) { + active_texture_index = index; + enum_or(update_flags, GL_REND_STATE_UPDATE_ACTIVE_TEXTURE); +} + +inline void gl_rend_state::begin_event(const char* message, int32_t length) { + if (DIVA_GL_VERSION_4_3) + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)length, message); +} + +inline void gl_rend_state::bind_framebuffer(GLuint framebuffer) { + read_framebuffer_binding = framebuffer; + draw_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER + | GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); +} + +inline void gl_rend_state::bind_read_framebuffer(GLuint framebuffer) { + read_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); +} + +inline void gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) { + draw_framebuffer_binding = framebuffer; + enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER); +} + +inline void gl_rend_state::bind_vertex_array(GLuint array) { + vertex_array_binding = array; + enum_or(update_flags, GL_REND_STATE_UPDATE_VERTEX_ARRAY); +} + +inline void gl_rend_state::bind_array_buffer(GLuint buffer) { + if (array_buffer_binding != buffer) { glBindBuffer(GL_ARRAY_BUFFER, buffer); array_buffer_binding = buffer; } } -void gl_rend_state_struct::bind_element_array_buffer(GLuint buffer, bool force) { - if (force || element_array_buffer_binding != buffer) { +inline void gl_rend_state::bind_element_array_buffer(GLuint buffer) { + if (element_array_buffer_binding != buffer) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); element_array_buffer_binding = buffer; } } -void gl_rend_state_struct::bind_uniform_buffer(GLuint buffer, bool force) { - if (force || uniform_buffer_binding != buffer) { +inline void gl_rend_state::bind_uniform_buffer(GLuint buffer) { + if (uniform_buffer_binding != buffer) { glBindBuffer(GL_UNIFORM_BUFFER, buffer); uniform_buffer_binding = buffer; } } -void gl_rend_state_struct::bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force) { - if (force || uniform_buffer_bindings[index] != buffer) { - glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer); - uniform_buffer_binding = buffer; - uniform_buffer_bindings[index] = buffer; - uniform_buffer_offsets[index] = 0; - uniform_buffer_sizes[index] = -1; - } +inline void gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) { + uniform_buffer_bindings[index] = buffer; + uniform_buffer_offsets[index] = 0; + uniform_buffer_sizes[index] = -1; + uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index); + uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } -void gl_rend_state_struct::bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - if (force || uniform_buffer_bindings[index] != buffer - || uniform_buffer_offsets[index] != offset - || uniform_buffer_sizes[index] != size) { - glBindBufferRange(GL_UNIFORM_BUFFER, index, buffer, offset, size); - uniform_buffer_binding = buffer; - uniform_buffer_bindings[index] = buffer; - uniform_buffer_offsets[index] = offset; - uniform_buffer_sizes[index] = size; - } +inline void gl_rend_state::bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + uniform_buffer_bindings[index] = buffer; + uniform_buffer_offsets[index] = offset; + uniform_buffer_sizes[index] = size; + uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index); + uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } -void gl_rend_state_struct::bind_shader_storage_buffer(GLuint buffer, bool force) { - if (!DIVA_GL_VERSION_4_3) - return; - - if (force || shader_storage_buffer_binding != buffer) { +inline void gl_rend_state::bind_shader_storage_buffer(GLuint buffer) { + if (shader_storage_buffer_binding != buffer) { glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); shader_storage_buffer_binding = buffer; } } -void gl_rend_state_struct::bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force) { - if (!DIVA_GL_VERSION_4_3) - return; +inline void gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) { + shader_storage_buffer_bindings[index] = buffer; + shader_storage_buffer_offsets[index] = 0; + shader_storage_buffer_sizes[index] = -1; + shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index); + shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); +} - if (force || shader_storage_buffer_bindings[index] != buffer) { - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer); - shader_storage_buffer_binding = buffer; - shader_storage_buffer_bindings[index] = buffer; - shader_storage_buffer_offsets[index] = 0; - shader_storage_buffer_sizes[index] = -1; +inline void gl_rend_state::bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size) { + shader_storage_buffer_bindings[index] = buffer; + shader_storage_buffer_offsets[index] = offset; + shader_storage_buffer_sizes[index] = size; + shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index); + shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); +} + +inline void gl_rend_state::bind_texture_2d(GLuint texture) { + texture_binding_2d[active_texture_index] = texture; + texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index); + texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index); + enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE); +} + +inline void gl_rend_state::bind_texture_cube_map(GLuint texture) { + texture_binding_cube_map[active_texture_index] = texture; + texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index); + texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index); + enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE); +} + +inline void gl_rend_state::bind_sampler(int32_t index, GLuint sampler) { + sampler_binding[index] = sampler; + sampler_binding_start_index = min_def(sampler_binding_start_index, (int32_t)index); + sampler_binding_end_index = max_def(sampler_binding_end_index, (int32_t)index); + enum_or(update_flags, GL_REND_STATE_UPDATE_SAMPLER); +} + +inline void gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + update_read_framebuffer(); + update_draw_framebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + update_color_mask(); + + if (mask & GL_DEPTH_BUFFER_BIT) { + update_depth_test(); + update_depth_mask(); + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + update_stencil_test(); + update_stencil_mask(); + } + + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +inline GLenum gl_rend_state::check_framebuffer_status(GLenum target) { + switch (target) { + case GL_READ_FRAMEBUFFER: + update_read_framebuffer(); + break; + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + update_draw_framebuffer(); + break; + } + + return glCheckFramebufferStatus(target); +} + +inline void gl_rend_state::clear(GLbitfield mask) { + update_draw_framebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + update_color_mask(); + + if (mask & GL_DEPTH_BUFFER_BIT) { + update_depth_test(); + update_depth_mask(); + } + + update_scissor_test(); + update_scissor(); + + if (mask & GL_STENCIL_BUFFER_BIT) { + update_stencil_test(); + update_stencil_mask(); + } + + if (mask & GL_COLOR_BUFFER_BIT) + update_clear_color(); + + if (mask & GL_DEPTH_BUFFER_BIT) + update_clear_depth(); + + if (mask & GL_STENCIL_BUFFER_BIT) + update_clear_stencil(); + + glClearDLL(mask); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + update_draw_framebuffer(); + + glClearBufferfv(buffer, drawbuffer, value); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + clear_color_value[0] = red; + clear_color_value[1] = green; + clear_color_value[2] = blue; + clear_color_value[3] = alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_COLOR); +} + +inline void gl_rend_state::clear_depth(GLfloat depth) { + clear_depth_value = depth; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_DEPTH); +} + +inline void gl_rend_state::clear_stencil(GLint stencil) { + clear_stencil_value = stencil; + enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_STENCIL); +} + +inline void gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { + glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, + dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + update_active_texture(); + update_curr_active_texture(); + update_read_framebuffer(); + glCopyTexSubImage2DDLL(target, level, xoffset, yoffset, x, y, width, height); + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::disable_blend() { + blend = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND); +} + +inline void gl_rend_state::disable_cull_face() { + cull_face = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE); +} + +inline void gl_rend_state::disable_depth_test() { + depth_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST); +} + +inline void gl_rend_state::disable_multisample() { + multisample = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE); +} + +inline void gl_rend_state::disable_primitive_restart() { + primitive_restart = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); +} + +inline void gl_rend_state::disable_scissor_test() { + scissor_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST); +} + +inline void gl_rend_state::disable_stencil_test() { + stencil_test = GL_FALSE; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST); +} + +inline void gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) { + update(); + glDrawArraysDLL(mode, first, count); +} + +inline void gl_rend_state::draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } + + enable_primitive_restart(); + set_primitive_restart_index(index); + break; + } + + update(); + glDrawElementsDLL(mode, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; } } -void gl_rend_state_struct::bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { - if (!DIVA_GL_VERSION_4_3) - return; +inline void gl_rend_state::draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } - if (force || shader_storage_buffer_bindings[index] != buffer - || shader_storage_buffer_offsets[index] != offset - || shader_storage_buffer_sizes[index] != size) { - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, buffer, offset, size); - shader_storage_buffer_binding = buffer; - shader_storage_buffer_bindings[index] = buffer; - shader_storage_buffer_offsets[index] = offset; - shader_storage_buffer_sizes[index] = size; + enable_primitive_restart(); + set_primitive_restart_index(index); + break; + } + + update(); + glDrawRangeElements(mode, start, end, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; } } -void gl_rend_state_struct::bind_texture_2d(GLuint texture, bool force) { - if (texture_binding_2d[active_texture_index] != texture) { - glBindTextureDLL(GL_TEXTURE_2D, texture); - texture_binding_2d[active_texture_index] = texture; - } +inline void gl_rend_state::enable_blend() { + blend = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND); } -void gl_rend_state_struct::bind_texture_cube_map(GLuint texture, bool force) { - if (force || texture_binding_cube_map[active_texture_index] != texture) { - glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture); - texture_binding_cube_map[active_texture_index] = texture; - } +inline void gl_rend_state::enable_cull_face() { + cull_face = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE); } -void gl_rend_state_struct::bind_sampler(int32_t index, GLuint sampler, bool force) { - if (force || sampler_binding[index] != sampler) { - glBindSampler(index, sampler); - sampler_binding[index] = sampler; - } +inline void gl_rend_state::enable_depth_test() { + depth_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST); } -bool gl_rend_state_struct::check_uniform_buffer_binding() { - return uniform_buffer_binding != 0; +inline void gl_rend_state::enable_multisample() { + multisample = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE); } -bool gl_rend_state_struct::check_uniform_buffer_binding_base(size_t index) { - return uniform_buffer_bindings[index] != 0; +inline void gl_rend_state::enable_primitive_restart() { + primitive_restart = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); } -bool gl_rend_state_struct::check_texture_binding_2d(size_t index) { - return texture_binding_2d[index] != 0; +inline void gl_rend_state::enable_scissor_test() { + scissor_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST); } -bool gl_rend_state_struct::check_shader_storage_buffer_binding() { - return shader_storage_buffer_binding != 0; +inline void gl_rend_state::enable_stencil_test() { + stencil_test = GL_TRUE; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST); } -bool gl_rend_state_struct::check_shader_storage_buffer_binding_base(size_t index) { - return shader_storage_buffer_bindings[index] != 0; +inline void gl_rend_state::end_event() { + if (DIVA_GL_VERSION_4_3) + glPopDebugGroup(); } -bool gl_rend_state_struct::check_texture_binding_cube_map(size_t index) { - return texture_binding_cube_map[index] != 0; +inline void gl_rend_state::generate_mipmap(GLenum target) { + update_curr_active_texture(); + glGenerateMipmap(target); + enum_or(flags, GL_REND_STATE_EXECUTE); } -bool gl_rend_state_struct::check_sampler_binding(int32_t index, GLuint sampler) { - return sampler_binding[index] != 0; +inline void gl_rend_state::generate_texture_mipmap(GLuint texture) { + glGenerateTextureMipmap(texture); + enum_or(flags, GL_REND_STATE_EXECUTE); } -void gl_rend_state_struct::disable_blend(bool force) { - if (force || blend) { - glDisableDLL(GL_BLEND); - blend = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_cull_face(bool force) { - if (force || cull_face) { - glDisableDLL(GL_CULL_FACE); - cull_face = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_depth_test(bool force) { - if (force || depth_test) { - glDisableDLL(GL_DEPTH_TEST); - depth_test = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_multisample(bool force) { - if (force || multisample) { - glDisableDLL(GL_MULTISAMPLE); - multisample = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_primitive_restart(bool force) { - if (force || primitive_restart) { - glDisableDLL(GL_PRIMITIVE_RESTART); - primitive_restart = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_scissor_test(bool force) { - if (force || scissor_test) { - glDisableDLL(GL_SCISSOR_TEST); - scissor_test = GL_FALSE; - } -} - -void gl_rend_state_struct::disable_stencil_test(bool force) { - if (force || stencil_test) { - glDisableDLL(GL_STENCIL_TEST); - stencil_test = GL_FALSE; - } -} - -void gl_rend_state_struct::enable_blend(bool force) { - if (force || !blend) { - glEnableDLL(GL_BLEND); - blend = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_cull_face(bool force) { - if (force || !cull_face) { - glEnableDLL(GL_CULL_FACE); - cull_face = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_depth_test(bool force) { - if (force || !depth_test) { - glEnableDLL(GL_DEPTH_TEST); - depth_test = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_multisample(bool force) { - if (force || !multisample) { - glEnableDLL(GL_MULTISAMPLE); - multisample = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_primitive_restart(bool force) { - if (force || !primitive_restart) { - glEnableDLL(GL_PRIMITIVE_RESTART); - primitive_restart = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_scissor_test(bool force) { - if (force || !scissor_test) { - glEnableDLL(GL_SCISSOR_TEST); - scissor_test = GL_TRUE; - } -} - -void gl_rend_state_struct::enable_stencil_test(bool force) { - if (force || !stencil_test) { - glEnableDLL(GL_STENCIL_TEST); - stencil_test = GL_TRUE; - } -} - -void gl_rend_state_struct::get() { +void gl_rend_state::get() { glGetIntegervDLL(GL_CURRENT_PROGRAM, (GLint*)&program); + GLenum active_texture = GL_TEXTURE0; glGetIntegervDLL(GL_ACTIVE_TEXTURE, (GLint*)&active_texture); active_texture_index = active_texture - GL_TEXTURE0; + texture_binding_start_index = 32; + texture_binding_end_index = -1; + sampler_binding_start_index = 32; + sampler_binding_end_index = -1; + if (DIVA_GL_VERSION_4_5) { for (GLuint i = 0; i < 32; i++) { - glGetIntegeri_v(GL_TEXTURE_BINDING_2D, i, &texture_binding_2d[i]); - glGetIntegeri_v(GL_TEXTURE_BINDING_CUBE_MAP, i, &texture_binding_cube_map[i]); - glGetIntegeri_v(GL_SAMPLER_BINDING, i, &sampler_binding[i]); + glGetIntegeri_v(GL_TEXTURE_BINDING_2D, i, (GLint*)&texture_binding_2d[i]); + glGetIntegeri_v(GL_TEXTURE_BINDING_CUBE_MAP, i, (GLint*)&texture_binding_cube_map[i]); + glGetIntegeri_v(GL_SAMPLER_BINDING, i, (GLint*)&sampler_binding[i]); } } else { for (GLuint i = 0; i < 32; i++) { glActiveTexture((GLenum)(GL_TEXTURE0 + i)); - glGetIntegervDLL(GL_TEXTURE_BINDING_2D, &texture_binding_2d[i]); - glGetIntegervDLL(GL_TEXTURE_BINDING_CUBE_MAP, &texture_binding_cube_map[i]); - glGetIntegervDLL(GL_SAMPLER_BINDING, &sampler_binding[i]); + glGetIntegervDLL(GL_TEXTURE_BINDING_2D, (GLint*)&texture_binding_2d[i]); + glGetIntegervDLL(GL_TEXTURE_BINDING_CUBE_MAP, (GLint*)&texture_binding_cube_map[i]); + glGetIntegervDLL(GL_SAMPLER_BINDING, (GLint*)&sampler_binding[i]); } glActiveTexture(active_texture); } @@ -330,41 +1046,53 @@ void gl_rend_state_struct::get() { glGetIntegervDLL(GL_BLEND_EQUATION_RGB, (GLint*)&blend_mode_rgb); glGetIntegervDLL(GL_BLEND_EQUATION_ALPHA, (GLint*)&blend_mode_alpha); - glGetIntegervDLL(GL_FRAMEBUFFER_BINDING, (GLint*)&framebuffer_binding); glGetIntegervDLL(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&read_framebuffer_binding); glGetIntegervDLL(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&draw_framebuffer_binding); + glGetIntegervDLL(GL_VERTEX_ARRAY_BINDING, (GLint*)&vertex_array_binding); + glGetIntegervDLL(GL_ARRAY_BUFFER_BINDING, (GLint*)&array_buffer_binding); glGetIntegervDLL(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&element_array_buffer_binding); + uniform_buffer_start_index = 14; + uniform_buffer_end_index = -1; + glGetIntegervDLL(GL_UNIFORM_BUFFER_BINDING, (GLint*)&uniform_buffer_binding); for (GLuint i = 0; i < 14; i++) { glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint*)&uniform_buffer_bindings[i]); - glGetInteger64i_v(GL_UNIFORM_BUFFER_START, i, (GLintptr*)&uniform_buffer_offsets[i]); - glGetInteger64i_v(GL_UNIFORM_BUFFER_SIZE, i, (GLsizeiptr*)&uniform_buffer_sizes[i]); + glGetInteger64i_v(GL_UNIFORM_BUFFER_START, i, (GLint64*)&uniform_buffer_offsets[i]); + glGetInteger64i_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint64*)&uniform_buffer_sizes[i]); } - if (DIVA_GL_VERSION_4_3) { - glGetIntegervDLL(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&shader_storage_buffer_binding); - for (GLuint i = 0; i < 14; i++) { - glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&shader_storage_buffer_bindings[i]); - glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_START, i, (GLintptr*)&shader_storage_buffer_offsets[i]); - glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_SIZE, i, (GLsizeiptr*)&shader_storage_buffer_sizes[i]); - } + shader_storage_buffer_start_index = 14; + shader_storage_buffer_end_index = -1; + + glGetIntegervDLL(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&shader_storage_buffer_binding); + for (GLuint i = 0; i < 14; i++) { + glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&shader_storage_buffer_bindings[i]); + glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_START, i, (GLint64*)&shader_storage_buffer_offsets[i]); + glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_SIZE, i, (GLint64*)&shader_storage_buffer_sizes[i]); } glGetBooleanvDLL(GL_COLOR_WRITEMASK, color_mask); + glGetBooleanvDLL(GL_CULL_FACE, &cull_face); glGetIntegervDLL(GL_CULL_FACE_MODE, (GLint*)&cull_face_mode); + glGetBooleanvDLL(GL_DEPTH_TEST, &depth_test); glGetIntegervDLL(GL_DEPTH_FUNC, (GLint*)&depth_func); glGetBooleanvDLL(GL_DEPTH_WRITEMASK, &depth_mask); + glGetFloatvDLL(GL_LINE_WIDTH, &line_width); + glGetBooleanvDLL(GL_MULTISAMPLE, &multisample); + glGetBooleanvDLL(GL_PRIMITIVE_RESTART, &primitive_restart); glGetIntegervDLL(GL_PRIMITIVE_RESTART_INDEX, (GLint*)&primitive_restart_index); + glGetIntegervDLL(GL_SCISSOR_BOX, (GLint*)&scissor_box); glGetBooleanvDLL(GL_SCISSOR_TEST, &scissor_test); + glGetBooleanvDLL(GL_STENCIL_TEST, &stencil_test); glGetIntegervDLL(GL_STENCIL_FUNC, (GLint*)&stencil_func); glGetIntegervDLL(GL_STENCIL_VALUE_MASK, (GLint*)&stencil_value_mask); @@ -373,214 +1101,711 @@ void gl_rend_state_struct::get() { glGetIntegervDLL(GL_STENCIL_PASS_DEPTH_PASS, (GLint*)&stencil_dppass); glGetIntegervDLL(GL_STENCIL_REF, &stencil_ref); glGetIntegervDLL(GL_STENCIL_WRITEMASK, (GLint*)&stencil_mask); + glGetIntegervDLL(GL_VIEWPORT, (GLint*)&viewport); - glPolygonModeDLL(GL_FRONT_AND_BACK, GL_FILL); - polygon_mode = GL_FILL; + glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, clear_color_value); + + glGetFloatvDLL(GL_DEPTH_CLEAR_VALUE, &clear_depth_value); + + glGetIntegervDLL(GL_STENCIL_CLEAR_VALUE, &clear_stencil_value); + + curr_program = program; + + curr_active_texture_index = active_texture_index; + + for (GLuint i = 0; i < 32; i++) { + curr_texture_binding_2d[i] = texture_binding_2d[i]; + curr_texture_binding_cube_map[i] = texture_binding_cube_map[i]; + curr_sampler_binding[i] = sampler_binding[i]; + } + + curr_blend = blend; + curr_blend_src_rgb = blend_src_rgb; + curr_blend_src_alpha = blend_src_alpha; + curr_blend_dst_rgb = blend_dst_rgb; + curr_blend_dst_alpha = blend_dst_alpha; + curr_blend_mode_rgb = blend_mode_rgb; + curr_blend_mode_alpha = blend_mode_alpha; + + curr_read_framebuffer_binding = read_framebuffer_binding; + curr_draw_framebuffer_binding = draw_framebuffer_binding; + + curr_vertex_array_binding = vertex_array_binding; + + for (GLuint i = 0; i < 14; i++) { + curr_uniform_buffer_bindings[i] = uniform_buffer_bindings[i]; + curr_uniform_buffer_offsets[i] = uniform_buffer_offsets[i]; + curr_uniform_buffer_sizes[i] = uniform_buffer_sizes[i]; + } + + for (GLuint i = 0; i < 14; i++) { + curr_shader_storage_buffer_bindings[i] = shader_storage_buffer_bindings[i]; + curr_shader_storage_buffer_offsets[i] = shader_storage_buffer_offsets[i]; + curr_shader_storage_buffer_sizes[i] = shader_storage_buffer_sizes[i]; + } + + memcpy(curr_color_mask, color_mask, sizeof(GLboolean) * 4); + + curr_cull_face = cull_face; + curr_cull_face_mode = cull_face_mode; + + curr_depth_test = depth_test; + curr_depth_func = depth_func; + curr_depth_mask = depth_mask; + + curr_line_width = line_width; + curr_multisample = multisample; + + curr_primitive_restart = primitive_restart; + curr_primitive_restart_index = primitive_restart_index; + + curr_scissor_box = scissor_box; + curr_scissor_test = scissor_test; + + curr_stencil_test = stencil_test; + curr_stencil_func = stencil_func; + curr_stencil_value_mask = stencil_value_mask; + curr_stencil_fail = stencil_fail; + curr_stencil_dpfail = stencil_dpfail; + curr_stencil_dppass = stencil_dppass; + curr_stencil_ref = stencil_ref; + curr_stencil_mask = stencil_mask; + + curr_viewport = viewport; + + memcpy(curr_clear_color_value, clear_color_value, sizeof(GLboolean) * 4); + curr_clear_depth_value = clear_depth_value; + curr_clear_stencil_value = clear_stencil_value; + + flags = (gl_rend_state_flags)0; + update_flags = (gl_rend_state_update_flags)0; } -GLuint gl_rend_state_struct::get_program() { +inline void gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) { + red = clear_color_value[0]; + green = clear_color_value[1]; + blue = clear_color_value[2]; + alpha = clear_color_value[3]; +} + +inline GLuint gl_rend_state::get_program() { return program; } -gl_rend_state_rect gl_rend_state_struct::get_scissor() { +inline gl_rend_state_rect gl_rend_state::get_scissor() { return scissor_box; } -void gl_rend_state_struct::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { +inline void gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { x = scissor_box.x; y = scissor_box.y; width = scissor_box.width; height = scissor_box.height; } -gl_rend_state_rect gl_rend_state_struct::get_viewport() { +inline gl_rend_state_rect gl_rend_state::get_viewport() { return viewport; } -void gl_rend_state_struct::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { +inline void gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) { x = viewport.x; y = viewport.y; width = viewport.width; height = viewport.height; } -void gl_rend_state_struct::set_blend_func(GLenum src, GLenum dst, bool force) { - if (force || blend_src_rgb != src || blend_dst_rgb != dst - || blend_src_alpha != GL_ONE || blend_dst_alpha != GL_ONE_MINUS_SRC_ALPHA) { - glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - blend_src_rgb = src; - blend_dst_rgb = dst; - blend_src_alpha = GL_ONE; - blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA; - } +inline void gl_rend_state::set_blend_func(GLenum src, GLenum dst) { + blend_src_rgb = src; + blend_dst_rgb = dst; + blend_src_alpha = GL_ONE; + blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC); } -void gl_rend_state_struct::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force) { - if (force || blend_src_rgb != src_rgb || blend_dst_rgb != dst_rgb - || blend_src_alpha != src_alpha || blend_dst_alpha != dst_alpha) { - glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - blend_src_rgb = src_rgb; - blend_dst_rgb = dst_rgb; - blend_src_alpha = src_alpha; - blend_dst_alpha = dst_alpha; - } +inline void gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha) { + blend_src_rgb = src_rgb; + blend_dst_rgb = dst_rgb; + blend_src_alpha = src_alpha; + blend_dst_alpha = dst_alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC); } -void gl_rend_state_struct::set_blend_equation(GLenum mode, bool force) { - if (force || blend_mode_rgb != mode || blend_mode_alpha != mode) { - glBlendEquationSeparate(mode, mode); - blend_mode_rgb = mode; - blend_mode_alpha = mode; - } +inline void gl_rend_state::set_blend_equation(GLenum mode) { + blend_mode_rgb = mode; + blend_mode_alpha = mode; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION); } -void gl_rend_state_struct::set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha, bool force) { - if (force || blend_mode_rgb != mode_rgb || blend_mode_alpha != mode_alpha) { - glBlendEquationSeparate(mode_rgb, mode_alpha); - blend_mode_rgb = mode_rgb; - blend_mode_alpha = mode_alpha; - } +inline void gl_rend_state::set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha) { + blend_mode_rgb = mode_rgb; + blend_mode_alpha = mode_alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION); } -void gl_rend_state_struct::set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force) { - if (force || color_mask[0] != red || color_mask[1] != green - || color_mask[2] != blue || color_mask[3] != alpha) { - glColorMaskDLL(red, green, blue, alpha); - color_mask[0] = red; - color_mask[1] = green; - color_mask[2] = blue; - color_mask[3] = alpha; - } +inline void gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + color_mask[0] = red; + color_mask[1] = green; + color_mask[2] = blue; + color_mask[3] = alpha; + enum_or(update_flags, GL_REND_STATE_UPDATE_COLOR_MASK); } -void gl_rend_state_struct::set_cull_face_mode(GLenum mode, bool force) { - if (force || cull_face_mode != mode) { - glCullFaceDLL(mode); - cull_face_mode = mode; - } +inline void gl_rend_state::set_cull_face_mode(GLenum mode) { + cull_face_mode = mode; + enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE_MODE); } -void gl_rend_state_struct::set_depth_func(GLenum func, bool force) { - if (force || depth_func != func) { - glDepthFuncDLL(func); - depth_func = func; - } +inline void gl_rend_state::set_depth_func(GLenum func) { + depth_func = func; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_FUNC); } -void gl_rend_state_struct::set_depth_mask(GLboolean flag, bool force) { - if (force || depth_mask != flag) { - glDepthMaskDLL(flag); - depth_mask = flag; - } +inline void gl_rend_state::set_depth_mask(GLboolean flag) { + depth_mask = flag; + enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_MASK); } -void gl_rend_state_struct::set_line_width(GLfloat width, bool force) { - if (force || line_width != width) { - glLineWidthDLL(width); - line_width = width; - } +inline void gl_rend_state::set_line_width(GLfloat width) { + line_width = width; + enum_or(update_flags, GL_REND_STATE_UPDATE_LINE_WIDTH); } -void gl_rend_state_struct::set_polygon_mode(GLenum face, GLenum mode, bool force) { - switch (face) { - case GL_FRONT: - if (force || polygon_mode != mode) { - glPolygonModeDLL(GL_FRONT, mode); - polygon_mode = mode; +inline void gl_rend_state::set_primitive_restart_index(GLuint index) { + primitive_restart_index = index; + enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX); +} + +inline void gl_rend_state::set_scissor(const gl_rend_state_rect& rect) { + scissor_box = rect; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR); +} + +inline void gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + scissor_box.x = x; + scissor_box.y = y; + scissor_box.width = width; + scissor_box.height = height; + enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR); +} + +inline void gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) { + stencil_func = func; + stencil_ref = ref; + stencil_value_mask = mask; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_FUNC); +} + +inline void gl_rend_state::set_stencil_mask(GLuint mask) { + stencil_mask = mask; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_MASK); +} + +inline void gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) { + stencil_fail = sfail; + stencil_dpfail = dpfail; + stencil_dppass = dppass; + enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_OP); +} + +inline void gl_rend_state::set_viewport(const gl_rend_state_rect& rect) { + viewport = rect; + enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT); +} + +inline void gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + viewport.x = x; + viewport.y = y; + viewport.width = width; + viewport.height = height; + enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT); +} + +void gl_rend_state::update() { + if (!update_flags) + return; + + update_program(); + update_texture(); + update_active_texture(); + update_sampler(); + update_blend(); + update_blend_func(); + update_blend_equation(); + update_read_framebuffer(); + update_draw_framebuffer(); + update_vertex_array(); + update_uniform_buffer(); + update_shader_storage_buffer(); + update_color_mask(); + update_cull_face(); + update_cull_face_mode(); + update_depth_test(); + update_depth_mask(); + update_depth_func(); + update_line_width(); + update_multisample(); + update_primitive_restart(); + update_primitive_restart_index(); + update_scissor_test(); + update_scissor(); + update_stencil_test(); + update_stencil_mask(); + update_stencil_func(); + update_stencil_op(); + update_viewport(); + update_clear_color(); + update_clear_depth(); + update_clear_stencil(); + + enum_or(flags, GL_REND_STATE_EXECUTE); +} + +inline void gl_rend_state::update_program() { + if (update_flags & GL_REND_STATE_UPDATE_PROGRAM) { + if (curr_program != program) { + glUseProgram(program); + curr_program = program; } - break; - case GL_BACK: - if (force || polygon_mode != mode) { - glPolygonModeDLL(GL_BACK, mode); - polygon_mode = mode; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PROGRAM); + } +} + +inline void gl_rend_state::update_active_texture() { + if (update_flags & GL_REND_STATE_UPDATE_ACTIVE_TEXTURE) { + if (curr_active_texture_index != active_texture_index) { + glActiveTexture((GLenum)(GL_TEXTURE0 + active_texture_index)); + curr_active_texture_index = active_texture_index; } - break; - case GL_FRONT_AND_BACK: - if (force || polygon_mode != mode) { - glPolygonModeDLL(GL_FRONT_AND_BACK, mode); - polygon_mode = mode; - polygon_mode = mode; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_ACTIVE_TEXTURE); + } +} + +inline void gl_rend_state::update_curr_active_texture() { + if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) { + GLuint index = curr_active_texture_index; + bool bind = false; + if (curr_texture_binding_2d[index] != texture_binding_2d[index]) { + glBindTextureDLL(GL_TEXTURE_2D, texture_binding_2d[curr_active_texture_index]); + curr_texture_binding_2d[index] = texture_binding_2d[index]; + bind = true; + } + else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) { + glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]); + curr_texture_binding_cube_map[index] = texture_binding_cube_map[index]; + bind = true; + } + + if (bind) { + if (texture_binding_start_index == curr_active_texture_index) + texture_binding_start_index++; + else if (texture_binding_end_index == curr_active_texture_index) + texture_binding_end_index--; + + if (texture_binding_start_index > texture_binding_end_index) { + texture_binding_start_index = 32; + texture_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE); + } } - break; } } -void gl_rend_state_struct::set_primitive_restart_index(GLuint index, bool force) { - if (force || primitive_restart_index != index) { - glPrimitiveRestartIndex(index); - primitive_restart_index = index; +inline void gl_rend_state::update_texture() { + if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) { + for (int32_t index = texture_binding_start_index; + index <= texture_binding_end_index; index++) + if (curr_texture_binding_2d[index] != texture_binding_2d[index]) { + if (DIVA_GL_VERSION_4_5) + glBindTextureUnit(index, texture_binding_2d[index]); + else { + if (curr_active_texture_index != index) + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + + glBindTextureDLL(GL_TEXTURE_2D, texture_binding_2d[index]); + curr_active_texture_index = index; + } + curr_texture_binding_2d[index] = texture_binding_2d[index]; + } + else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) { + if (DIVA_GL_VERSION_4_5) + glBindTextureUnit(index, texture_binding_cube_map[index]); + else { + if (curr_active_texture_index != index) + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + + glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]); + curr_active_texture_index = index; + } + curr_texture_binding_cube_map[index] = texture_binding_cube_map[index]; + } + + texture_binding_start_index = 32; + texture_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE); } } -void gl_rend_state_struct::set_scissor(const gl_rend_state_rect& rect, bool force) { - if (force || scissor_box.x != rect.x || scissor_box.y != rect.y - || scissor_box.width != rect.width || scissor_box.height != rect.height) { - glScissorDLL(rect.x, rect.y, rect.width, rect.height); - scissor_box = rect; +inline void gl_rend_state::update_sampler() { + if (update_flags & GL_REND_STATE_UPDATE_SAMPLER) { + for (int32_t index = sampler_binding_start_index; + index <= sampler_binding_end_index; index++) + if (curr_sampler_binding[index] != sampler_binding[index]) { + glBindSampler(index, sampler_binding[index]); + curr_sampler_binding[index] = sampler_binding[index]; + } + + sampler_binding_start_index = 32; + sampler_binding_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SAMPLER); } } -void gl_rend_state_struct::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - if (force || scissor_box.x != x || scissor_box.y != y - || scissor_box.width != width || scissor_box.height != height) { - glScissorDLL(x, y, width, height); - scissor_box.x = x; - scissor_box.y = y; - scissor_box.width = width; - scissor_box.height = height; +inline void gl_rend_state::update_blend() { + if (update_flags & GL_REND_STATE_UPDATE_BLEND) { + if (curr_blend != blend) { + (blend ? glEnableDLL : glDisableDLL)(GL_BLEND); + curr_blend = blend; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND); } } -void gl_rend_state_struct::set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force) { - if (force || stencil_func != func || stencil_ref != ref || stencil_value_mask != mask) { - glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); - stencil_func = func; - stencil_ref = ref; - stencil_value_mask = mask; +inline void gl_rend_state::update_blend_func() { + if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_FUNC)) { + if (curr_blend_src_rgb != blend_src_rgb || curr_blend_dst_rgb != blend_dst_rgb + || curr_blend_src_alpha != blend_src_alpha || curr_blend_dst_alpha != blend_dst_alpha) { + glBlendFuncSeparate(blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha); + curr_blend_src_rgb = blend_src_rgb; + curr_blend_dst_rgb = blend_dst_rgb; + curr_blend_src_alpha = blend_src_alpha; + curr_blend_dst_alpha = blend_dst_alpha; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_FUNC); } } -void gl_rend_state_struct::set_stencil_mask(GLuint mask, bool force) { - if (force || stencil_mask != mask) { - glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); - stencil_mask = mask; +inline void gl_rend_state::update_blend_equation() { + if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_EQUATION)) { + if (curr_blend_mode_rgb != blend_mode_rgb || curr_blend_mode_alpha != blend_mode_alpha) { + glBlendEquationSeparate(blend_mode_rgb, blend_mode_alpha); + curr_blend_mode_rgb = blend_mode_rgb; + curr_blend_mode_alpha = blend_mode_alpha; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_EQUATION); } } -void gl_rend_state_struct::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force) { - if (force || stencil_fail != sfail || stencil_dpfail != dpfail || stencil_dppass != dppass) { - glStencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass); - stencil_fail = sfail; - stencil_dpfail = dpfail; - stencil_dppass = dppass; +inline void gl_rend_state::update_read_framebuffer() { + if (update_flags & GL_REND_STATE_UPDATE_READ_FRAMEBUFFER) { + if (curr_read_framebuffer_binding != read_framebuffer_binding) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer_binding); + if (read_framebuffer_binding) { + GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + printf_debug("GL Error: Bind Read Framebuffer Status - 0x%04X\n", status); + gl_get_error_print(); + } + curr_read_framebuffer_binding = read_framebuffer_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_READ_FRAMEBUFFER); } } -void gl_rend_state_struct::set_viewport(const gl_rend_state_rect& rect, bool force) { - if (force || viewport.x != rect.x || viewport.y != rect.y - || viewport.width != rect.width || viewport.height != rect.height) { - glViewportDLL(rect.x, rect.y, rect.width, rect.height); - viewport = rect; +inline void gl_rend_state::update_draw_framebuffer() { + if (update_flags & GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER) { + if (curr_draw_framebuffer_binding != draw_framebuffer_binding) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_framebuffer_binding); + if (draw_framebuffer_binding) { + GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + printf_debug("GL Error: Bind Draw Framebuffer Status - 0x%04X\n", status); + gl_get_error_print(); + } + curr_draw_framebuffer_binding = draw_framebuffer_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER); } } -void gl_rend_state_struct::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force) { - if (force || viewport.x != x || viewport.y != y - || viewport.width != width || viewport.height != height) { - glViewportDLL(x, y, width, height); - viewport.x = x; - viewport.y = y; - viewport.width = width; - viewport.height = height; +inline void gl_rend_state::update_vertex_array() { + if (update_flags & GL_REND_STATE_UPDATE_VERTEX_ARRAY) { + if (curr_vertex_array_binding != vertex_array_binding) { + glBindVertexArray(vertex_array_binding); + curr_vertex_array_binding = vertex_array_binding; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_VERTEX_ARRAY); } } -void gl_rend_state_struct::use_program(GLuint program, bool force) { - if (force || this->program != program) { - glUseProgram(program); - this->program = program; +inline void gl_rend_state::update_uniform_buffer() { + if (update_flags & GL_REND_STATE_UPDATE_UNIFORM_BUFFER) { + for (int32_t index = uniform_buffer_start_index; + index <= uniform_buffer_end_index; index++) { + if (curr_uniform_buffer_bindings[index] == uniform_buffer_bindings[index] + && curr_uniform_buffer_offsets[index] == uniform_buffer_offsets[index] + && curr_uniform_buffer_sizes[index] == uniform_buffer_sizes[index]) + continue; + + if (uniform_buffer_offsets[index] == 0 && uniform_buffer_sizes[index] == -1) + glBindBufferBase(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index]); + else + glBindBufferRange(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index], + uniform_buffer_offsets[index], uniform_buffer_sizes[index]); + uniform_buffer_binding = uniform_buffer_bindings[index]; + curr_uniform_buffer_bindings[index] = uniform_buffer_bindings[index]; + curr_uniform_buffer_offsets[index] = uniform_buffer_offsets[index]; + curr_uniform_buffer_sizes[index] = uniform_buffer_sizes[index]; + } + + uniform_buffer_start_index = 14; + uniform_buffer_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_UNIFORM_BUFFER); } } + +inline void gl_rend_state::update_shader_storage_buffer() { + if (update_flags & GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER) { + for (int32_t index = shader_storage_buffer_start_index; + index <= shader_storage_buffer_end_index; index++) { + if (curr_shader_storage_buffer_bindings[index] == shader_storage_buffer_bindings[index] + && curr_shader_storage_buffer_offsets[index] == shader_storage_buffer_offsets[index] + && curr_shader_storage_buffer_sizes[index] == shader_storage_buffer_sizes[index]) + continue; + + if (shader_storage_buffer_offsets[index] == 0 && shader_storage_buffer_sizes[index] == -1) + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index]); + else + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index], + shader_storage_buffer_offsets[index], shader_storage_buffer_sizes[index]); + shader_storage_buffer_binding = shader_storage_buffer_bindings[index]; + curr_shader_storage_buffer_bindings[index] = shader_storage_buffer_bindings[index]; + curr_shader_storage_buffer_offsets[index] = shader_storage_buffer_offsets[index]; + curr_shader_storage_buffer_sizes[index] = shader_storage_buffer_sizes[index]; + } + + shader_storage_buffer_start_index = 14; + shader_storage_buffer_end_index = -1; + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER); + } +} + +inline void gl_rend_state::update_color_mask() { + if (update_flags & GL_REND_STATE_UPDATE_COLOR_MASK) { + if (memcmp(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4)) { + glColorMaskDLL(color_mask[0], color_mask[1], color_mask[2], color_mask[3]); + memcpy(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4); + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_COLOR_MASK); + } +} + +inline void gl_rend_state::update_cull_face() { + if (update_flags & GL_REND_STATE_UPDATE_CULL_FACE) { + if (curr_cull_face != cull_face) { + (cull_face ? glEnableDLL : glDisableDLL)(GL_CULL_FACE); + curr_cull_face = cull_face; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE); + } +} + +inline void gl_rend_state::update_cull_face_mode() { + if (curr_cull_face && (update_flags & GL_REND_STATE_UPDATE_CULL_FACE_MODE)) { + if (curr_cull_face_mode != cull_face_mode) { + glCullFaceDLL(cull_face_mode); + curr_cull_face_mode = cull_face_mode; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE_MODE); + } +} + +inline void gl_rend_state::update_depth_test() { + if (update_flags & GL_REND_STATE_UPDATE_DEPTH_TEST) { + if (curr_depth_test != depth_test) { + (depth_test ? glEnableDLL : glDisableDLL)(GL_DEPTH_TEST); + curr_depth_test = depth_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_TEST); + } +} + +inline void gl_rend_state::update_depth_mask() { + if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_MASK)) { + if (curr_depth_mask != depth_mask) { + glDepthMaskDLL(depth_mask); + curr_depth_mask = depth_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_MASK); + } +} + +inline void gl_rend_state::update_depth_func() { + if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_FUNC)) { + if (curr_depth_func != depth_func) { + glDepthFuncDLL(depth_func); + curr_depth_func = depth_func; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_FUNC); + } +} + +inline void gl_rend_state::update_line_width() { + if (update_flags & GL_REND_STATE_UPDATE_LINE_WIDTH) { + if (curr_line_width != line_width) { + glLineWidthDLL(line_width); + curr_line_width = line_width; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_LINE_WIDTH); + } +} + +inline void gl_rend_state::update_multisample() { + if (update_flags & GL_REND_STATE_UPDATE_MULTISAMPLE) { + if (curr_multisample != multisample) { + (multisample ? glEnableDLL : glDisableDLL)(GL_MULTISAMPLE); + curr_multisample = multisample; + } + + enum_and(update_flags, ~GL_REND_STATE_UPDATE_MULTISAMPLE); + } +} + +inline void gl_rend_state::update_primitive_restart() { + if (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART) { + if (curr_primitive_restart != primitive_restart) { + (primitive_restart ? glEnableDLL : glDisableDLL)(GL_PRIMITIVE_RESTART); + curr_primitive_restart = primitive_restart; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART); + } +} + +inline void gl_rend_state::update_primitive_restart_index() { + if (curr_primitive_restart && (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX)) { + if (curr_primitive_restart_index != primitive_restart_index) { + glPrimitiveRestartIndex(primitive_restart_index); + curr_primitive_restart_index = primitive_restart_index; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX); + } +} + +inline void gl_rend_state::update_scissor_test() { + if (update_flags & GL_REND_STATE_UPDATE_SCISSOR_TEST) { + if (curr_scissor_test != scissor_test) { + (scissor_test ? glEnableDLL : glDisableDLL)(GL_SCISSOR_TEST); + curr_scissor_test = scissor_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR_TEST); + } +} + +inline void gl_rend_state::update_scissor() { + if (curr_scissor_test && (update_flags & GL_REND_STATE_UPDATE_SCISSOR)) { + if (memcmp(&curr_scissor_box, &scissor_box, sizeof(gl_rend_state_rect))) { + glScissorDLL(scissor_box.x, scissor_box.y, scissor_box.width, scissor_box.height); + curr_scissor_box = scissor_box; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR); + } +} + +inline void gl_rend_state::update_stencil_test() { + if (update_flags & GL_REND_STATE_UPDATE_STENCIL_TEST) { + if (curr_stencil_test != stencil_test) { + (stencil_test ? glEnableDLL : glDisableDLL)(GL_STENCIL_TEST); + curr_stencil_test = stencil_test; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_TEST); + } +} + +inline void gl_rend_state::update_stencil_mask() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_MASK)) { + if (curr_stencil_mask != stencil_mask) { + glStencilMask(stencil_mask); + curr_stencil_mask = stencil_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_MASK); + } +} + +inline void gl_rend_state::update_stencil_func() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_FUNC)) { + if (curr_stencil_func != stencil_func || curr_stencil_ref != stencil_ref + || curr_stencil_value_mask != stencil_value_mask) { + glStencilFunc(stencil_func, stencil_ref, stencil_ref); + curr_stencil_func = stencil_func; + curr_stencil_ref = stencil_ref; + curr_stencil_value_mask = stencil_value_mask; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_FUNC); + } +} + +inline void gl_rend_state::update_stencil_op() { + if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_OP)) { + if (curr_stencil_fail != stencil_fail || curr_stencil_dpfail != stencil_dpfail + || curr_stencil_dppass != stencil_dppass) { + glStencilOp(stencil_fail, stencil_dpfail, stencil_dppass); + curr_stencil_fail = stencil_fail; + curr_stencil_dpfail = stencil_dpfail; + curr_stencil_dppass = stencil_dppass; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_OP); + } +} + +inline void gl_rend_state::update_viewport() { + if (update_flags & GL_REND_STATE_UPDATE_VIEWPORT) { + if (memcmp(&curr_viewport, &viewport, sizeof(gl_rend_state_rect))) { + glViewportDLL(viewport.x, viewport.y, viewport.width, viewport.height); + curr_viewport = viewport; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_VIEWPORT); + } +} + +inline void gl_rend_state::update_clear_color() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_COLOR) { + if (curr_clear_color_value[0] != clear_color_value[0] + || curr_clear_color_value[1] != clear_color_value[1] + || curr_clear_color_value[2] != clear_color_value[2] + || curr_clear_color_value[3] != clear_color_value[3]) { + glClearColorDLL(clear_color_value[0], clear_color_value[1], + clear_color_value[2], clear_color_value[3]); + curr_clear_color_value[0] = clear_color_value[0]; + curr_clear_color_value[1] = clear_color_value[1]; + curr_clear_color_value[2] = clear_color_value[2]; + curr_clear_color_value[3] = clear_color_value[3]; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_COLOR); + } +} + +inline void gl_rend_state::update_clear_depth() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_DEPTH) { + if (curr_clear_depth_value != clear_depth_value) { + glClearDepthf(clear_depth_value); + curr_clear_depth_value = clear_depth_value; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_DEPTH); + } +} + +inline void gl_rend_state::update_clear_stencil() { + if (update_flags & GL_REND_STATE_UPDATE_CLEAR_STENCIL) { + if (curr_clear_stencil_value != clear_stencil_value) { + glClearStencilDLL(clear_stencil_value); + curr_clear_stencil_value = clear_stencil_value; + } + enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_STENCIL); + } +} + +inline void gl_rend_state::use_program(GLuint program) { + this->program = program; + enum_or(update_flags, GL_REND_STATE_UPDATE_PROGRAM); +} diff --git a/src/DivaGL/gl_rend_state.hpp b/src/DivaGL/gl_rend_state.hpp index e48c124..90e7cee 100644 --- a/src/DivaGL/gl_rend_state.hpp +++ b/src/DivaGL/gl_rend_state.hpp @@ -6,7 +6,15 @@ #pragma once #include "../KKdLib/default.hpp" -#include "wrap.hpp" +#include "gl.hpp" + +enum gl_rend_state_index { + GL_REND_STATE_PRE_3D = 0, + GL_REND_STATE_3D, + GL_REND_STATE_2D, + GL_REND_STATE_POST_2D, + GL_REND_STATE_COUNT, +}; struct gl_rend_state_rect { GLint x; @@ -15,135 +23,98 @@ struct gl_rend_state_rect { GLsizei height; }; -struct gl_rend_state_struct { - GLint program; - GLuint active_texture_index; - GLint texture_binding_2d[32]; - GLint texture_binding_cube_map[32]; - GLint sampler_binding[32]; - GLboolean blend; - GLenum blend_src_rgb; - GLenum blend_src_alpha; - GLenum blend_dst_rgb; - GLenum blend_dst_alpha; - GLenum blend_mode_rgb; - GLenum blend_mode_alpha; - GLuint framebuffer_binding; - GLuint read_framebuffer_binding; - GLuint draw_framebuffer_binding; - GLuint vertex_array_binding; - GLuint array_buffer_binding; - GLuint element_array_buffer_binding; - GLuint uniform_buffer_binding; - GLuint uniform_buffer_bindings[14]; - GLintptr uniform_buffer_offsets[14]; - GLsizeiptr uniform_buffer_sizes[14]; - GLuint shader_storage_buffer_binding; - GLuint shader_storage_buffer_bindings[14]; - GLintptr shader_storage_buffer_offsets[14]; - GLsizeiptr shader_storage_buffer_sizes[14]; - GLboolean color_mask[4]; - GLboolean cull_face; - GLenum cull_face_mode; - GLboolean depth_test; - GLenum depth_func; - GLboolean depth_mask; - GLfloat line_width; - GLenum polygon_mode; - GLboolean multisample; - GLboolean primitive_restart; - GLuint primitive_restart_index; - gl_rend_state_rect scissor_box; - GLboolean scissor_test; - GLboolean stencil_test; - GLenum stencil_func; - GLenum stencil_fail; - GLenum stencil_dpfail; - GLenum stencil_dppass; - GLuint stencil_mask; - GLint stencil_ref; - GLuint stencil_value_mask; - gl_rend_state_rect viewport; +struct p_gl_rend_state { + struct gl_rend_state& ptr; - void active_bind_texture_2d(int32_t index, GLuint texture, bool force = false); - void active_bind_texture_cube_map(int32_t index, GLuint texture, bool force = false); - void active_texture(size_t index, bool force = false); - void bind_framebuffer(GLuint framebuffer, bool force = false); - void bind_read_framebuffer(GLuint framebuffer, bool force = false); - void bind_draw_framebuffer(GLuint framebuffer, bool force = false); - void bind_vertex_array(GLuint array, bool force = false); - void bind_array_buffer(GLuint buffer, bool force = false); - void bind_element_array_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer(GLuint buffer, bool force = false); - void bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force = false); + p_gl_rend_state(gl_rend_state_index index); + + void active_bind_texture_2d(int32_t index, GLuint texture); + void active_bind_texture_cube_map(int32_t index, GLuint texture); + void active_texture(int32_t index); + void begin_event(const char* message, int32_t length); + void bind_framebuffer(GLuint framebuffer); + void bind_read_framebuffer(GLuint framebuffer); + void bind_draw_framebuffer(GLuint framebuffer); + void bind_vertex_array(GLuint array); + void bind_array_buffer(GLuint buffer); + void bind_element_array_buffer(GLuint buffer); + void bind_uniform_buffer(GLuint buffer); + void bind_uniform_buffer_base(GLuint index, GLuint buffer); void bind_uniform_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_shader_storage_buffer(GLuint buffer, bool force = false); - void bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_shader_storage_buffer(GLuint buffer); + void bind_shader_storage_buffer_base(GLuint index, GLuint buffer); void bind_shader_storage_buffer_range(GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); - void bind_texture_2d(GLuint texture, bool force = false); - void bind_texture_cube_map(GLuint texture, bool force = false); - void bind_sampler(int32_t index, GLuint sampler, bool force = false); - bool check_uniform_buffer_binding(); - bool check_uniform_buffer_binding_base(size_t index); - bool check_shader_storage_buffer_binding(); - bool check_shader_storage_buffer_binding_base(size_t index); - bool check_texture_binding_2d(size_t index); - bool check_texture_binding_cube_map(size_t index); - bool check_sampler_binding(int32_t index, GLuint sampler); - void disable_blend(bool force = false); - void disable_cull_face(bool force = false); - void disable_depth_test(bool force = false); - void disable_multisample(bool force = false); - void disable_primitive_restart(bool force = false); - void disable_scissor_test(bool force = false); - void disable_stencil_test(bool force = false); - void enable_blend(bool force = false); - void enable_cull_face(bool force = false); - void enable_depth_test(bool force = false); - void enable_multisample(bool force = false); - void enable_primitive_restart(bool force = false); - void enable_scissor_test(bool force = false); - void enable_stencil_test(bool force = false); + GLuint buffer, GLintptr offset, GLsizeiptr size); + void bind_texture_2d(GLuint texture); + void bind_texture_cube_map(GLuint texture); + void bind_sampler(int32_t index, GLuint sampler); + void blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + GLenum check_framebuffer_status(GLenum target); + void clear(GLbitfield mask); + void clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void clear_depth(GLfloat depth); + void clear_stencil(GLint stencil); + void copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + void copy_tex_sub_image_2d(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void disable_blend(); + void disable_cull_face(); + void disable_depth_test(); + void disable_multisample(); + void disable_primitive_restart(); + void disable_scissor_test(); + void disable_stencil_test(); + void draw_arrays(GLenum mode, GLint first, GLsizei count); + void draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices); + void draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); + void enable_blend(); + void enable_cull_face(); + void enable_depth_test(); + void enable_multisample(); + void enable_primitive_restart(); + void enable_scissor_test(); + void enable_stencil_test(); + void end_event(); + void generate_mipmap(GLenum target); + void generate_texture_mipmap(GLuint texture); void get(); + void get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha); GLuint get_program(); gl_rend_state_rect get_scissor(); void get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height); gl_rend_state_rect get_viewport(); void get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height); - void set_blend_func(GLenum src, GLenum dst, bool force = false); + void set_blend_func(GLenum src, GLenum dst); void set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, - GLenum src_alpha, GLenum dst_alpha, bool force = false); - void set_blend_equation(GLenum mode, bool force = false); + GLenum src_alpha, GLenum dst_alpha); + void set_blend_equation(GLenum mode); void set_blend_equation_separate( - GLenum mode_rgb, GLenum mode_alpha, bool force = false); - void set_color_mask(GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha, bool force = false); - void set_cull_face_mode(GLenum mode, bool force = false); - void set_depth_func(GLenum func, bool force = false); - void set_depth_mask(GLboolean flag, bool force = false); - void set_line_width(GLfloat width, bool force = false); - void set_polygon_mode(GLenum face, GLenum mode, bool force = false); - void set_primitive_restart_index(GLuint index, bool force = false); - void set_scissor(const gl_rend_state_rect& rect, bool force = false); - void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void set_stencil_func(GLenum func, GLint ref, GLuint mask, bool force = false); - void set_stencil_mask(GLuint mask, bool force = false); - void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass, bool force = false); - void set_viewport(const gl_rend_state_rect& rect, bool force = false); - void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height, bool force = false); - void use_program(GLuint program, bool force = false); + GLenum mode_rgb, GLenum mode_alpha); + void set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void set_cull_face_mode(GLenum mode); + void set_depth_func(GLenum func); + void set_depth_mask(GLboolean flag); + void set_line_width(GLfloat width); + void set_primitive_restart_index(GLuint index); + void set_scissor(const gl_rend_state_rect& rect); + void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height); + void set_stencil_func(GLenum func, GLint ref, GLuint mask); + void set_stencil_mask(GLuint mask); + void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass); + void set_viewport(const gl_rend_state_rect& rect); + void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height); + void update(); + void use_program(GLuint program); template inline void begin_event(const char(&str)[size]) { - glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)(size - 1), str); + begin_event(str, (GLsizei)(size - 1)); } - - inline void end_event() { - glPopDebugGroup(); - } - }; - -extern gl_rend_state_struct gl_rend_state; diff --git a/src/DivaGL/gl_state.cpp b/src/DivaGL/gl_state.cpp new file mode 100644 index 0000000..9f68507 --- /dev/null +++ b/src/DivaGL/gl_state.cpp @@ -0,0 +1,110 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "gl_state.hpp" + +gl_state_struct gl_state; + +void gl_state_struct::bind_framebuffer(GLuint framebuffer, bool force) { + if (force || read_framebuffer_binding != framebuffer + || draw_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + read_framebuffer_binding = framebuffer; + draw_framebuffer_binding = framebuffer; + } +} + +void gl_state_struct::bind_read_framebuffer(GLuint framebuffer, bool force) { + if (force || read_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); + read_framebuffer_binding = framebuffer; + } +} + +void gl_state_struct::bind_draw_framebuffer(GLuint framebuffer, bool force) { + if (force || draw_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); + draw_framebuffer_binding = framebuffer; + } +} + +void gl_state_struct::bind_vertex_array(GLuint array, bool force) { + if (force || vertex_array_binding != array) { + glBindVertexArray(array); + vertex_array_binding = array; + } +} + +void gl_state_struct::bind_array_buffer(GLuint buffer, bool force) { + if (force || array_buffer_binding != buffer) { + glBindBuffer(GL_ARRAY_BUFFER, buffer); + array_buffer_binding = buffer; + } +} + +void gl_state_struct::bind_element_array_buffer(GLuint buffer, bool force) { + if (force || element_array_buffer_binding != buffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); + element_array_buffer_binding = buffer; + } +} + +void gl_state_struct::bind_uniform_buffer(GLuint buffer, bool force) { + if (force || uniform_buffer_binding != buffer) { + glBindBuffer(GL_UNIFORM_BUFFER, buffer); + uniform_buffer_binding = buffer; + } +} + +void gl_state_struct::bind_shader_storage_buffer(GLuint buffer, bool force) { + if (force || shader_storage_buffer_binding != buffer) { + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); + shader_storage_buffer_binding = buffer; + } +} + +void gl_state_struct::bind_texture_2d(GLuint texture, bool force) { + if (texture_binding_2d != texture) { + glBindTextureDLL(GL_TEXTURE_2D, texture); + texture_binding_2d = texture; + } +} + +void gl_state_struct::bind_texture_cube_map(GLuint texture, bool force) { + if (force || texture_binding_cube_map != texture) { + glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture); + texture_binding_cube_map = texture; + } +} + +bool gl_state_struct::check_uniform_buffer_binding() { + return uniform_buffer_binding != 0; +} + +bool gl_state_struct::check_shader_storage_buffer_binding() { + return shader_storage_buffer_binding != 0; +} + +bool gl_state_struct::check_texture_binding_2d() { + return texture_binding_2d != 0; +} + +bool gl_state_struct::check_texture_binding_cube_map() { + return texture_binding_cube_map != 0; +} + +void gl_state_struct::get() { + glGetIntegervDLL(GL_TEXTURE_BINDING_2D, (GLint*)&texture_binding_2d); + glGetIntegervDLL(GL_TEXTURE_BINDING_CUBE_MAP, (GLint*)&texture_binding_cube_map); + + glGetIntegervDLL(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&read_framebuffer_binding); + glGetIntegervDLL(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&draw_framebuffer_binding); + glGetIntegervDLL(GL_VERTEX_ARRAY_BINDING, (GLint*)&vertex_array_binding); + glGetIntegervDLL(GL_ARRAY_BUFFER_BINDING, (GLint*)&array_buffer_binding); + glGetIntegervDLL(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&element_array_buffer_binding); + + glGetIntegervDLL(GL_UNIFORM_BUFFER_BINDING, (GLint*)&uniform_buffer_binding); + glGetIntegervDLL(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&shader_storage_buffer_binding); +} diff --git a/src/DivaGL/gl_state.hpp b/src/DivaGL/gl_state.hpp new file mode 100644 index 0000000..800538e --- /dev/null +++ b/src/DivaGL/gl_state.hpp @@ -0,0 +1,39 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "wrap.hpp" + +struct gl_state_struct { + GLuint texture_binding_2d; + GLuint texture_binding_cube_map; + GLuint read_framebuffer_binding; + GLuint draw_framebuffer_binding; + GLuint vertex_array_binding; + GLuint array_buffer_binding; + GLuint element_array_buffer_binding; + GLuint uniform_buffer_binding; + GLuint shader_storage_buffer_binding; + + void bind_framebuffer(GLuint framebuffer, bool force = false); + void bind_read_framebuffer(GLuint framebuffer, bool force = false); + void bind_draw_framebuffer(GLuint framebuffer, bool force = false); + void bind_vertex_array(GLuint array, bool force = false); + void bind_array_buffer(GLuint buffer, bool force = false); + void bind_element_array_buffer(GLuint buffer, bool force = false); + void bind_uniform_buffer(GLuint buffer, bool force = false); + void bind_shader_storage_buffer(GLuint buffer, bool force = false); + void bind_texture_2d(GLuint texture, bool force = false); + void bind_texture_cube_map(GLuint texture, bool force = false); + bool check_uniform_buffer_binding(); + bool check_shader_storage_buffer_binding(); + bool check_texture_binding_2d(); + bool check_texture_binding_cube_map(); + void get(); +}; + +extern gl_state_struct gl_state; diff --git a/src/DivaGL/graphics/color_change_dw.cpp b/src/DivaGL/graphics/color_change_dw.cpp index 2d0404d..39d1398 100644 --- a/src/DivaGL/graphics/color_change_dw.cpp +++ b/src/DivaGL/graphics/color_change_dw.cpp @@ -6,7 +6,7 @@ #include "color_change_dw.hpp" #include "../../AFTModsShared/dw.hpp" #include "../rob/rob.hpp" -#include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../shared.hpp" #include "../texture.hpp" #include @@ -121,7 +121,7 @@ HOOK(void, FASTCALL, ColorChangeDw__Draw, 0x00000001402C2170, ColorChangeDw* Thi else dxt5_image_apply_color_tone(width_align, height_align, size, (dxt5_block*)data, col_tone); - gl_rend_state.bind_texture_2d(org_tex->glid); + gl_state.bind_texture_2d(org_tex->glid); int32_t width = chg_tex->get_width_mip_level(i); int32_t height = chg_tex->get_height_mip_level(i); glCompressedTexSubImage2D(org_tex->target, i, 0, 0, width, height, @@ -130,7 +130,7 @@ HOOK(void, FASTCALL, ColorChangeDw__Draw, 0x00000001402C2170, ColorChangeDw* Thi else if (chg_tex->internal_format == GL_RGB5) { rgb565_image_apply_color_tone(width_align, height_align, size, (rgb565*)data, col_tone); - gl_rend_state.bind_texture_2d(org_tex->glid); + gl_state.bind_texture_2d(org_tex->glid); int32_t width = chg_tex->get_width_mip_level(i); int32_t height = chg_tex->get_height_mip_level(i); glTexSubImage2DDLL(org_tex->target, i, 0, 0, width, height, @@ -139,7 +139,7 @@ HOOK(void, FASTCALL, ColorChangeDw__Draw, 0x00000001402C2170, ColorChangeDw* Thi gl_get_error_print(); prj::HeapCMallocFree(prj::HeapCMallocTemp, data); } - gl_rend_state.bind_texture_2d(0); + gl_state.bind_texture_2d(0); } if (This->show) { @@ -249,7 +249,7 @@ bool ColorChangeDw::LoadTexture() { return false; int32_t tex_num = objset_info_storage_get_set_tex_num(obj_set_id); - + /*for (int32_t i = 0; i < tex_num; i++) { ::texture* chg_tex = 0; ::texture* org_tex = textures[i]; @@ -281,7 +281,7 @@ bool ColorChangeDw::LoadTexture() { int32_t width_align = org_tex->get_width_align_mip_level(i); int32_t height_align = org_tex->get_height_align_mip_level(i); - gl_rend_state.bind_texture_2d(org_tex->glid); + gl_state.bind_texture_2d(org_tex->glid); if (org_tex->flags & TEXTURE_BLOCK_COMPRESSION) glGetCompressedTexImage(org_tex->target, i, data); else diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp index 480655e..c09f26a 100644 --- a/src/DivaGL/hook.cpp +++ b/src/DivaGL/hook.cpp @@ -13,6 +13,7 @@ #include "auth_3d.hpp" #include "camera.hpp" #include "effect.hpp" +#include "gl_state.hpp" #include "light_param.hpp" #include "object.hpp" #include "print.hpp" @@ -113,13 +114,15 @@ HOOK(int32_t, FASTCALL, data_free, 0x000000140192490) { return ret; } -HOOK(void, FASTCALL, sub_140194CD0, 0x000000140194CD0) { +HOOK(void, FASTCALL, display_callback, 0x000000140194CD0) { rctx->ctrl(); - originalsub_140194CD0(); + originaldisplay_callback(); + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + rend_data_ctx.state.update(); } HOOK(void, FASTCALL, gl_rend_state__get, 0x0000000140442DF0) { - gl_rend_state.get(); + } HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* rend, bool set, int32_t base_downsample) { @@ -128,11 +131,12 @@ HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* HOOK(void, FASTCALL, rndr__Render__take_ss, 0x00000001404A9CD0, rndr::Render* rend, texture* tex, bool vertical, float_t horizontal_offset) { - rend->take_ss(tex, vertical, horizontal_offset); + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + rend->take_ss(rend_data_ctx, tex, vertical, horizontal_offset); } -HOOK(void, FASTCALL, rndr__Render__init_tone_map_buffers, 0x00000001404A9FF0, rndr::Render* rend) { - rend->init_tone_map_buffers(); +HOOK(void, FASTCALL, rndr__Render__init_post_process_buffers, 0x00000001404A9FF0, rndr::Render* rend) { + rend->init_post_process_buffers(); } HOOK(void, FASTCALL, rndr__Render__init_render_buffers, 0x00000001404AB0C0, rndr::Render* rend, @@ -165,12 +169,13 @@ HOOK(void, FASTCALL, rndr__Render__movie_texture_free, 0x00000001404B18F0, } HOOK(void, FASTCALL, rndr__RenderManager__rndpass_pre_proc, 0x0000000140502C90) { - gl_rend_state.begin_event("rndpass_pre_proc"); - render_manager.render->pre_proc(); + render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); + rend_data_ctx.state.begin_event("rndpass_pre_proc"); + render_manager.render->pre_proc(rend_data_ctx); Glitter::glt_particle_manager->CalcDisp(); Glitter::glt_particle_manager_x->CalcDisp(); rctx->pre_proc(); - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } HOOK(void, FASTCALL, rndr__RenderManager__render_all, 0x0000000140502CA0) { @@ -178,40 +183,14 @@ HOOK(void, FASTCALL, rndr__RenderManager__render_all, 0x0000000140502CA0) { } HOOK(void, FASTCALL, rndr__RenderManager__rndpass_post_proc, 0x0000000140502C70) { - gl_rend_state.begin_event("rndpass_post_proc"); + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + rend_data_ctx.state.begin_event("rndpass_post_proc"); rctx->post_proc(); render_manager.render->post_proc(); render_manager.field_31C = false; - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } -struct ScreenShotData { - prj::string path; - int32_t format; - bool screen_shot_4x; - int32_t width; - int32_t height; - GLuint buffer; - const void* tex_data; -}; - -struct ScreenShotImpl { - void* __vftable; - prj::string path; - int32_t format; - bool screen_shot_4x; - int32_t width; - int32_t height; - int32_t curr_width; - int32_t curr_height; - bool capture; - texture* tex; - GLuint data_buffers[2]; - ScreenShotData ss_data[2]; - int32_t data_buffer_index; - void* thread; // Thrd_t -}; - HOOK(void, FASTCALL, shader_free, 0x00000001405E4DB0) { shaders_ft.unload(); } @@ -236,11 +215,11 @@ HOOK(int32_t, FASTCALL, shader_get_index_by_name, 0x00000001405E4ED0, const char } HOOK(void, FASTCALL, env_set_blend_color, 0x00000001405E5600, float_t r, float_t g, float_t b, float_t a) { - rctx->set_batch_blend_color({ r, g, b, a }); + } HOOK(void, FASTCALL, env_set_offset_color, 0x00000001405E5630, float_t r, float_t g, float_t b, float_t a) { - rctx->set_batch_offset_color({ r, g, b, a }); + } HOOK(void, FASTCALL, set_render_defaults, 0x00000001401948B0) { @@ -277,13 +256,13 @@ void hook_funcs() { INSTALL_HOOK(data_init); INSTALL_HOOK(data_free); - INSTALL_HOOK(sub_140194CD0); + INSTALL_HOOK(display_callback); INSTALL_HOOK(gl_rend_state__get); INSTALL_HOOK(rndr__Render__update_res); INSTALL_HOOK(rndr__Render__take_ss); - INSTALL_HOOK(rndr__Render__init_tone_map_buffers); + INSTALL_HOOK(rndr__Render__init_post_process_buffers); INSTALL_HOOK(rndr__Render__init_render_buffers); INSTALL_HOOK(rndr__Render__free); INSTALL_HOOK(rndr__Render__render_texture_set); diff --git a/src/DivaGL/light_param.cpp b/src/DivaGL/light_param.cpp index 0fc0313..fe0bf21 100644 --- a/src/DivaGL/light_param.cpp +++ b/src/DivaGL/light_param.cpp @@ -7,6 +7,7 @@ #include "../KKdLib/hash.hpp" #include "../KKdLib/str_utils.hpp" #include "../AFTModsShared/file_handler.hpp" +#include "gl_state.hpp" #include "render_context.hpp" #include @@ -241,19 +242,13 @@ void light_param_patch() { INSTALL_HOOK(light_param_data_storage__delete_textures); } -void light_param_data_storage_data_set_ibl() { - static const int32_t ibl_texture_index[] = { - 9, 10, 11, 12, 13 - }; - - for (int32_t i = 0; i < 5; i++) - gl_rend_state.active_bind_texture_cube_map(ibl_texture_index[i], - light_param_data_storage_data->textures[i]); +const GLuint* light_param_data_storage_data_get_ibl_textures() { + return light_param_data_storage_data->textures; } void light_param_data::set_ibl(const light_param_data_ibl* ibl, const light_param_data_storage* storage) { for (int32_t i = 0, j = -1; i < 5; i++, j++) { - gl_rend_state.bind_texture_cube_map(storage->textures[i]); + gl_state.bind_texture_cube_map(storage->textures[i]); glTexParameteriDLL(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteriDLL(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteriDLL(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); @@ -279,7 +274,7 @@ void light_param_data::set_ibl(const light_param_data_ibl* ibl, const light_para light_param_data::set_ibl_specular(&ibl->specular[j]); } } - gl_rend_state.bind_texture_cube_map(0); + gl_state.bind_texture_cube_map(0); ::light_set* set = &light_set_data[LIGHT_SET_MAIN]; set->set_irradiance(ibl->diff_coef[1][0], ibl->diff_coef[1][1], ibl->diff_coef[1][2]); diff --git a/src/DivaGL/light_param.hpp b/src/DivaGL/light_param.hpp index 6efe40c..f5b7582 100644 --- a/src/DivaGL/light_param.hpp +++ b/src/DivaGL/light_param.hpp @@ -6,6 +6,7 @@ #pragma once #include "../AFTModsShared/types.hpp" +#include "wrap.hpp" extern void light_param_patch(); -extern void light_param_data_storage_data_set_ibl(); +extern const GLuint* light_param_data_storage_data_get_ibl_textures(); diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 31f5b88..76bc100 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -10,6 +10,7 @@ #include "../Glitter/glitter.hpp" #include "../rob/rob.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../object.hpp" #include "../render_manager.hpp" #include "../shader_ft.hpp" @@ -49,7 +50,7 @@ static void rob_chara_item_cos_data_disp_item_object(rob_chara_item_cos_data* it object_info obj_info, const mat4& mat, int32_t item_no); static void rob_chara_item_cos_data_set_chara_index(rob_chara_item_cos_data* item_cos_data, ::chara_index chara_index); -static void sub_140436760(mat4* view); +static void sub_140436760(const cam_data& cam); extern bool reflect_draw; extern mat4 reflect_mat; @@ -293,17 +294,19 @@ namespace mdl { void DispManager::vertex_array::reset_vertex_attrib() { alive_time = 0; vertex_buffer = 0; + vertex_buffer_offset = 0; morph_vertex_buffer = 0; + morph_vertex_buffer_offset = 0; - gl_rend_state.bind_vertex_array(vertex_array); + gl_state.bind_vertex_array(vertex_array); for (int32_t i = 0; i < 16; i++) if (vertex_attrib_array[i]) { glDisableVertexAttribArray(i); vertex_attrib_array[i] = false; } - gl_rend_state.bind_array_buffer(0, true); - gl_rend_state.bind_element_array_buffer(0, true); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0, true); + gl_state.bind_element_array_buffer(0, true); + gl_state.bind_vertex_array(0); } void DispManager::add_vertex_array(ObjSubMeshArgs* args) { @@ -374,10 +377,11 @@ namespace mdl { vertex_array = &vertex_array_cache.back(); } + bool new_vertex_array = false; if (!vertex_array->vertex_array) { glGenVertexArrays(1, &vertex_array->vertex_array); - gl_rend_state.bind_vertex_array(vertex_array->vertex_array); + gl_state.bind_vertex_array(vertex_array->vertex_array); glVertexAttrib4f( POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f( BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); glVertexAttrib4f( NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); @@ -394,6 +398,7 @@ namespace mdl { glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f( BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + new_vertex_array = true; } vertex_array->vertex_buffer = vertex_buffer; @@ -409,10 +414,11 @@ namespace mdl { memcpy(&vertex_array->vertex_attrib_buffer_binding, vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)); - gl_rend_state.bind_vertex_array(vertex_array->vertex_array); - gl_rend_state.bind_array_buffer(vertex_buffer, true); + if (!new_vertex_array) + gl_state.bind_vertex_array(vertex_array->vertex_array); + gl_state.bind_array_buffer(vertex_buffer, true); if (index_buffer) - gl_rend_state.bind_element_array_buffer(index_buffer, true); + gl_state.bind_element_array_buffer(index_buffer, true); size_t offset = vertex_buffer_offset; if (vertex_format & OBJ_VERTEX_POSITION) { @@ -424,7 +430,7 @@ namespace mdl { glVertexAttribPointer(POSITION_INDEX, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; - } + } else if (vertex_array->vertex_attrib_array[POSITION_INDEX]) { glDisableVertexAttribArray(POSITION_INDEX); vertex_array->vertex_attrib_array[POSITION_INDEX] = false; @@ -651,7 +657,7 @@ namespace mdl { } if (morph_vertex_buffer) { - gl_rend_state.bind_array_buffer(morph_vertex_buffer, true); + gl_state.bind_array_buffer(morph_vertex_buffer, true); size_t offset = morph_vertex_buffer_offset; if (vertex_format & OBJ_VERTEX_POSITION) { @@ -802,8 +808,6 @@ namespace mdl { } if (vertex_format & OBJ_VERTEX_COLOR0) { - uniform->arr[U_MORPH_COLOR] = 1; - if (!vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { glEnableVertexAttribArray(MORPH_COLOR_INDEX); vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = true; @@ -883,10 +887,10 @@ namespace mdl { } } - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); if (index_buffer) - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_element_array_buffer(0); } static size_t gen_grid_vertices(prj::vector>& data, @@ -1647,10 +1651,11 @@ namespace mdl { etc_vertex_array = &etc_vertex_array_cache.back(); } + bool new_vertex_array = false; if (!etc_vertex_array->vertex_array) { glGenVertexArrays(1, &etc_vertex_array->vertex_array); - gl_rend_state.bind_vertex_array(etc_vertex_array->vertex_array); + gl_state.bind_vertex_array(etc_vertex_array->vertex_array); glVertexAttrib4f( POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f( BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); glVertexAttrib4f( NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); @@ -1667,11 +1672,13 @@ namespace mdl { glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); glVertexAttrib4f( BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + new_vertex_array = true; } etc_vertex_array->alive_time = 2; etc_vertex_array->data = etc->data; etc_vertex_array->type = type; + etc_vertex_array->indexed = indexed; prj::vector> vtx_data; prj::vector vtx_indices; @@ -1787,20 +1794,21 @@ namespace mdl { GLsizei size_vertex = sizeof(vec3) * 2; - gl_rend_state.bind_vertex_array(etc_vertex_array->vertex_array); + if (!new_vertex_array) + gl_state.bind_vertex_array(etc_vertex_array->vertex_array); if (etc_vertex_array->vertex_buffer.IsNull()) - etc_vertex_array->vertex_buffer.Create(sizeof(vec3) * 2 * vtx_data.size()); + etc_vertex_array->vertex_buffer.Create(gl_state, sizeof(vec3) * 2 * vtx_data.size()); - etc_vertex_array->vertex_buffer.Bind(true); + gl_state.bind_array_buffer(etc_vertex_array->vertex_buffer, true); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3) * 2 * vtx_data.size(), vtx_data.data()); if (indexed) { if (etc_vertex_array->index_buffer.IsNull()) - etc_vertex_array->index_buffer.Create(sizeof(uint32_t) * vtx_indices.size()); + etc_vertex_array->index_buffer.Create(gl_state, sizeof(uint32_t) * vtx_indices.size()); - etc_vertex_array->index_buffer.Bind(true); + gl_state.bind_element_array_buffer(etc_vertex_array->index_buffer, true); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint32_t) * vtx_indices.size(), vtx_indices.data()); } @@ -1813,10 +1821,10 @@ namespace mdl { glVertexAttribPointer(NORMAL_INDEX, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)sizeof(vec3)); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); if (indexed) - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_element_array_buffer(0); } void* DispManager::alloc_data(int32_t size) { @@ -1853,7 +1861,7 @@ namespace mdl { buff_offset = 0; } - void DispManager::calc_obj_radius(mat4* view, ObjType type) { + void DispManager::calc_obj_radius(const cam_data& cam, ObjType type) { prj::vector alpha_center; prj::vector mat_center; @@ -1864,9 +1872,9 @@ namespace mdl { case OBJ_KIND_NORMAL: { mat4 mat = i->mat; if (i->args.sub_mesh.mesh->attrib.m.billboard) - model_mat_face_camera_view(view, &mat, &mat); + model_mat_face_camera_view(cam, &mat, &mat); else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) - model_mat_face_camera_position(view, &mat, &mat); + model_mat_face_camera_position(cam, &mat, &mat); get_obj_center(mat, &i->args.sub_mesh, center); @@ -1900,7 +1908,7 @@ namespace mdl { if (show_mat_center && type == OBJ_TYPE_TRANSLUCENT && v50) mat_center.push_back(center); - mat4_transform_point(view, ¢er, ¢er); + mat4_transform_point(&cam.get_view_mat(), ¢er, ¢er); i->view_z = center.z; } @@ -1935,7 +1943,7 @@ namespace mdl { } } - void DispManager::calc_obj_radius(mat4* view, ObjTypeLocal type) { + void DispManager::calc_obj_radius(const cam_data& cam, ObjTypeLocal type) { for (ObjData*& i : get_obj_list(type)) { vec3 center = 0.0f; bool v50 = false; @@ -1943,9 +1951,9 @@ namespace mdl { case OBJ_KIND_NORMAL: { mat4 mat = i->mat; if (i->args.sub_mesh.mesh->attrib.m.billboard) - model_mat_face_camera_view(view, &mat, &mat); + model_mat_face_camera_view(cam, &mat, &mat); else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) - model_mat_face_camera_position(view, &mat, &mat); + model_mat_face_camera_position(cam, &mat, &mat); get_obj_center(mat, &i->args.sub_mesh, center); @@ -1970,13 +1978,12 @@ namespace mdl { break; } - mat4_transform_point(view, ¢er, ¢er); + mat4_transform_point(&cam.get_view_mat(), ¢er, ¢er); i->view_z = center.z; } - } - void DispManager::calc_obj_radius(mat4* view, ObjTypeReflect type) { + void DispManager::calc_obj_radius(const cam_data& cam, ObjTypeReflect type) { for (ObjData*& i : get_obj_list(type)) { vec3 center = 0.0f; bool v50 = false; @@ -1984,9 +1991,9 @@ namespace mdl { case OBJ_KIND_NORMAL: { mat4 mat = i->mat; if (i->args.sub_mesh.mesh->attrib.m.billboard) - model_mat_face_camera_view(view, &mat, &mat); + model_mat_face_camera_view(cam, &mat, &mat); else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) - model_mat_face_camera_position(view, &mat, &mat); + model_mat_face_camera_position(cam, &mat, &mat); get_obj_center(mat, &i->args.sub_mesh, center); @@ -2011,10 +2018,9 @@ namespace mdl { break; } - mat4_transform_point(view, ¢er, ¢er); + mat4_transform_point(&cam.get_view_mat(), ¢er, ¢er); i->view_z = center.z; } - } void DispManager::check_index_buffer(GLuint buffer) { @@ -2030,12 +2036,13 @@ namespace mdl { for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) if (i.alive_time > 0 && --i.alive_time <= 0) { - gl_rend_state.bind_vertex_array(i.vertex_array); + gl_state.bind_vertex_array(i.vertex_array); glDisableVertexAttribArray(POSITION_INDEX); glDisableVertexAttribArray(NORMAL_INDEX); - gl_rend_state.bind_array_buffer(0, true); - gl_rend_state.bind_element_array_buffer(0, true); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + if (i.indexed) + gl_state.bind_element_array_buffer(0); + gl_state.bind_vertex_array(0); } } @@ -2046,31 +2053,32 @@ namespace mdl { i.reset_vertex_attrib(); } - void DispManager::draw(ObjType type, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) { + void DispManager::draw(render_data_context& rend_data_ctx, ObjType type, + const cam_data& cam, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) { if (type < 0 || type >= OBJ_TYPE_MAX || get_obj_count(type) < 1) return; int32_t alpha_test = 0; float_t min_alpha = 1.0f; float_t alpha_threshold = 0.0f; - bool reflect = uniform->arr[U_REFLECT] == 1; - void(*func)(const ObjSubMeshArgs * args) = draw_sub_mesh_default; + bool reflect = rend_data_ctx.shader_flags.arr[U_REFLECT] == 1; + void(*func)(render_data_context & rend_data_ctx, const ObjSubMeshArgs * args, + const cam_data & cam, const mat4 * mat) = draw_sub_mesh_default; for (int32_t i = 0; i < 5; i++) - gl_rend_state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); - gl_rend_state.active_texture(0); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_rend_state.get(); + rend_data_ctx.state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); + rend_data_ctx.state.active_texture(0); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.reset_shader_flags(); switch (type) { case OBJ_TYPE_TRANSLUCENT: case OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS: if (depth_mask) - func = draw_sub_mesh_translucent; + func = draw_sub_mesh_no_mat; else - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); alpha_test = 1; min_alpha = 0.0f; @@ -2088,43 +2096,43 @@ namespace mdl { func = draw_sub_mesh_shadow; break; case OBJ_TYPE_TYPE_6: - func = draw_sub_mesh_translucent; - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - draw_state.shader_index = SHADER_FT_SIL; + func = draw_sub_mesh_no_mat; + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SIL; break; case OBJ_TYPE_TYPE_7: - func = draw_sub_mesh_translucent; - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - draw_state.shader_index = SHADER_FT_SIL; + func = draw_sub_mesh_no_mat; + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SIL; alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.99999994f; break; case OBJ_TYPE_REFLECT_CHARA_OPAQUE: - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); if (!reflect_draw) { if (reflect) - func = draw_sub_mesh_reflect; + func = draw_sub_mesh_cheap; else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; + func = draw_sub_mesh_cheap_reflect_map; } break; case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); min_alpha = 0.0f; if (!reflect_draw) { if (reflect) - func = draw_sub_mesh_reflect; + func = draw_sub_mesh_cheap; else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; + func = draw_sub_mesh_cheap_reflect_map; } break; case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); alpha_test = 1; min_alpha = 0.1f; @@ -2132,9 +2140,9 @@ namespace mdl { if (!reflect_draw) { if (reflect) - func = draw_sub_mesh_reflect; + func = draw_sub_mesh_cheap; else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; + func = draw_sub_mesh_cheap_reflect_map; } break; case OBJ_TYPE_REFLECT_OPAQUE: @@ -2142,18 +2150,18 @@ namespace mdl { alpha_threshold = 0.5f; if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); else if (!reflect_texture_mask) - func = draw_sub_mesh_reflect_reflect_map; + func = draw_sub_mesh_cheap_reflect_map; break; case OBJ_TYPE_REFLECT_TRANSLUCENT: - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); min_alpha = 0.0f; alpha_threshold = 0.0f; if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_REFLECT_TRANSPARENT: alpha_test = 1; @@ -2161,10 +2169,10 @@ namespace mdl { alpha_threshold = 0.5f; if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_REFRACT_TRANSLUCENT: - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); min_alpha = 0.0f; alpha_threshold = 0.0f; @@ -2178,7 +2186,7 @@ namespace mdl { func = draw_sub_mesh_sss; if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: @@ -2190,35 +2198,35 @@ namespace mdl { case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.0f; break; case OBJ_TYPE_USER: - func = draw_sub_mesh_translucent; + func = draw_sub_mesh_no_mat; break; } - rctx->set_batch_alpha_threshold(alpha_threshold); - rctx->set_batch_min_alpha(min_alpha); - uniform->arr[U_ALPHA_TEST] = alpha_test; + rend_data_ctx.set_batch_alpha_threshold(alpha_threshold); + rend_data_ctx.set_batch_min_alpha(min_alpha); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = alpha_test; if (alpha < 0) for (ObjData*& i : get_obj_list(type)) { switch (i->kind) { case OBJ_KIND_NORMAL: { - draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); } break; case OBJ_KIND_ETC: { - draw_etc_obj(&i->args.etc, &i->mat); + draw_etc_obj(rend_data_ctx, &i->args.etc, &i->mat); } break; case OBJ_KIND_USER: { - i->args.user.func(i->args.user.data, &i->mat); + i->args.user.func(rend_data_ctx, i->args.user.data, cam, &i->mat); } break; case OBJ_KIND_TRANSLUCENT: { for (int32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); + draw_sub_mesh(rend_data_ctx, i->args.translucent.sub_mesh[j], &i->mat, func, cam); } break; } } @@ -2229,7 +2237,7 @@ namespace mdl { int32_t a = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); a = clamp_def(a, 0, 255); if (a == alpha) - draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); } break; case OBJ_KIND_TRANSLUCENT: { for (int32_t j = 0; j < i->args.translucent.count; j++) { @@ -2237,7 +2245,7 @@ namespace mdl { int32_t a = (int32_t)(args->blend_color.w * 255.0f); a = clamp_def(a, 0, 255); if (a == alpha) - draw_sub_mesh(args, &i->mat, func); + draw_sub_mesh(rend_data_ctx, args, &i->mat, func, cam); } } break; } @@ -2247,78 +2255,79 @@ namespace mdl { case OBJ_TYPE_TRANSLUCENT: case OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS: if (!depth_mask) - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_depth_mask(GL_TRUE); break; case OBJ_TYPE_TYPE_6: case OBJ_TYPE_TYPE_7: - draw_state.shader_index = -1; - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); break; case OBJ_TYPE_REFLECT_CHARA_OPAQUE: case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; case OBJ_TYPE_REFLECT_OPAQUE: if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_REFLECT_TRANSLUCENT: if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_depth_mask(GL_TRUE); break; case OBJ_TYPE_REFLECT_TRANSPARENT: if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_REFRACT_TRANSLUCENT: if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_FRONT); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_depth_mask(GL_TRUE); break; case OBJ_TYPE_SSS: if (reflect_draw) - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_depth_mask(GL_TRUE); break; } - uniform_value_reset(); - gl_rend_state.bind_vertex_array(0); - shader::unbind(); - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.reset_shader_flags(); + rend_data_ctx.state.bind_vertex_array(0); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); for (int32_t i = 0; i < 5; i++) - gl_rend_state.bind_sampler(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); } - void DispManager::draw(mdl::ObjTypeLocal type, int32_t depth_mask) { + void DispManager::draw(render_data_context& rend_data_ctx, mdl::ObjTypeLocal type, + const cam_data& cam, int32_t depth_mask, bool reflect_texture_mask) { if (type < 0 || type >= OBJ_TYPE_LOCAL_MAX || get_obj_count(type) < 1) return; int32_t alpha_test = 0; float_t min_alpha = 1.0f; float_t alpha_threshold = 0.0f; - void(*func)(const ObjSubMeshArgs * args) = draw_sub_mesh_default; + void(*func)(render_data_context & rend_data_ctx, const ObjSubMeshArgs * args, + const cam_data & cam, const mat4 * mat) = draw_sub_mesh_default; for (int32_t i = 0; i < 5; i++) - gl_rend_state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); - gl_rend_state.active_texture(0); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_rend_state.get(); + rend_data_ctx.state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); + rend_data_ctx.state.active_texture(0); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.reset_shader_flags(); switch (type) { case OBJ_TYPE_LOCAL_TRANSLUCENT: if (depth_mask) - func = draw_sub_mesh_translucent; + func = draw_sub_mesh_no_mat; else - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); alpha_test = 1; min_alpha = 0.0f; @@ -2330,18 +2339,18 @@ namespace mdl { alpha_threshold = 0.5f; break; } - rctx->set_batch_alpha_threshold(alpha_threshold); - rctx->set_batch_min_alpha(min_alpha); - uniform->arr[U_ALPHA_TEST] = alpha_test; + rend_data_ctx.set_batch_alpha_threshold(alpha_threshold); + rend_data_ctx.set_batch_min_alpha(min_alpha); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = alpha_test; for (ObjData*& i : get_obj_list(type)) { switch (i->kind) { case OBJ_KIND_NORMAL: { - draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); } break; case OBJ_KIND_TRANSLUCENT: { for (int32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); + draw_sub_mesh(rend_data_ctx, i->args.translucent.sub_mesh[j], &i->mat, func, cam); } break; } } @@ -2349,62 +2358,63 @@ namespace mdl { switch (type) { case OBJ_TYPE_LOCAL_TRANSLUCENT: if (!depth_mask) - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_depth_mask(GL_TRUE); break; } - uniform_value_reset(); - gl_rend_state.bind_vertex_array(0); - shader::unbind(); - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.reset_shader_flags(); + rend_data_ctx.state.bind_vertex_array(0); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); for (int32_t i = 0; i < 5; i++) - gl_rend_state.bind_sampler(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); } - void DispManager::draw(mdl::ObjTypeReflect type, int32_t depth_mask) { + void DispManager::draw(render_data_context& rend_data_ctx, mdl::ObjTypeReflect type, + const cam_data& cam, int32_t depth_mask, bool reflect_texture_mask) { if (type < 0 || type >= OBJ_TYPE_REFLECT_MAX || get_obj_count(type) < 1) return; int32_t alpha_test = 0; float_t min_alpha = 1.0f; float_t alpha_threshold = 0.0f; - bool reflect = uniform->arr[U_REFLECT] == 1; - void(*func)(const ObjSubMeshArgs * args) = draw_sub_mesh_default; + bool reflect = rend_data_ctx.shader_flags.arr[U_REFLECT] == 1; + void(*func)(render_data_context & rend_data_ctx, const ObjSubMeshArgs * args, + const cam_data & cam, const mat4 * mat) = draw_sub_mesh_default; for (int32_t i = 0; i < 5; i++) - gl_rend_state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); - gl_rend_state.active_texture(0); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_rend_state.get(); + rend_data_ctx.state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); + rend_data_ctx.state.active_texture(0); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.reset_shader_flags(); switch (type) { case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS: if (depth_mask) - func = draw_sub_mesh_translucent; + func = draw_sub_mesh_no_mat; else - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.0f; - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; } - rctx->set_batch_alpha_threshold(alpha_threshold); - rctx->set_batch_min_alpha(min_alpha); - uniform->arr[U_ALPHA_TEST] = alpha_test; + rend_data_ctx.set_batch_alpha_threshold(alpha_threshold); + rend_data_ctx.set_batch_min_alpha(min_alpha); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = alpha_test; for (ObjData*& i : get_obj_list(type)) { switch (i->kind) { case OBJ_KIND_NORMAL: { - draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); } break; case OBJ_KIND_TRANSLUCENT: { for (int32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); + draw_sub_mesh(rend_data_ctx, i->args.translucent.sub_mesh[j], &i->mat, func, cam); } break; } } @@ -2412,16 +2422,16 @@ namespace mdl { switch (type) { case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS: if (!depth_mask) - gl_rend_state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; } - uniform_value_reset(); - gl_rend_state.bind_vertex_array(0); - shader::unbind(); - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.reset_shader_flags(); + rend_data_ctx.state.bind_vertex_array(0); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); for (int32_t i = 0; i < 5; i++) - gl_rend_state.bind_sampler(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); } /*void DispManager::draw_show_vector(ObjType type, int32_t show_vector) { @@ -2431,12 +2441,12 @@ namespace mdl { render_context* rctx = rctx_ptr; for (int32_t i = 0; i < 5; i++) - gl_rend_state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); - gl_rend_state.active_texture(0); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_rend_state.get(); + rend_data_ctx.state.active_bind_texture_2d(i, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); + rend_data_ctx.state.active_texture(0); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.reset_shader_flags(); + rend_data_ctx.state.get(); for (ObjData*& i : get_obj_list(type)) { switch (i->type) { @@ -2451,7 +2461,7 @@ namespace mdl { } break; } } - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); }*/ void DispManager::entry_list(ObjType type, ObjData* data) { @@ -3654,11 +3664,11 @@ namespace mdl { int32_t DispManager::get_obj_count(ObjType type) { return (int32_t)get_obj_list(type).size(); } - + int32_t DispManager::get_obj_count(ObjTypeLocal type) { return (int32_t)get_obj_list(type).size(); } - + int32_t DispManager::get_obj_count(ObjTypeReflect type) { return (int32_t)get_obj_list(type).size(); } @@ -3705,15 +3715,16 @@ namespace mdl { return wet_param; } - void DispManager::obj_sort(mat4* view, ObjType type, int32_t compare_func, bool a3) { + void DispManager::obj_sort(render_data_context& rend_data_ctx, + ObjType type, int32_t compare_func, const cam_data& cam, bool a3) { prj::list& list = get_obj_list(type); if (list.size() < 1) return; if (a3 && type == OBJ_TYPE_TRANSLUCENT) - sub_140436760(view); + sub_140436760(cam); - calc_obj_radius(view, type); + calc_obj_radius(cam, type); switch (compare_func) { case 0: @@ -3734,12 +3745,13 @@ namespace mdl { } } - void DispManager::obj_sort(mat4* view, ObjTypeLocal type, int32_t compare_func, bool a3) { + void DispManager::obj_sort(render_data_context& rend_data_ctx, + ObjTypeLocal type, int32_t compare_func, const cam_data& cam) { prj::list& list = get_obj_list(type); if (list.size() < 1) return; - calc_obj_radius(view, type); + calc_obj_radius(cam, type); switch (compare_func) { case 0: @@ -3760,12 +3772,13 @@ namespace mdl { } } - void DispManager::obj_sort(mat4* view, ObjTypeReflect type, int32_t compare_func, bool a3) { + void DispManager::obj_sort(render_data_context& rend_data_ctx, + ObjTypeReflect type, int32_t compare_func, const cam_data& cam) { prj::list& list = get_obj_list(type); if (list.size() < 1) return; - calc_obj_radius(view, type); + calc_obj_radius(cam, type); switch (compare_func) { case 0: @@ -4150,7 +4163,7 @@ static void rob_chara_item_cos_data_set_chara_index(rob_chara_item_cos_data* ite item_cos_data->chara_index = chara_index; } -static void sub_140436760(mat4* view) { +static void sub_140436760(const cam_data& cam) { for (auto& i : disp_manager->obj[mdl::OBJ_TYPE_TRANSLUCENT]) { if (i->kind != mdl::OBJ_KIND_NORMAL) continue; @@ -4184,7 +4197,7 @@ static void sub_140436760(mat4* view) { mat4 mat; mat4_transpose(&i->mat, &mat); mat4_mul_translate(&mat, &aabb->center, &mat); - mat4_mul(&mat, view, &mat); + mat4_mul(&mat, &cam.get_view_mat(), &mat); mat4_transpose(&mat, &mat); vec4 t; diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index 47d2076..5fb1efa 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -19,6 +19,9 @@ #define TEXTURE_PATTERN_COUNT 24 #define TEXTURE_TRANSFORM_COUNT 24 +struct cam_data; +struct render_data_context; + namespace mdl { enum EtcObjType { ETC_OBJ_TEAPOT = 0, @@ -101,6 +104,9 @@ struct material_list_struct { vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission); }; +struct cam_data; +struct render_data_context; + namespace mdl { struct ObjSubMeshArgs; @@ -202,7 +208,7 @@ namespace mdl { EtcObjCross(); }; - + struct EtcObjCapsule { // Added float_t radius; int32_t slices; @@ -251,7 +257,7 @@ namespace mdl { ~EtcObj(); }; - typedef void(*UserArgsFunc)(void* data, mat4* mat); + typedef void(*UserArgsFunc)(render_data_context& rend_data_ctx, void* data, const cam_data& cam, mat4* mat); struct UserArgs { UserArgsFunc func; @@ -283,7 +289,7 @@ namespace mdl { float_t view_z; float_t radius; Args args; - + ObjData(); ~ObjData(); @@ -342,6 +348,7 @@ namespace mdl { GLuint vertex_array; EtcObj::Data data; EtcObjType type; + bool indexed; GLsizei count; size_t offset; GLsizei wire_count; @@ -384,16 +391,18 @@ namespace mdl { ObjData* alloc_obj_data(ObjKind kind); mat4* alloc_mat4_array(int32_t count); void buffer_reset(); - void calc_obj_radius(mat4* view, ObjType type); - void calc_obj_radius(mat4* view, ObjTypeLocal type); - void calc_obj_radius(mat4* view, ObjTypeReflect type); + void calc_obj_radius(const cam_data& cam, ObjType type); + void calc_obj_radius(const cam_data& cam, ObjTypeLocal type); + void calc_obj_radius(const cam_data& cam, ObjTypeReflect type); void check_index_buffer(GLuint buffer); void check_vertex_arrays(); void check_vertex_buffer(GLuint buffer); - void draw(ObjType type, int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); - void draw(ObjTypeLocal type, int32_t depth_mask = 0); - void draw(ObjTypeReflect type, int32_t depth_mask = 0); - /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ + void draw(render_data_context& rend_data_ctx, ObjType type, const cam_data& cam, + int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); + void draw(render_data_context& rend_data_ctx, ObjTypeLocal type, const cam_data& cam, + int32_t depth_mask = 0, bool reflect_texture_mask = true); + void draw(render_data_context& rend_data_ctx, ObjTypeReflect type, const cam_data& cam, + int32_t depth_mask = 0, bool reflect_texture_mask = true); void entry_list(ObjType type, ObjData* data); void entry_list(ObjTypeLocal type, ObjData* data); void entry_list(ObjTypeReflect type, ObjData* data); @@ -446,9 +455,12 @@ namespace mdl { void get_texture_specular_offset(vec4& value); void get_texture_transform(int32_t& count, texture_transform_struct*& value); float_t get_wet_param(); - void obj_sort(mat4* view, ObjType type, int32_t compare_func, bool a3 = false); - void obj_sort(mat4* view, ObjTypeLocal type, int32_t compare_func, bool a3 = false); - void obj_sort(mat4* view, ObjTypeReflect type, int32_t compare_func, bool a3 = false); + void obj_sort(render_data_context& rend_data_ctx, + ObjType type, int32_t compare_func, const cam_data& cam, bool a3 = false); + void obj_sort(render_data_context& rend_data_ctx, + ObjTypeLocal type, int32_t compare_func, const cam_data& cam); + void obj_sort(render_data_context& rend_data_ctx, + ObjTypeReflect type, int32_t compare_func, const cam_data& cam); void refresh(); void set_chara_color(bool value = false); void set_culling_func(bool(FASTCALL* func)(const obj_bounding_sphere*) = 0); diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp index 909ccf1..4d833a1 100644 --- a/src/DivaGL/mdl/draw_object.cpp +++ b/src/DivaGL/mdl/draw_object.cpp @@ -9,31 +9,37 @@ #include "../shader_ft.hpp" #include "../texture.hpp" -static bool draw_object_blend_set( +static bool draw_object_blend_set(render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args, obj_material_shader_lighting_type lighting_type); static bool draw_object_blend_set_check_use_default_blend(int32_t index); -static void draw_object_chara_color_fog_set( +static void draw_object_chara_color_fog_set(render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args, bool disable_fog); -static void draw_object_material_reset_default(const obj_material_data* mat_data); -static void draw_object_material_reset_reflect(); -static void draw_object_material_set_default( +static void draw_object_material_reset_cheap(render_data_context& rend_data_ctx); +static void draw_object_material_reset_default( + render_data_context& rend_data_ctx, const obj_material_data* mat_data); +static void draw_object_material_set_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args); +static void draw_object_material_set_default(render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args, bool use_shader); static void draw_object_material_set_parameter( - const obj_material_data* mat_data); -static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args); -static void draw_object_material_set_uniform(const obj_material_data* mat_data, bool disable_color_l); -static void draw_object_model_mat_load(const mat4& mat); -static void draw_object_vertex_attrib_reset_default(const mdl::ObjSubMeshArgs* args); -static void draw_object_vertex_attrib_reset_reflect(const mdl::ObjSubMeshArgs* args); -static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* args); -static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* args); + render_data_context& rend_data_ctx, const obj_material_data* mat_data); +static void draw_object_material_set_uniform(render_data_context& rend_data_ctx, + const obj_material_data* mat_data, bool disable_color_l); +static void draw_object_vertex_attrib_reset_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_reset_default( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_set_default( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_set_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args); static bool(FASTCALL* use_shader_get)() = (bool(FASTCALL*)())0x0000000140440E30; extern bool config_shared_storage_uniform_buffer; namespace mdl { - void draw(obj_primitive_type primitive_type, uint32_t count, + void draw(render_data_context& rend_data_ctx, obj_primitive_type primitive_type, uint32_t count, uint16_t start, uint16_t end, obj_index_format index_format, size_t indices) { GLenum mesh_draw_mode[] = { GL_ZERO, //GL_POINTS, @@ -54,23 +60,24 @@ namespace mdl { GL_UNSIGNED_INT, }; - rctx->set_render_data(); + rend_data_ctx.set_render_data_state(); if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP && index_format == OBJ_INDEX_U16) - shaders_ft.draw_range_elements(GL_TRIANGLE_STRIP, + rend_data_ctx.state.draw_range_elements(GL_TRIANGLE_STRIP, start, end, count, GL_UNSIGNED_SHORT, (void*)indices); else - shaders_ft.draw_elements(mesh_draw_mode[primitive_type], + rend_data_ctx.state.draw_elements(mesh_draw_mode[primitive_type], count, mesh_indices_type[index_format], (void*)indices); - draw_state.stats.draw_count += count; + draw_state_stats& stats = rctx->draw_state_rend_data[rend_data_ctx.index].stats; + stats.draw_count += count; if (primitive_type == OBJ_PRIMITIVE_TRIANGLES) - draw_state.stats.draw_triangle_count += count / 3; + stats.draw_triangle_count += count / 3; else if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP) - draw_state.stats.draw_triangle_count += count - 2; + stats.draw_triangle_count += count - 2; } - void draw_etc_obj(const mdl::EtcObj* etc, const mat4* mat) { + void draw_etc_obj(render_data_context& rend_data_ctx, const mdl::EtcObj* etc, const mat4* mat) { switch (etc->type) { case mdl::ETC_OBJ_TEAPOT: case mdl::ETC_OBJ_GRID: @@ -94,7 +101,7 @@ namespace mdl { if (!vao) return; - draw_object_model_mat_load(*mat); + rend_data_ctx.set_batch_worlds(*mat); const vec4 color = etc->color; @@ -105,159 +112,172 @@ namespace mdl { vec4 emission = etc->constant ? 1.0f : vec4(0.0f, 0.0f, 0.0f, 1.0f); vec4 specular = { 0.0f, 0.0f, 0.0f, 1.0f }; - rctx->set_batch_material_color(diffuse, ambient, emission, + rend_data_ctx.set_batch_material_color(diffuse, ambient, emission, 0.0f, specular, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); - rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(1.0f, 0.0f); } else - rctx->set_batch_blend_color_offset_color(color, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(color, 0.0f); - gl_rend_state.bind_vertex_array(vao); - //rctx->set_shader(SHADER_FT_SIMPLE); - rctx->set_shader(etc->constant ? SHADER_FT_CONSTANT : SHADER_FT_SIMPLE); - rctx->set_render_data(); + rend_data_ctx.state.bind_vertex_array(vao); + //rend_data_ctx.set_shader(SHADER_FT_SIMPLE); + rend_data_ctx.set_shader(etc->constant ? SHADER_FT_CONSTANT : SHADER_FT_SIMPLE); + rend_data_ctx.set_render_data_state(); switch (etc->type) { case mdl::ETC_OBJ_TEAPOT: - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); break; case mdl::ETC_OBJ_GRID: - gl_rend_state.set_line_width(0.2f); - shaders_ft.draw_arrays(GL_LINES, 0, etc->count); - gl_rend_state.set_line_width(2.0f); - shaders_ft.draw_arrays(GL_LINES, (GLint)etc->count, 4); - gl_rend_state.set_line_width(1.0f); + rend_data_ctx.state.set_line_width(0.2f); + rend_data_ctx.state.draw_arrays(GL_LINES, 0, etc->count); + rend_data_ctx.state.set_line_width(2.0f); + rend_data_ctx.state.draw_arrays(GL_LINES, (GLint)etc->count, 4); + rend_data_ctx.state.set_line_width(1.0f); break; case mdl::ETC_OBJ_CUBE: if (etc->data.sphere.wire) - shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); else - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; case mdl::ETC_OBJ_SPHERE: if (etc->data.sphere.wire) - shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); else - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; case mdl::ETC_OBJ_PLANE: - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, etc->count); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, etc->count); break; case mdl::ETC_OBJ_CONE: if (etc->data.cone.wire) - shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); else - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; case mdl::ETC_OBJ_LINE: - shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + rend_data_ctx.state.draw_arrays(GL_LINES, 0, etc->count); break; case mdl::ETC_OBJ_CROSS: - shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + rend_data_ctx.state.draw_arrays(GL_LINES, 0, etc->count); break; case mdl::ETC_OBJ_CAPSULE: // Added if (etc->data.capsule.wire) - shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); else - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; case mdl::ETC_OBJ_CYLINDER: // Added if (etc->data.cylinder.wire) - shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); else - shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + rend_data_ctx.state.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; } - shader::unbind(); - uniform_value_reset(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.reset_shader_flags(); - rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(1.0f, 0.0f); } - void draw_sub_mesh(const ObjSubMeshArgs* args, const mat4* mat, - void(*func)(const ObjSubMeshArgs* args)) { + void draw_sub_mesh(render_data_context& rend_data_ctx, const ObjSubMeshArgs* args, + const mat4* mat, void(*func)(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat), const cam_data& cam) { GLuint vao = disp_manager->get_vertex_array(args); if (!vao) return; if (args->mats) { - const mat4* mats = args->mats; + rend_data_ctx.set_skinning_data(rend_data_ctx.state, args->mats, args->mat_count); - if (args->mat_count == 2) - rctx->set_batch_joint(mats[0]); + rend_data_ctx.set_batch_worlds(mat4_identity); - if (config_shared_storage_uniform_buffer) { - GLuint buffer = 0; - size_t offset = 0; - size_t size = 0; - if (rctx->get_shared_storage_uniform_buffer_data( - (size_t)args->mats, buffer, offset, size, !!DIVA_GL_VERSION_4_3)) - if (DIVA_GL_VERSION_4_3) - gl_rend_state.bind_shader_storage_buffer_range(0, buffer, (GLintptr)offset, (GLsizeiptr)size); - else - gl_rend_state.bind_uniform_buffer_range(6, buffer, (GLintptr)offset, (GLsizeiptr)size); - } - else { - vec4* g_joint_transforms = rctx->data.buffer_skinning_data.g_joint_transforms; - - mat4 mat; - for (int32_t i = 0; i < args->mat_count; i++, mats++, g_joint_transforms += 3) { - mat4_transpose(mats, &mat); - g_joint_transforms[0] = mat.row0; - g_joint_transforms[1] = mat.row1; - g_joint_transforms[2] = mat.row2; - } - - if (DIVA_GL_VERSION_4_3) - rctx->data.buffer_skinning.WriteMemory(rctx->data.buffer_skinning_data); - else - rctx->data.buffer_skinning_ubo.WriteMemory(0, - sizeof(vec4) * 3 * args->mat_count, &rctx->data.buffer_skinning_data); - } - - rctx->set_batch_worlds(mat4_identity); - - uniform->arr[U_SKINNING] = 1; - gl_rend_state.bind_vertex_array(vao); - func(args); - uniform->arr[U_SKINNING] = 0; + rend_data_ctx.shader_flags.arr[U_SKINNING] = 1; + rend_data_ctx.state.bind_vertex_array(vao); + func(rend_data_ctx, args, cam, mat); + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; } else { mat4 _mat; if (args->mesh->attrib.m.billboard) - model_mat_face_camera_view(&rctx->view_mat, mat, &_mat); + model_mat_face_camera_view(cam, mat, &_mat); else if (args->mesh->attrib.m.billboard_y_axis) - model_mat_face_camera_position(&rctx->view_mat, mat, &_mat); + model_mat_face_camera_position(cam, mat, &_mat); else _mat = *mat; - uniform->arr[U_SKINNING] = 0; - gl_rend_state.bind_vertex_array(vao); + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; + rend_data_ctx.state.bind_vertex_array(vao); if (func != draw_sub_mesh_default || !args->instances_count) { - draw_object_model_mat_load(_mat); - func(args); + rend_data_ctx.set_batch_worlds(_mat); + func(rend_data_ctx, args, cam, &_mat); } else - draw_sub_mesh_default_instanced(args, &_mat); - uniform->arr[U_SKINNING] = 0; + draw_sub_mesh_default_instanced(rend_data_ctx, args, cam, &_mat); + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; } } - /*void draw_sub_mesh_show_vector( - const ObjSubMeshArgs* args, mat4* model, int32_t show_vector) { - return; - }*/ - - void draw_sub_mesh_default(const ObjSubMeshArgs* args) { - if (args->set_blend_color) - rctx->set_batch_blend_color_offset_color(args->blend_color, 0.0f); - - if (!args->func) - draw_object_vertex_attrib_set_default(args); - - draw_object_material_set_default(args, use_shader_get()); + void draw_sub_mesh_cheap(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { + const obj_material_data* material = args->material; + draw_object_vertex_attrib_set_cheap(rend_data_ctx, args); + obj_material_shader_lighting_type lighting_type + = material->material.shader_info.get_lighting_type(); + bool disable_fog = draw_object_blend_set(rend_data_ctx, args, lighting_type); + draw_object_chara_color_fog_set(rend_data_ctx, args, disable_fog); + draw_object_material_set_cheap(rend_data_ctx, args); const obj_sub_mesh* sub_mesh = args->sub_mesh; - draw( + if (sub_mesh->index_format != OBJ_INDEX_U8) + draw(rend_data_ctx, + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + draw_object_material_reset_cheap(rend_data_ctx); + draw_object_vertex_attrib_reset_cheap(rend_data_ctx, args); + rend_data_ctx.reset_shader_flags(); + + rctx->draw_state_rend_data[rend_data_ctx.index].stats.sub_mesh_cheap_count++; + } + + void draw_sub_mesh_cheap_reflect_map(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { + draw_object_vertex_attrib_set_cheap(rend_data_ctx, args); + draw_object_material_set_cheap(rend_data_ctx, args); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + if (sub_mesh->index_format != OBJ_INDEX_U8) + draw(rend_data_ctx, + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + draw_object_material_reset_cheap(rend_data_ctx); + draw_object_vertex_attrib_reset_cheap(rend_data_ctx, args); + + rctx->draw_state_rend_data[rend_data_ctx.index].stats.sub_mesh_cheap_count++; + } + + void draw_sub_mesh_default(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { + if (args->set_blend_color) + rend_data_ctx.set_batch_blend_color_offset_color(args->blend_color, 0.0f); + + if (!args->func) + draw_object_vertex_attrib_set_default(rend_data_ctx, args); + + draw_object_material_set_default(rend_data_ctx, args, use_shader_get()); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + draw(rend_data_ctx, sub_mesh->primitive_type, sub_mesh->num_index, sub_mesh->first_index, @@ -265,33 +285,33 @@ namespace mdl { sub_mesh->index_format, sub_mesh->index_offset); - draw_object_material_reset_default(args->material); + draw_object_material_reset_default(rend_data_ctx, args->material); if (!args->func) - draw_object_vertex_attrib_reset_default(args); + draw_object_vertex_attrib_reset_default(rend_data_ctx, args); if (args->set_blend_color) - rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(1.0f, 0.0f); - draw_state.stats.object_draw_count++; + rctx->draw_state_rend_data[rend_data_ctx.index].stats.sub_mesh_count++; } - void draw_sub_mesh_default_instanced( - const ObjSubMeshArgs* args, const mat4* mat) { + void draw_sub_mesh_default_instanced(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { if (args->set_blend_color) - rctx->set_batch_blend_color_offset_color(args->blend_color, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(args->blend_color, 0.0f); if (!args->func) - draw_object_vertex_attrib_set_default(args); + draw_object_vertex_attrib_set_default(rend_data_ctx, args); - draw_object_material_set_default(args, use_shader_get()); + draw_object_material_set_default(rend_data_ctx, args, use_shader_get()); const obj_sub_mesh* sub_mesh = args->sub_mesh; const mat4* instances_mat = args->instances_mat; mat4 _mat; for (int32_t i = args->instances_count; i >= 0; i--, instances_mat++) { mat4_mul(instances_mat, mat, &_mat); - draw_object_model_mat_load(_mat); - draw( + rend_data_ctx.set_batch_worlds(_mat); + draw(rend_data_ctx, sub_mesh->primitive_type, sub_mesh->num_index, sub_mesh->first_index, @@ -300,133 +320,31 @@ namespace mdl { sub_mesh->index_offset); } - draw_object_material_reset_default(args->material); + draw_object_material_reset_default(rend_data_ctx, args->material); if (!args->func) - draw_object_vertex_attrib_reset_default(args); + draw_object_vertex_attrib_reset_default(rend_data_ctx, args); if (args->set_blend_color) - rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); + rend_data_ctx.set_batch_blend_color_offset_color(1.0f, 0.0f); - draw_state.stats.object_draw_count++; + rctx->draw_state_rend_data[rend_data_ctx.index].stats.sub_mesh_count++; } - void draw_sub_mesh_sss(const ObjSubMeshArgs* args) { - obj_material_attrib_member attrib = args->material->material.attrib.m; - uniform->arr[U_ALPHA_TEST] = (!attrib.flag_28 && (args->blend_color.w < 1.0f - || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through - || args->sub_mesh->attrib.m.translucent) - || attrib.punch_through) ? 1 : 0; - - uniform->arr[U_NPR_NORMAL] = 1; - bool chara = false; - const obj_material_data* material = args->material; - switch (material->material.shader.index) { - case SHADER_FT_CLOTH: - if (!render_manager.npr_param && material->material.color.ambient.w < 1.0f - && material->material.shader_info.m.aniso_direction == OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) - chara = true; - break; - case SHADER_FT_TIGHTS: - if (!render_manager.npr_param) - chara = true; - break; - case SHADER_FT_GLASEYE: - uniform->arr[U_NPR_NORMAL] = 0; - chara = true; - break; - case SHADER_FT_SKIN: - chara = true; - break; - } - - if (chara) { - rctx->set_batch_sss_param({ 0.0f, 0.0f, 0.0f, 0.5f }); - uniform->arr[U_SSS_CHARA] = 1; - } - else { - const vec4& sss_param = sss_data_get()->param; - rctx->set_batch_sss_param({ sss_param.x, sss_param.y, sss_param.z, 0.5f }); - uniform->arr[U_SSS_CHARA] = 0; - } - draw_sub_mesh_default(args); - } - - void draw_sub_mesh_reflect(const ObjSubMeshArgs* args) { - const obj_material_data* material = args->material; - draw_object_vertex_attrib_set_reflect(args); - obj_material_shader_lighting_type lighting_type - = material->material.shader_info.get_lighting_type(); - bool disable_fog = draw_object_blend_set(args, lighting_type); - draw_object_chara_color_fog_set(args, disable_fog); - draw_object_material_set_reflect(args); - - const obj_sub_mesh* sub_mesh = args->sub_mesh; - if (sub_mesh->index_format != OBJ_INDEX_U8) - draw( - sub_mesh->primitive_type, - sub_mesh->num_index, - sub_mesh->first_index, - sub_mesh->last_index, - sub_mesh->index_format, - sub_mesh->index_offset); - - draw_object_material_reset_reflect(); - draw_object_vertex_attrib_reset_reflect(args); - uniform_value_reset(); - - draw_state.stats.object_reflect_draw_count++; - } - - void draw_sub_mesh_reflect_reflect_map(const ObjSubMeshArgs* args) { - draw_object_vertex_attrib_set_reflect(args); - draw_object_material_set_reflect(args); - - const obj_sub_mesh* sub_mesh = args->sub_mesh; - if (sub_mesh->index_format != OBJ_INDEX_U8) - draw( - sub_mesh->primitive_type, - sub_mesh->num_index, - sub_mesh->first_index, - sub_mesh->last_index, - sub_mesh->index_format, - sub_mesh->index_offset); - - draw_object_material_reset_reflect(); - draw_object_vertex_attrib_reset_reflect(args); - - draw_state.stats.object_reflect_draw_count++; - } - - void draw_sub_mesh_shadow(const ObjSubMeshArgs* args) { - obj_material_attrib_member attrib = args->material->material.attrib.m; - if (!attrib.flag_28 && (args->blend_color.w < 1.0f - || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through - || args->sub_mesh->attrib.m.translucent) - || attrib.punch_through) { - uniform->arr[U_ALPHA_TEST] = 1; - rctx->set_batch_alpha_threshold(0.5f); - draw_sub_mesh_translucent(args); - uniform->arr[U_ALPHA_TEST] = 0; - rctx->set_batch_alpha_threshold(0.0f); - } - else - draw_sub_mesh_translucent(args); - } - - void draw_sub_mesh_translucent(const ObjSubMeshArgs* args) { + void draw_sub_mesh_no_mat(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { const obj_material_data* material = args->material; const prj::vector* textures = args->textures; - if (draw_state.shader_index != -1) { - rctx->set_batch_material_color_emission(args->emission); - draw_object_material_set_uniform(material, false); + if (rctx->draw_state_rend_data[rend_data_ctx.index].shader_index != -1) { + rend_data_ctx.set_batch_material_color_emission(args->emission); + draw_object_material_set_uniform(rend_data_ctx, material, false); if (material->material.attrib.m.alpha_texture) - uniform->arr[U_TEXTURE_COUNT] = 0; - rctx->set_shader(draw_state.shader_index); + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 0; + rend_data_ctx.set_shader(rctx->draw_state_rend_data[rend_data_ctx.index].shader_index); } - draw_object_vertex_attrib_set_default(args); + draw_object_vertex_attrib_set_default(rend_data_ctx, args); if (args->material->material.attrib.m.double_sided) - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_cull_face(); GLuint tex_id = -1; int32_t tex_index = 0; @@ -467,7 +385,7 @@ namespace mdl { if (tex_id == -1) tex_id = rctx->empty_texture_2d->glid;; - gl_rend_state.active_bind_texture_2d(tex_index, tex_id); + rend_data_ctx.state.active_bind_texture_2d(tex_index, tex_id); int32_t wrap_s; if (texdata->attrib.m.mirror_u) @@ -486,14 +404,14 @@ namespace mdl { wrap_t = 0; texture* tex = texture_manager_get_texture(texture_id); - gl_rend_state.bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + rend_data_ctx.state.bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + (!tex || tex->max_mipmap_level > 0 ? 1 : 0)]); } } const obj_sub_mesh* sub_mesh = args->sub_mesh; if (sub_mesh->index_format != OBJ_INDEX_U8) - draw( + draw(rend_data_ctx, sub_mesh->primitive_type, sub_mesh->num_index, sub_mesh->first_index, @@ -502,21 +420,80 @@ namespace mdl { sub_mesh->index_offset); if (tex_id != -1) - gl_rend_state.active_bind_texture_2d(tex_index, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(tex_index, rctx->empty_texture_2d->glid); - gl_rend_state.enable_cull_face(); - draw_object_vertex_attrib_reset_default(args); + rend_data_ctx.state.enable_cull_face(); + draw_object_vertex_attrib_reset_default(rend_data_ctx, args); - if (draw_state.shader_index != -1) - uniform_value_reset(); + if (rctx->draw_state_rend_data[rend_data_ctx.index].shader_index != -1) + rend_data_ctx.reset_shader_flags(); - draw_state.stats.object_translucent_draw_count++; + rctx->draw_state_rend_data[rend_data_ctx.index].stats.sub_mesh_no_mat_count++; + } + + void draw_sub_mesh_shadow(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { + obj_material_attrib_member attrib = args->material->material.attrib.m; + if (!attrib.flag_28 && (args->blend_color.w < 1.0f + || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through + || args->sub_mesh->attrib.m.translucent) + || attrib.punch_through) { + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 1; + rend_data_ctx.set_batch_alpha_threshold(0.5f); + draw_sub_mesh_no_mat(rend_data_ctx, args, cam, mat); + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = 0; + rend_data_ctx.set_batch_alpha_threshold(0.0f); + } + else + draw_sub_mesh_no_mat(rend_data_ctx, args, cam, mat); + } + + void draw_sub_mesh_sss(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat) { + obj_material_attrib_member attrib = args->material->material.attrib.m; + rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = (!attrib.flag_28 && (args->blend_color.w < 1.0f + || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through + || args->sub_mesh->attrib.m.translucent) + || attrib.punch_through) ? 1 : 0; + + rend_data_ctx.shader_flags.arr[U_NPR_NORMAL] = 1; + bool chara = false; + const obj_material_data* material = args->material; + switch (material->material.shader.index) { + case SHADER_FT_CLOTH: + if (!render_manager.npr_param && material->material.color.ambient.w < 1.0f + && material->material.shader_info.m.aniso_direction == OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) + chara = true; + break; + case SHADER_FT_TIGHTS: + if (!render_manager.npr_param) + chara = true; + break; + case SHADER_FT_GLASEYE: + rend_data_ctx.shader_flags.arr[U_NPR_NORMAL] = 0; + chara = true; + break; + case SHADER_FT_SKIN: + chara = true; + break; + } + + if (chara) { + rend_data_ctx.set_batch_sss_param({ 0.0f, 0.0f, 0.0f, 0.5f }); + rend_data_ctx.shader_flags.arr[U_SSS_CHARA] = 1; + } + else { + const vec4& sss_param = sss_data_get()->param; + rend_data_ctx.set_batch_sss_param({ sss_param.x, sss_param.y, sss_param.z, 0.5f }); + rend_data_ctx.shader_flags.arr[U_SSS_CHARA] = 0; + } + draw_sub_mesh_default(rend_data_ctx, args, cam, mat); } } -inline void model_mat_face_camera_position(const mat4* view, const mat4* src, mat4* dst) { +inline void model_mat_face_camera_position(const cam_data& cam, const mat4* src, mat4* dst) { mat4 mat; - mat4_invert_fast(view, &mat); + mat4_invert_fast(&cam.get_view_mat(), &mat); vec3 dir = vec3::normalize(*(vec3*)&mat.row3 - *(vec3*)&src->row3); @@ -538,15 +515,15 @@ inline void model_mat_face_camera_position(const mat4* view, const mat4* src, ma dst->row3.w = 1.0f; } -inline void model_mat_face_camera_view(const mat4* view, const mat4* src, mat4* dst) { +inline void model_mat_face_camera_view(const cam_data& cam, const mat4* src, mat4* dst) { mat3 mat; - mat4_to_mat3(view, &mat); + mat4_to_mat3(&cam.get_view_mat(), &mat); mat3_invert(&mat, &mat); mat4_from_mat3(&mat, dst); mat4_mul(dst, src, dst); } -static bool draw_object_blend_set( +static bool draw_object_blend_set(render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args, obj_material_shader_lighting_type lighting_type) { static const GLenum blend_factor_table[] = { GL_ZERO, @@ -581,7 +558,7 @@ static bool draw_object_blend_set( chara_color->get_specular(specular); if (specular.w >= 4.0f && chara_color->get_type() == LIGHT_PARALLEL && (src_blend_factor != GL_ONE || dst_blend_factor)) { - int32_t shader_index = draw_state.shader_index; + int32_t shader_index = rctx->draw_state_rend_data[rend_data_ctx.index].shader_index; if (shader_index == -1) { shader_index = material->material.shader.index; if (shader_index == SHADER_FT_BLINN) { @@ -598,7 +575,7 @@ static bool draw_object_blend_set( } } } - gl_rend_state.set_blend_func(src_blend_factor, dst_blend_factor); + rend_data_ctx.state.set_blend_func(src_blend_factor, dst_blend_factor); return dst_blend_factor == GL_ONE; } @@ -616,58 +593,139 @@ static bool draw_object_blend_set_check_use_default_blend(int32_t index) { return false; } -static void draw_object_chara_color_fog_set(const mdl::ObjSubMeshArgs* args, bool disable_fog) { - uniform->arr[U_CHARA_COLOR] = 0; +static void draw_object_chara_color_fog_set(render_data_context& rend_data_ctx, + const mdl::ObjSubMeshArgs* args, bool disable_fog) { + rend_data_ctx.shader_flags.arr[U_CHARA_COLOR] = 0; if (args->chara_color) { light_set* set = &light_set_data[LIGHT_SET_MAIN]; light_data* chara_color = &set->lights[LIGHT_CHARA_COLOR]; vec4 specular; chara_color->get_specular(specular); if (specular.w > 0.0f && chara_color->get_type() == LIGHT_PARALLEL) - uniform->arr[U_CHARA_COLOR] = 1; + rend_data_ctx.shader_flags.arr[U_CHARA_COLOR] = 1; } obj_material_attrib_member attrib = args->material->material.attrib.m; if (!attrib.no_fog && !disable_fog) { - uniform->arr[U_FOG_STAGE] = attrib.has_fog_height ? (attrib.fog_height ? 3 : 2) : 1; - uniform->arr[U_FOG_CHARA] = draw_state.fog_height ? 2 : 1; + rend_data_ctx.shader_flags.arr[U_FOG_STAGE] = attrib.has_fog_height ? (attrib.fog_height ? 3 : 2) : 1; + rend_data_ctx.shader_flags.arr[U_FOG_CHARA] = draw_state.fog_height ? 2 : 1; } } -static void draw_object_material_reset_default(const obj_material_data* mat_data) { +static void draw_object_material_reset_cheap(render_data_context& rend_data_ctx) { + rend_data_ctx.state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.reset_shader_flags(); +} + +static void draw_object_material_reset_default( + render_data_context& rend_data_ctx, const obj_material_data* mat_data) { if (mat_data) { - gl_rend_state.enable_cull_face(); + rend_data_ctx.state.enable_cull_face(); obj_material_attrib_member attrib = mat_data->material.attrib.m; if ((attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through) - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - uniform_value_reset(); + rend_data_ctx.reset_shader_flags(); } -static void draw_object_material_reset_reflect() { - gl_rend_state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid); - gl_rend_state.enable_cull_face(); - uniform_value_reset(); +static void draw_object_material_set_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args) { + const obj_material_data* material = args->material; + const prj::vector* textures = args->textures; + if (material->material.attrib.m.double_sided) + rend_data_ctx.state.disable_cull_face(); + + const obj_material_texture_data* texdata = material->material.texdata; + for (int32_t i = 0; i < 1; i++, texdata++) { + uint32_t texture_id = texdata->tex_index & 0xFFFFF; + if (texdata->tex_index == -1) + break; + + GLuint tex_id = -1; + for (int32_t j = 0; j < args->texture_pattern_count; j++) + if (args->texture_pattern_array[j].src == ::texture_id(0x00, texture_id)) { + texture* tex = texture_manager_get_texture(args->texture_pattern_array[j].dst); + if (tex) + tex_id = tex->glid; + break; + } + + if (tex_id == -1) + tex_id = (*textures)[texdata->tex_index >> 20]; + + if (tex_id == -1) + tex_id = rctx->empty_texture_2d->glid;; + + rend_data_ctx.state.active_bind_texture_2d(i, tex_id); + + int32_t wrap_s; + if (texdata->attrib.m.mirror_u) + wrap_s = 2; + else if (texdata->attrib.m.repeat_u) + wrap_s = 1; + else + wrap_s = 0; + + int32_t wrap_t; + if (texdata->attrib.m.mirror_v) + wrap_t = 2; + else if (texdata->attrib.m.repeat_v) + wrap_t = 1; + else + wrap_t = 0; + + texture* tex = texture_manager_get_texture(texture_id); + rend_data_ctx.state.bind_sampler(i, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + + (!tex || tex->max_mipmap_level > 0 ? 1 : 0)]); + } + + vec4 ambient; + vec4 diffuse; + vec4 emission; + vec4 specular; + if (material->material.shader.index == -1) { + ambient = 1.0f; + diffuse = material->material.color.diffuse; + emission = 1.0f; + specular = material->material.color.specular; + } + else { + ambient = material->material.color.ambient; + diffuse = material->material.color.diffuse; + emission = args->emission; + specular = material->material.color.specular; + } + + draw_object_material_set_uniform(rend_data_ctx, material, true); + rend_data_ctx.set_shader(rctx->draw_state_rend_data[rend_data_ctx.index].shader_index); + rend_data_ctx.set_batch_material_color(diffuse, ambient, emission, + 0.0f, specular, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + draw_object_material_set_parameter(rend_data_ctx, args->material); } -static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bool use_shader) { +static void draw_object_material_set_default(render_data_context& rend_data_ctx, + const mdl::ObjSubMeshArgs* args, bool use_shader) { const prj::vector* textures = args->textures; const obj_material_data* material = args->material; obj_material_shader_lighting_type lighting_type = material->material.shader_info.get_lighting_type(); - bool disable_fog = draw_object_blend_set(args, lighting_type); - draw_object_material_set_uniform(material, false); - if (!draw_state.shadow) - uniform->arr[U_STAGE_SHADOW] = 0; - else if (args->self_shadow) - uniform->arr[U_STAGE_SHADOW] = 1; + bool disable_fog = draw_object_blend_set(rend_data_ctx, args, lighting_type); + draw_object_material_set_uniform(rend_data_ctx, material, false); + if (!rctx->draw_state_rend_data[rend_data_ctx.index].shadow) + rend_data_ctx.shader_flags.arr[U_STAGE_SHADOW] = 0; + else if (!args->self_shadow) + rend_data_ctx.shader_flags.arr[U_STAGE_SHADOW] = args->sub_mesh->attrib.m.recieve_shadow ? 1 : 0; + else if (args->self_shadow != 1) + rend_data_ctx.shader_flags.arr[U_STAGE_SHADOW] = 0; else - uniform->arr[U_STAGE_SHADOW] = args->sub_mesh->attrib.m.recieve_shadow ? 1 : 0; - uniform->arr[U_CHARA_SHADOW2] = 0; - uniform->arr[U_CHARA_SHADOW] = draw_state.self_shadow ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_STAGE_SHADOW] = 1; + + rend_data_ctx.shader_flags.arr[U_CHARA_SHADOW2] = args->shadow > SHADOW_CHARA ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_CHARA_SHADOW] + = rctx->draw_state_rend_data[rend_data_ctx.index].self_shadow ? 1 : 0; const obj_material_texture_data* texdata = material->material.texdata; - uniform->arr[U_CHARA_SHADOW2] = args->shadow > SHADOW_CHARA; for (int32_t i = 0, j = 0; i < 8; i++, texdata++) { if (texdata->tex_index == -1) continue; @@ -699,27 +757,27 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo if (texdata->attrib.m.flag_29) { switch (tex_type) { case OBJ_MATERIAL_TEXTURE_NORMAL: - uniform->arr[U_NORMAL] = 0; + rend_data_ctx.shader_flags.arr[U_NORMAL] = 0; break; case OBJ_MATERIAL_TEXTURE_SPECULAR: - uniform->arr[U_SPECULAR] = 0; + rend_data_ctx.shader_flags.arr[U_SPECULAR] = 0; break; case OBJ_MATERIAL_TEXTURE_TRANSLUCENCY: - uniform->arr[U_TRANSLUCENCY] = 0; + rend_data_ctx.shader_flags.arr[U_TRANSLUCENCY] = 0; break; case OBJ_MATERIAL_TEXTURE_TRANSPARENCY: - uniform->arr[U_TRANSPARENCY] = 0; + rend_data_ctx.shader_flags.arr[U_TRANSPARENCY] = 0; break; } continue; } if (tex_type == OBJ_MATERIAL_TEXTURE_ENVIRONMENT_CUBE) { - gl_rend_state.active_bind_texture_cube_map(tex_index, tex_id); - gl_rend_state.bind_sampler(tex_index, 0); + rend_data_ctx.state.active_bind_texture_cube_map(tex_index, tex_id); + rend_data_ctx.state.bind_sampler(tex_index, 0); } else { - gl_rend_state.active_bind_texture_2d(tex_index, tex_id); + rend_data_ctx.state.active_bind_texture_2d(tex_index, tex_id); int32_t wrap_s; if (texdata->attrib.m.mirror_u) @@ -738,7 +796,7 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo wrap_t = 0; texture* tex = texture_manager_get_texture(texture_id); - gl_rend_state.bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + rend_data_ctx.state.bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + (!tex || tex->max_mipmap_level > 0 ? 1 : 0)]); } @@ -749,26 +807,26 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo texture* tex = texture_manager_get_texture(texture_id); if (!tex) - uniform->arr[uni_type] = 1; + rend_data_ctx.shader_flags.arr[uni_type] = 1; else if (tex->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) - uniform->arr[uni_type] = 3; + rend_data_ctx.shader_flags.arr[uni_type] = 3; else if (tex->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) - uniform->arr[uni_type] = 2; + rend_data_ctx.shader_flags.arr[uni_type] = 2; else - uniform->arr[uni_type] = 1; + rend_data_ctx.shader_flags.arr[uni_type] = 1; } if (tex_index >= 0 && tex_index <= 1) - uniform->arr[U_TEXTURE_BLEND] = texdata->attrib.get_blend(); + rend_data_ctx.shader_flags.arr[U_TEXTURE_BLEND] = texdata->attrib.get_blend(); } if (material->material.attrib.m.double_sided) { - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_cull_face(); if (!material->material.attrib.m.normal_dir_light) - uniform->arr[U0B] = 1; + rend_data_ctx.shader_flags.arr[U0B] = 1; } - draw_object_chara_color_fog_set(args, disable_fog); + draw_object_chara_color_fog_set(rend_data_ctx, args, disable_fog); vec4 ambient = material->material.color.ambient; if (!sss_data_get()->enable) @@ -783,17 +841,17 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo float_t luma = vec3::dot(*(vec3*)&specular, { 0.30f, 0.59f, 0.11f }); if (luma >= 0.01f || args->texture_color_coefficients.w >= 0.1f) - uniform->arr[U_SPECULAR_IBL] = 1; + rend_data_ctx.shader_flags.arr[U_SPECULAR_IBL] = 1; else - uniform->arr[U_SPECULAR_IBL] = 0; + rend_data_ctx.shader_flags.arr[U_SPECULAR_IBL] = 0; if (!material->material.shader_info.m.fresnel_type) - uniform->arr[U_TRANSLUCENCY] = 0; + rend_data_ctx.shader_flags.arr[U_TRANSLUCENCY] = 0; line_light = (float_t)material->material.shader_info.m.line_light * (float_t)(1.0 / 9.0); } else - line_light = 0.0; + line_light = 0.0f; float_t material_shininess = 0.0f; vec4 fresnel_coefficients; @@ -841,31 +899,32 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo } } - rctx->set_batch_material_color(diffuse, ambient, emission, material_shininess, + rend_data_ctx.set_batch_material_color(diffuse, ambient, emission, material_shininess, specular, fresnel_coefficients, texture_color_coefficients, texture_color_offset, texture_specular_coefficients, texture_specular_offset, shininess); if (!use_shader) - rctx->set_shader(SHADER_FT_SIMPLE); - else if (draw_state.shader_index != -1) - rctx->set_shader(draw_state.shader_index); + rend_data_ctx.set_shader(SHADER_FT_SIMPLE); + else if (rctx->draw_state_rend_data[rend_data_ctx.index].shader_index != -1) + rend_data_ctx.set_shader(rctx->draw_state_rend_data[rend_data_ctx.index].shader_index); else if (material->material.shader.index != -1) { if (material->material.shader.index != SHADER_FT_BLINN) - rctx->set_shader(material->material.shader.index); + rend_data_ctx.set_shader(material->material.shader.index); else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT) - rctx->set_shader(SHADER_FT_LAMBERT); + rend_data_ctx.set_shader(SHADER_FT_LAMBERT); else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) - rctx->set_shader(SHADER_FT_BLINN); + rend_data_ctx.set_shader(SHADER_FT_BLINN); else - rctx->set_shader(SHADER_FT_CONSTANT); + rend_data_ctx.set_shader(SHADER_FT_CONSTANT); } else - rctx->set_shader(SHADER_FT_CONSTANT); + rend_data_ctx.set_shader(SHADER_FT_CONSTANT); - draw_object_material_set_parameter(material); + draw_object_material_set_parameter(rend_data_ctx, material); } -static void draw_object_material_set_parameter(const obj_material_data* mat_data) { +static void draw_object_material_set_parameter( + render_data_context& rend_data_ctx, const obj_material_data* mat_data) { vec4 specular; float_t bump_depth; float_t intensity; @@ -893,87 +952,14 @@ static void draw_object_material_set_parameter(const obj_material_data* mat_data has_specular = false; } - rctx->set_batch_material_parameter(has_specular ? &specular : 0, + rend_data_ctx.set_batch_material_parameter(has_specular ? &specular : 0, { inv_bump_depth, bump_depth, 0.0f, 0.0f }, { intensity, max_def(intensity, 1.0f), intensity * 25.5f, 1.0f }, reflect_uv_scale, refract_uv_scale); } -static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args) { - const obj_material_data* material = args->material; - const prj::vector* textures = args->textures; - if (material->material.attrib.m.double_sided) - gl_rend_state.disable_cull_face(); - - const obj_material_texture_data* texdata = material->material.texdata; - for (int32_t i = 0; i < 1; i++, texdata++) { - uint32_t texture_id = texdata->tex_index & 0xFFFFF; - if (texdata->tex_index == -1) - break; - - GLuint tex_id = -1; - for (int32_t j = 0; j < args->texture_pattern_count; j++) - if (args->texture_pattern_array[j].src == ::texture_id(0x00, texture_id)) { - texture* tex = texture_manager_get_texture(args->texture_pattern_array[j].dst); - if (tex) - tex_id = tex->glid; - break; - } - - if (tex_id == -1) - tex_id = (*textures)[texdata->tex_index >> 20]; - - if (tex_id == -1) - tex_id = rctx->empty_texture_2d->glid;; - - gl_rend_state.active_bind_texture_2d(i, tex_id); - - int32_t wrap_s; - if (texdata->attrib.m.mirror_u) - wrap_s = 2; - else if (texdata->attrib.m.repeat_u) - wrap_s = 1; - else - wrap_s = 0; - - int32_t wrap_t; - if (texdata->attrib.m.mirror_v) - wrap_t = 2; - else if (texdata->attrib.m.repeat_v) - wrap_t = 1; - else - wrap_t = 0; - - texture* tex = texture_manager_get_texture(texture_id); - gl_rend_state.bind_sampler(i, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 - + (!tex || tex->max_mipmap_level > 0 ? 1 : 0)]); - } - - vec4 ambient; - vec4 diffuse; - vec4 emission; - vec4 specular; - if (material->material.shader.index == -1) { - ambient = 1.0f; - diffuse = material->material.color.diffuse; - emission = 1.0f; - specular = material->material.color.specular; - } - else { - ambient = material->material.color.ambient; - diffuse = material->material.color.diffuse; - emission = args->emission; - specular = material->material.color.specular; - } - - draw_object_material_set_uniform(material, true); - rctx->set_shader(draw_state.shader_index); - rctx->set_batch_material_color(diffuse, ambient, emission, - 0.0f, specular, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); - draw_object_material_set_parameter(args->material); -} - -static void draw_object_material_set_uniform(const obj_material_data* mat_data, bool disable_color_l) { +static void draw_object_material_set_uniform(render_data_context& rend_data_ctx, + const obj_material_data* mat_data, bool disable_color_l) { obj_shader_compo_member shader_compo = mat_data->material.shader_compo.m; obj_material_shader_attrib_member shader_info = mat_data->material.shader_info.m; @@ -987,83 +973,126 @@ static void draw_object_material_set_uniform(const obj_material_data* mat_data, if (shader_compo.color) { if (!shader_compo.color_l2) if (shader_compo.color_l1) { - uniform->arr[U_TEXTURE_COUNT] = 2; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 2; v4 = 3; } else { - uniform->arr[U_TEXTURE_COUNT] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 1; v4 = 1; } } else if (shader_compo.color_l1 && !shader_compo.color_l2) { - uniform->arr[U_TEXTURE_COUNT] = 1; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 1; v4 = 1; } else - uniform->arr[U_TEXTURE_COUNT] = 0; + rend_data_ctx.shader_flags.arr[U_TEXTURE_COUNT] = 0; if (shader_compo.normal_01) - uniform->arr[U_NORMAL] = 1; + rend_data_ctx.shader_flags.arr[U_NORMAL] = 1; if (shader_compo.specular) - uniform->arr[U_SPECULAR] = 1; + rend_data_ctx.shader_flags.arr[U_SPECULAR] = 1; if (shader_compo.transparency) { - uniform->arr[U_TRANSPARENCY] = 1; + rend_data_ctx.shader_flags.arr[U_TRANSPARENCY] = 1; v4 |= 2; } if (shader_compo.translucency) { - uniform->arr[U_TRANSLUCENCY] = 1; + rend_data_ctx.shader_flags.arr[U_TRANSLUCENCY] = 1; v4 |= 2; } if (shader_compo.override_ibl) - uniform->arr[U_ENV_MAP] = 1; + rend_data_ctx.shader_flags.arr[U_ENV_MAP] = 1; if (shader_info.aniso_direction != OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) - uniform->arr[U_ANISO] = shader_info.aniso_direction; + rend_data_ctx.shader_flags.arr[U_ANISO] = shader_info.aniso_direction; if (v4 == 1) - uniform->arr[U45] = 0; + rend_data_ctx.shader_flags.arr[U45] = 0; else if (v4 == 2 || v4 == 3) - uniform->arr[U45] = 1; + rend_data_ctx.shader_flags.arr[U45] = 1; } -static void draw_object_model_mat_load(const mat4& mat) { - rctx->set_batch_worlds(mat); -} - -static void draw_object_vertex_attrib_reset_default(const mdl::ObjSubMeshArgs* args) { +static void draw_object_vertex_attrib_reset_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args) { const obj_mesh* mesh = args->mesh; obj_vertex_format vertex_format = mesh->vertex_format; if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) - uniform->arr[U_SKINNING] = 0; + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; if (args->morph_vertex_buffer) { - uniform->arr[U_MORPH] = 0; - uniform->arr[U_MORPH_COLOR] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; + } + + rend_data_ctx.state.active_texture(0); +} + +static void draw_object_vertex_attrib_reset_default( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + obj_vertex_format vertex_format = mesh->vertex_format; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; + + if (args->morph_vertex_buffer) { + rend_data_ctx.shader_flags.arr[U_MORPH] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; } /*if (args->instances_count) - uniform->arr[U_INSTANCE] = 0;*/ + rend_data_ctx.shader_flags.arr[U_INSTANCE] = 0;*/ - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_texture(0); } -static void draw_object_vertex_attrib_reset_reflect(const mdl::ObjSubMeshArgs* args) { +static void draw_object_vertex_attrib_set_cheap( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args) { const obj_mesh* mesh = args->mesh; obj_vertex_format vertex_format = mesh->vertex_format; - if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) - uniform->arr[U_SKINNING] = 0; + mat4 mats[2]; + mats[0] = mat4_identity; + mats[1] = mat4_identity; + const obj_material_data* material = args->material; + if (material->material.texdata[0].tex_index != -1) { + uint32_t texture_id = material->material.texdata[0].tex_index & 0xFFFFF; - if (args->morph_vertex_buffer) { - uniform->arr[U_MORPH] = 0; - uniform->arr[U_MORPH_COLOR] = 0; + mats[0] = material->material.texdata[0].tex_coord_mat; + if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + for (int32_t j = 0; j < args->texture_transform_count; j++) + if (args->texture_transform_array[j].id == texture_id) { + mats[0] = args->texture_transform_array[j].mat; + break; + } } - gl_rend_state.active_texture(0); + rend_data_ctx.set_batch_texcoord_transforms(mats); + + if (vertex_format & OBJ_VERTEX_BONE_DATA) + rend_data_ctx.shader_flags.arr[U_SKINNING] = 1; + else + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; + + if (args->morph_vertex_buffer) { + rend_data_ctx.shader_flags.arr[U_MORPH] = 1; + + if (vertex_format & OBJ_VERTEX_COLOR0) + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 1; + else + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; + + rend_data_ctx.set_batch_morph_weight(args->morph_weight); + } + else { + rend_data_ctx.shader_flags.arr[U_MORPH] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; + } } -static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* args) { +static void draw_object_vertex_attrib_set_default( + render_data_context& rend_data_ctx, const mdl::ObjSubMeshArgs* args) { const obj_mesh* mesh = args->mesh; obj_vertex_format vertex_format = mesh->vertex_format; @@ -1102,73 +1131,30 @@ static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* arg } } - rctx->set_batch_texcoord_transforms(mats); + rend_data_ctx.set_batch_texcoord_transforms(mats); if (vertex_format & OBJ_VERTEX_BONE_DATA) - uniform->arr[U_SKINNING] = 1; + rend_data_ctx.shader_flags.arr[U_SKINNING] = 1; else - uniform->arr[U_SKINNING] = 0; + rend_data_ctx.shader_flags.arr[U_SKINNING] = 0; if (args->morph_vertex_buffer) { - uniform->arr[U_MORPH] = 1; + rend_data_ctx.shader_flags.arr[U_MORPH] = 1; if (vertex_format & OBJ_VERTEX_COLOR0) - uniform->arr[U_MORPH_COLOR] = 1; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 1; else - uniform->arr[U_MORPH_COLOR] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; - rctx->set_batch_morph_weight(args->morph_weight); + rend_data_ctx.set_batch_morph_weight(args->morph_weight); } else { - uniform->arr[U_MORPH] = 0; - uniform->arr[U_MORPH_COLOR] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH] = 0; + rend_data_ctx.shader_flags.arr[U_MORPH_COLOR] = 0; } /*if (args->instances_count) - uniform->arr[U_INSTANCE] = 1; + rend_data_ctx.shader_flags.arr[U_INSTANCE] = 1; else - uniform->arr[U_INSTANCE] = 0;*/ -} - -static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* args) { - const obj_mesh* mesh = args->mesh; - obj_vertex_format vertex_format = mesh->vertex_format; - - mat4 mats[2]; - mats[0] = mat4_identity; - mats[1] = mat4_identity; - const obj_material_data* material = args->material; - if (material->material.texdata[0].tex_index != -1) { - uint32_t texture_id = material->material.texdata[0].tex_index & 0xFFFFF; - - mats[0] = material->material.texdata[0].tex_coord_mat; - if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) - for (int32_t j = 0; j < args->texture_transform_count; j++) - if (args->texture_transform_array[j].id == texture_id) { - mats[0] = args->texture_transform_array[j].mat; - break; - } - } - - rctx->set_batch_texcoord_transforms(mats); - - if (vertex_format & OBJ_VERTEX_BONE_DATA) - uniform->arr[U_SKINNING] = 1; - else - uniform->arr[U_SKINNING] = 0; - - if (args->morph_vertex_buffer) { - uniform->arr[U_MORPH] = 1; - - if (vertex_format & OBJ_VERTEX_COLOR0) - uniform->arr[U_MORPH_COLOR] = 1; - else - uniform->arr[U_MORPH_COLOR] = 0; - - rctx->set_batch_morph_weight(args->morph_weight); - } - else { - uniform->arr[U_MORPH] = 0; - uniform->arr[U_MORPH_COLOR] = 0; - } + rend_data_ctx.shader_flags.arr[U_INSTANCE] = 0;*/ } diff --git a/src/DivaGL/mdl/draw_object.hpp b/src/DivaGL/mdl/draw_object.hpp index b02f932..ec4970e 100644 --- a/src/DivaGL/mdl/draw_object.hpp +++ b/src/DivaGL/mdl/draw_object.hpp @@ -12,20 +12,29 @@ #include "../render_context.hpp" namespace mdl { - extern void draw(obj_primitive_type primitive_type, uint32_t count, + extern void draw( + render_data_context& rend_data_ctx, obj_primitive_type primitive_type, uint32_t count, uint16_t start, uint16_t end, obj_index_format index_format, size_t indices); - extern void draw_etc_obj(const mdl::EtcObj* etc, const mat4* mat); - extern void draw_sub_mesh(const ObjSubMeshArgs* args, const mat4* mat, - void(*func)(const ObjSubMeshArgs* args)); - //extern void draw_sub_mesh_show_vector(const ObjSubMeshArgs* args, const mat4* model, int32_t show_vector); - extern void draw_sub_mesh_default(const ObjSubMeshArgs* args); - extern void draw_sub_mesh_default_instanced(const ObjSubMeshArgs* args, const mat4* mat); - extern void draw_sub_mesh_sss(const ObjSubMeshArgs* args); - extern void draw_sub_mesh_reflect(const ObjSubMeshArgs* args); - extern void draw_sub_mesh_reflect_reflect_map(const ObjSubMeshArgs* args); - extern void draw_sub_mesh_shadow(const ObjSubMeshArgs* args); - extern void draw_sub_mesh_translucent(const ObjSubMeshArgs* args); + extern void draw_etc_obj( + render_data_context& rend_data_ctx, const mdl::EtcObj* etc, const mat4* mat); + extern void draw_sub_mesh(render_data_context& rend_data_ctx, const ObjSubMeshArgs* args, + const mat4* mat, void(*func)(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat), const cam_data& cam); + extern void draw_sub_mesh_cheap(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_cheap_reflect_map(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_default(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_default_instanced(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_no_mat(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_shadow(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); + extern void draw_sub_mesh_sss(render_data_context& rend_data_ctx, + const ObjSubMeshArgs* args, const cam_data& cam, const mat4* mat); }; -extern void model_mat_face_camera_position(const mat4* view, const mat4* src, mat4* dst); -extern void model_mat_face_camera_view(const mat4* view, const mat4* src, mat4* dst); +extern void model_mat_face_camera_position(const cam_data& cam, const mat4* src, mat4* dst); +extern void model_mat_face_camera_view(const cam_data& cam, const mat4* src, mat4* dst); diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp index e13bd58..1b8ff14 100644 --- a/src/DivaGL/object.cpp +++ b/src/DivaGL/object.cpp @@ -8,7 +8,7 @@ #include "../AFTModsShared/file_handler.hpp" #include "mdl/disp_manager.hpp" #include "pv_game/firstread.hpp" -#include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "wrap.hpp" #include @@ -206,9 +206,9 @@ GLsizeiptr obj_mesh_vertex_buffer_divagl::get_size() { GLint buffer; GLint size; glGetIntegervDLL(GL_ARRAY_BUFFER_BINDING, &buffer); - gl_rend_state.bind_element_array_buffer(buffers[0]); + gl_state.bind_element_array_buffer(buffers[0]); glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size); - gl_rend_state.bind_element_array_buffer(buffer); + gl_state.bind_element_array_buffer(buffer); return size; } #endif @@ -1163,12 +1163,12 @@ bool ObjsetInfo::vertex_buffer_load() { static GLuint create_index_buffer(size_t size, const void* data) { GLuint buffer = 0; glGenBuffers(1, &buffer); - gl_rend_state.bind_element_array_buffer(buffer); + gl_state.bind_element_array_buffer(buffer); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, data, 0); else glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, data, GL_STATIC_DRAW); - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_element_array_buffer(0); if (glGetErrorDLL()) { glDeleteBuffers(1, &buffer); @@ -1183,14 +1183,14 @@ static GLuint create_index_buffer(size_t size, const void* data) { static GLuint create_vertex_buffer(size_t size, const void* data, bool dynamic) { GLuint buffer = 0; glGenBuffers(1, &buffer); - gl_rend_state.bind_array_buffer(buffer); + gl_state.bind_array_buffer(buffer); if (DIVA_GL_VERSION_4_4) glBufferStorage(GL_ARRAY_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); else glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)size, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); - gl_rend_state.bind_array_buffer(0); + gl_state.bind_array_buffer(0); if (glGetErrorDLL()) { glDeleteBuffers(1, &buffer); @@ -1209,9 +1209,9 @@ static void free_index_buffer(GLuint buffer) { disp_manager->check_index_buffer(buffer); GLint size; - gl_rend_state.bind_element_array_buffer(buffer); + gl_state.bind_element_array_buffer(buffer); glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - gl_rend_state.bind_element_array_buffer(0); + gl_state.bind_element_array_buffer(0); bufobj_mgr.ib_all_size -= size; glDeleteBuffers(1, &buffer); @@ -1225,9 +1225,9 @@ static void free_vertex_buffer(GLuint buffer) { disp_manager->check_vertex_buffer(buffer); GLint size = 0; - gl_rend_state.bind_array_buffer(buffer); + gl_state.bind_array_buffer(buffer); glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - gl_rend_state.bind_array_buffer(0); + gl_state.bind_array_buffer(0); bufobj_mgr.vb_all_size -= size; glDeleteBuffers(1, &buffer); diff --git a/src/DivaGL/render.cpp b/src/DivaGL/render.cpp index cff1ff7..1abdcf7 100644 --- a/src/DivaGL/render.cpp +++ b/src/DivaGL/render.cpp @@ -6,6 +6,7 @@ #include "render.hpp" #include "rob/rob.hpp" #include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "render_context.hpp" #include "render_context.hpp" #include "shader_ft.hpp" @@ -34,49 +35,50 @@ namespace rndr { spot_weight = 0.0f; } - void Render::apply_post_process(texture* light_proj_tex, int32_t npr_param) { + void Render::apply_post_process(render_data_context& rend_data_ctx, + const cam_data& cam, texture* light_proj_tex, int32_t npr_param) { for (int32_t i = 0; i < 8; i++) - gl_rend_state.bind_sampler(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); - gl_rend_state.disable_depth_test(); - gl_rend_state.disable_blend(); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.disable_blend(); - dof->apply(&rend_texture[0], &rctx->render_buffer); + dof->apply(rend_data_ctx, &rend_texture[0], &rctx->render_buffer); - draw_lens_ghost(); + draw_lens_ghost(rend_data_ctx); - downsample(); + downsample(rend_data_ctx); reduce_tex_draw = 0; - get_blur(); + get_blur(rend_data_ctx); - calc_exposure(); - apply_tone_map(light_proj_tex, npr_param); + calc_exposure(rend_data_ctx, cam); + apply_tone_map(rend_data_ctx, light_proj_tex, npr_param); - apply_mlaa(taa_texture_selector, 2, mlaa); + apply_mlaa(rend_data_ctx, taa_texture_selector, 2, mlaa); for (int32_t i = 0; i < 16; i++) { if (!render_textures_data[i]) continue; - render_textures[i].Bind(); + render_textures[i].Bind(rend_data_ctx.state); texture* t = render_textures_data[i]; if (render_width[0] > t->width * 2 || render_height[0] > t->height * 2) - uniform->arr[U_REDUCE] = 1; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 1; else - uniform->arr[U_REDUCE] = 0; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; - gl_rend_state.set_viewport(0, 0, t->width, t->height); - gl_rend_state.active_bind_texture_2d(0, taa_tex[taa_texture_selector]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(render_post_width[0], render_post_height[0], + rend_data_ctx.state.set_viewport(0, 0, t->width, t->height); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[taa_texture_selector]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } - copy_to_frame_texture(rend_texture[0].GetColorTex(), + copy_to_frame_texture(rend_data_ctx, rend_texture[0].GetColorTex(), render_width[0], render_height[0], taa_tex[taa_texture_selector]->glid); if (taa) { @@ -89,7 +91,7 @@ namespace rndr { if (taa_blend < 0.0f || taa_blend >= 1.0f) taa_texture = taa_texture_selector; else { - gl_rend_state.begin_event("taa_or_blur"); + rend_data_ctx.state.begin_event("taa_or_blur"); bool blur; GLuint sampler; if (taa_blend > 0.99f) { @@ -102,43 +104,43 @@ namespace rndr { } taa_texture = 2; - taa_buffer[2].Bind(); - gl_rend_state.set_viewport(0, 0, render_width[0], render_height[0]); - gl_rend_state.active_bind_texture_2d(0, taa_tex[taa_texture_selector]->glid); - gl_rend_state.bind_sampler(0, sampler); + taa_buffer[2].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, render_width[0], render_height[0]); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[taa_texture_selector]->glid); + rend_data_ctx.state.bind_sampler(0, sampler); if (blur) { - gl_rend_state.active_bind_texture_2d(2, rend_texture[0].depth_texture->glid); - gl_rend_state.bind_sampler(2, sampler); + rend_data_ctx.state.active_bind_texture_2d(2, rend_texture[0].depth_texture->glid); + rend_data_ctx.state.bind_sampler(2, sampler); mat4 mat; mat4_invert(&cam_view_projection, &mat); mat4_mul(&cam_view_projection_prev, &mat, &mat); - uniform->arr[U_REDUCE] = 6; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 6; camera_blur_shader_data shader_data = {}; shader_data.g_transform[0] = mat.row0; shader_data.g_transform[1] = mat.row1; shader_data.g_transform[2] = mat.row2; shader_data.g_transform[3] = mat.row3; - rctx->camera_blur_ubo.WriteMemory(shader_data); - rctx->camera_blur_ubo.Bind(1); + rctx->camera_blur_ubo.WriteMemory(rend_data_ctx.state, shader_data); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->camera_blur_ubo); } else { int32_t taa_texture_selector = this->taa_texture_selector + 1; if (taa_texture_selector > taa) taa_texture_selector = 0; - gl_rend_state.active_bind_texture_2d(1, taa_tex[taa_texture_selector]->glid); - gl_rend_state.bind_sampler(1, sampler); - uniform->arr[U_REDUCE] = 5; + rend_data_ctx.state.active_bind_texture_2d(1, taa_tex[taa_texture_selector]->glid); + rend_data_ctx.state.bind_sampler(1, sampler); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 5; } - shaders_ft.set(SHADER_FT_REDUCE); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); - draw_quad(render_post_width[0], render_post_height[0], + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, taa_blend); - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } if (taa) { @@ -148,88 +150,83 @@ namespace rndr { this->taa_texture_selector = taa_texture_selector; } - rctx->screen_buffer.Bind(); - gl_rend_state.set_viewport(0, 0, rctx->screen_width, rctx->screen_height); + rctx->screen_buffer.Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, rctx->screen_width, rctx->screen_height); if (ssaa) { - gl_rend_state.active_bind_texture_2d(0, taa_tex[taa_texture]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - uniform->arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(render_post_width[0], render_post_height[0], + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[taa_texture]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.shader_flags.arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform->arr[U_ALPHA_MASK] = 0; + rend_data_ctx.shader_flags.arr[U_ALPHA_MASK] = 0; } else { - gl_rend_state.active_bind_texture_2d(0, taa_tex[taa_texture]->glid); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[taa_texture]->glid); if (mag_filter == MAG_FILTER_NEAREST) - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); else - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); switch (mag_filter) { case MAG_FILTER_NEAREST: case MAG_FILTER_BILINEAR: default: - uniform->arr[U_MAGNIFY] = 0; + rend_data_ctx.shader_flags.arr[U_MAGNIFY] = 0; break; case MAG_FILTER_SHARPEN_5_TAP: - uniform->arr[U_MAGNIFY] = 2; + rend_data_ctx.shader_flags.arr[U_MAGNIFY] = 2; break; case MAG_FILTER_SHARPEN_4_TAP: - uniform->arr[U_MAGNIFY] = 3; + rend_data_ctx.shader_flags.arr[U_MAGNIFY] = 3; break; case MAG_FILTER_CONE_4_TAP: - uniform->arr[U_MAGNIFY] = 4; + rend_data_ctx.shader_flags.arr[U_MAGNIFY] = 4; break; case MAG_FILTER_CONE_2_TAP: - uniform->arr[U_MAGNIFY] = 5; + rend_data_ctx.shader_flags.arr[U_MAGNIFY] = 5; break; } - shaders_ft.set(SHADER_FT_MAGNIFY); - draw_quad(render_post_width[0], render_post_height[0], + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_MAGNIFY); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } - shader::unbind(); + shader::unbind(rend_data_ctx.state); for (int32_t i = 0; i < 8; i++) - gl_rend_state.bind_sampler(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); - fbo_blit(rctx->screen_buffer.fbos[0], 0, + fbo_blit(rend_data_ctx.state, rctx->screen_buffer.fbos[0], 0, 0, 0, rctx->screen_width, rctx->screen_height, 0, 0, rctx->screen_width, rctx->screen_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.bind_framebuffer(0); } - void Render::bind_render_texture(bool aet_back) { + void Render::bind_render_texture(p_gl_rend_state& p_gl_rend_st, bool aet_back) { if (aet_back) { - aet_back_texture.Bind(); + aet_back_texture.Bind(p_gl_rend_st); this->aet_back = 1; } else - rend_texture[0].Bind(); - gl_rend_state.set_viewport(0, 0, render_width[0], render_height[0]); + rend_texture[0].Bind(p_gl_rend_st); + p_gl_rend_st.set_viewport(0, 0, render_width[0], render_height[0]); } - void Render::calc_exposure_chara_data() { - shader::unbind(); + void Render::calc_exposure_chara_data(render_data_context& rend_data_ctx, const cam_data& cam) { + shader::unbind(rend_data_ctx.state); - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.disable_cull_face(); - shaders_ft.set(SHADER_FT_SUN_NO_TEXTURED); - gl_rend_state.bind_vertex_array(rctx->common_vao); - rctx->sun_quad_ubo.Bind(0); - - mat4 view; - mat4_transpose(&camera_data.view, &view); - mat4 projection; - mat4_transpose(&camera_data.projection, &projection); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SUN_NO_TEXTURED); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->sun_quad_ubo); ExposureCharaData* chara_data = exposure_chara_data; int32_t query_index = (this->exposure_query_index + 1) % 3; @@ -245,11 +242,11 @@ namespace rndr { mat4 mat = mat4_identity; sub_1405163C0(rob_chr, 4, &mat); - mat4_mul(&mat, &view, &mat); + mat4_mul(&mat, &cam.get_view_mat(), &mat); mat4_mul_translate(&mat, max_face_depth + 0.1f, 0.0f, -0.06f, &mat); mat4_clear_rot(&mat, &mat); mat4_scale_rot(&mat, 0.0035f, &mat); - mat4_mul(&mat, &projection, &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); sun_quad_shader_data shader_data = {}; mat4_transpose(&mat, &mat); @@ -258,10 +255,10 @@ namespace rndr { shader_data.g_transform[2] = mat.row2; shader_data.g_transform[3] = mat.row3; shader_data.g_emission = 0.0f; - rctx->sun_quad_ubo.WriteMemory(shader_data); + rctx->sun_quad_ubo.WriteMemory(rend_data_ctx.state, shader_data); glBeginQuery(GL_SAMPLES_PASSED, chara_data->query[next_query_index]); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); glEndQuery(GL_SAMPLES_PASSED); if (chara_data->query_data[next_query_index] == -1) @@ -279,36 +276,15 @@ namespace rndr { } } - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.bind_vertex_array(0); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.enable_cull_face(); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_cull_face(); } - void Render::calc_projection_matrix(mat4* mat, float_t fov, float_t aspect, float_t z_near, float_t z_far, - float_t left_offset, float_t right_offset, float_t bottom_offset, float_t top_offset) { - float_t tan_fov = (float_t)tan(fov * M_PI * (1.0 / 360.0)) * z_near; - float_t left = -tan_fov * aspect + tan_fov * aspect * left_offset; - float_t right = tan_fov * aspect + tan_fov * aspect * right_offset; - float_t bottom = -tan_fov + tan_fov * bottom_offset; - float_t top = tan_fov + tan_fov * top_offset; - - if (taa) { - float_t offset = taa_texture_selector == 1 ? -0.25f : 0.25f; - float_t left_right_offset = (right - left) * offset / (float_t)render_width[0]; - float_t bottom_top_offset = (top - bottom) * offset / (float_t)render_height[0]; - left += left_right_offset; - right += left_right_offset; - bottom += bottom_top_offset; - top += bottom_top_offset; - } - - mat4_frustrum(left, right, bottom, top, z_near, z_far, mat); - mat4_transpose(mat, mat); - } - - void Render::draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, + void Render::draw_quad(render_data_context& rend_data_ctx, + int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w) { s0 -= s1; t0 -= t1; @@ -321,13 +297,13 @@ namespace rndr { quad.g_color = { param_x, param_y, param_z, param_w }; quad.g_texture_lod = 0.0f; - rctx->quad_ubo.WriteMemory(quad); - rctx->quad_ubo.Bind(0); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rctx->quad_ubo.WriteMemory(rend_data_ctx.state, quad); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->quad_ubo); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); } - void Render::draw_lens_flare() { + void Render::draw_lens_flare(render_data_context& rend_data_ctx, const cam_data& cam) { static float_t flt_1411ACB84 = sinf(0.01365909819f); static float_t flt_1411ACB8C = tanf(0.01365909819f) * 2.0f * 0.94f; @@ -338,17 +314,7 @@ namespace rndr { if (!tex) return; - mat4 view; - mat4_transpose(&camera_data.view, &view); - mat4 projection; - mat4_transpose(&camera_data.projection, &projection); - - mat4 view_projection; - mat4 inverse_view_projection_matrix; - mat4_transpose(&camera_data.view_projection, &view_projection); - mat4_invert(&view_projection, &inverse_view_projection_matrix); - - float_t v5 = tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT); + float_t v5 = tanf(cam.get_fov() * 0.5f * DEG_TO_RAD_FLOAT); light_set* set = &light_set_data[LIGHT_SET_MAIN]; light_data* data = &set->lights[LIGHT_SUN]; @@ -371,7 +337,7 @@ namespace rndr { *(vec3*)&v44 = position; v44.w = 1.0f; - mat4_transform_vector(&view_projection, &v44, &v44); + mat4_transform_vector(&cam.get_view_proj_mat(), &v44, &v44); float_t v13 = 1.0f / v44.w; float_t v14 = v44.x * v13; @@ -382,7 +348,9 @@ namespace rndr { v44.x = v14 * v44.w; v44.y = v15 * v44.w; - mat4_transform_vector(&inverse_view_projection_matrix, &v44, &v44); + mat4 inv_view_proj_mat; + mat4_invert(&cam.get_view_proj_mat(), &inv_view_proj_mat); + mat4_transform_vector(&inv_view_proj_mat, &v44, &v44); void (FASTCALL * pos_scale__get_screen_pos_scale)(vec3 * data, vec3 * trans, __int64 r8, bool apply_offset) = (void(FASTCALL*)(vec3 * data, vec3 * trans, __int64 r8, bool apply_offset))0x00000001401F7EE0; @@ -401,10 +369,10 @@ namespace rndr { sun_quad_shader_data shader_data = {}; shader_data.g_emission = emission; - gl_rend_state.active_bind_texture_2d(0, tex); - shaders_ft.set(SHADER_FT_SUN); - gl_rend_state.bind_vertex_array(rctx->common_vao); - rctx->sun_quad_ubo.Bind(0); + rend_data_ctx.state.active_bind_texture_2d(0, tex); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SUN); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->sun_quad_ubo); int32_t query_index = (lens_flare_query_index + 1) % 3; lens_flare_query_index = query_index; @@ -416,46 +384,46 @@ namespace rndr { if (lens_flare_query_data[next_query_index] == -1) lens_flare_query_data[next_query_index] = 0; - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.disable_cull_face(); mat4 mat; - mat4_mul_translate(&view, &position, &mat); + mat4_mul_translate(&cam.get_view_mat(), &position, &mat); mat4_clear_rot(&mat, &mat); mat4_scale_rot(&mat, v24 * 0.2f, &mat); - mat4_mul(&mat, &projection, &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); mat4_transpose(&mat, &mat); shader_data.g_transform[0] = mat.row0; shader_data.g_transform[1] = mat.row1; shader_data.g_transform[2] = mat.row2; shader_data.g_transform[3] = mat.row3; - rctx->sun_quad_ubo.WriteMemory(shader_data); + rctx->sun_quad_ubo.WriteMemory(rend_data_ctx.state, shader_data); glBeginQuery(GL_SAMPLES_PASSED, lens_shaft_query[next_query_index]); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); glEndQuery(GL_SAMPLES_PASSED); - mat4_mul_translate(&view, (vec3*)&v44, &mat); + mat4_mul_translate(&cam.get_view_mat(), (vec3*)&v44, &mat); mat4_clear_rot(&mat, &mat); mat4_scale_rot(&mat, v24 * 2.0f, &mat); - mat4_mul(&mat, &projection, &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); mat4_transpose(&mat, &mat); shader_data.g_transform[0] = mat.row0; shader_data.g_transform[1] = mat.row1; shader_data.g_transform[2] = mat.row2; shader_data.g_transform[3] = mat.row3; - rctx->sun_quad_ubo.WriteMemory(shader_data); + rctx->sun_quad_ubo.WriteMemory(rend_data_ctx.state, shader_data); glBeginQuery(GL_SAMPLES_PASSED, lens_flare_query[next_query_index]); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); glEndQuery(GL_SAMPLES_PASSED); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.enable_cull_face(); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_cull_face(); if (lens_shaft_query_data[query_index] != -1) { int32_t res = 0; @@ -472,31 +440,31 @@ namespace rndr { } if (emission.x + emission.y + emission.z > 0.0f) { - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_ONE, GL_ONE); - gl_rend_state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ONE); + rend_data_ctx.state.set_depth_mask(GL_FALSE); - mat4_mul_translate(&view, &position, &mat); + mat4_mul_translate(&cam.get_view_mat(), &position, &mat); mat4_clear_rot(&mat, &mat); mat4_scale_rot(&mat, v24 * 1.1f, &mat); - mat4_mul(&mat, &projection, &mat); + mat4_mul(&mat, &cam.get_proj_mat(), &mat); mat4_transpose(&mat, &mat); shader_data.g_transform[0] = mat.row0; shader_data.g_transform[1] = mat.row1; shader_data.g_transform[2] = mat.row2; shader_data.g_transform[3] = mat.row3; - rctx->sun_quad_ubo.WriteMemory(shader_data); + rctx->sun_quad_ubo.WriteMemory(rend_data_ctx.state, shader_data); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.disable_blend(); - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.state.set_depth_mask(GL_TRUE); } - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.bind_vertex_array(0); if (lens_flare_appear_power <= 0.01f) lens_flare_appear_power = 0.0f; @@ -631,6 +599,14 @@ namespace rndr { } } + vec2 Render::get_taa_offset() { + if (taa) { + float_t offset = taa_texture_selector == 1 ? -0.25f : 0.25f; + return -offset / vec2((float_t)render_width[0], (float_t)render_height[0]); + } + return 0.0; + } + void Render::init_render_buffers(int32_t width, int32_t height, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask) { this->ssaa = ssaa; @@ -673,10 +649,10 @@ namespace rndr { rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); - gl_rend_state.bind_texture_2d(rend_texture[0].GetColorTex()); + gl_state.bind_texture_2d(rend_texture[0].GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl_rend_state.bind_texture_2d(rend_texture[0].GetDepthTex()); + gl_state.bind_texture_2d(rend_texture[0].GetDepthTex()); GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); @@ -694,19 +670,19 @@ namespace rndr { temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); sss_contour_texture = &mlaa_buffer; - gl_rend_state.bind_texture_2d(mlaa_buffer.GetDepthTex()); + gl_state.bind_texture_2d(mlaa_buffer.GetDepthTex()); glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); for (int32_t i = 1; i < downsample_count; i++) { rend_texture[i].Init(render_post_width[i], render_post_height[i], 0, GL_RGBA16F, GL_ZERO); - gl_rend_state.bind_texture_2d(rend_texture[i].GetColorTex()); + gl_state.bind_texture_2d(rend_texture[i].GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } downsample_texture.Init(reduce_width[0], reduce_height[0], 0, GL_RGBA16F, GL_ZERO); - gl_rend_state.bind_texture_2d(downsample_texture.GetColorTex()); + gl_state.bind_texture_2d(downsample_texture.GetColorTex()); const vec4 border_color = 0.0f; glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); @@ -725,11 +701,11 @@ namespace rndr { rend_texture[0].GetDepthTex(), render_post_width[0], render_post_height[0]); } - void Render::init_tone_map_buffers() { + void Render::init_post_process_buffers() { for (int32_t i = 0; i < 5; i++) { reduce_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), GL_RGBA16F, reduce_width[i], reduce_height[i], 0, 0, 0); - gl_rend_state.bind_texture_2d(reduce_tex[i]->glid); + gl_state.bind_texture_2d(reduce_tex[i]->glid); const vec4 border_color = 0.0f; glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); @@ -743,18 +719,18 @@ namespace rndr { GL_RGBA16F, 32, 2, 0, 0, 0); glGenTextures(1, &exposure_tex); - gl_rend_state.bind_texture_2d(exposure_tex); + gl_state.bind_texture_2d(exposure_tex); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RGBA32F, 2, 2, 0, GL_RGBA, GL_FLOAT, 0); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl_rend_state.bind_texture_2d(0); + gl_state.bind_texture_2d(0); exposure_texture.SetColorDepthTextures(exposure_tex); glGenTextures(1, &tonemap_lut_texture); - gl_rend_state.bind_texture_2d(tonemap_lut_texture); + gl_state.bind_texture_2d(tonemap_lut_texture); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG16F, 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, 0, GL_RG, GL_HALF_FLOAT, 0); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -762,7 +738,7 @@ namespace rndr { glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); const GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - gl_rend_state.bind_texture_2d(0); + gl_state.bind_texture_2d(0); generate_mlaa_area_texture(); @@ -814,20 +790,22 @@ namespace rndr { aet_back = 0; } - void Render::pre_proc() { + void Render::pre_proc(render_data_context& rend_data_ctx) { static int32_t(FASTCALL * task_stage_get_current_stage_index)() = (int32_t(FASTCALL*)())0x000000014064ADA0; + cam_data& cam = rctx->render_manager_cam; + view_point_prev = view_point; interest_prev = interest; - view_point = camera_data.view_point; - interest = camera_data.interest; + view_point = cam.get_view_point(); + interest = cam.get_interest(); stage_index_prev = stage_index; stage_index = task_stage_get_current_stage_index(); cam_view_projection_prev = cam_view_projection; - cam_view_projection = camera_data.view_projection; + cam_view_projection = cam.get_view_proj_mat(); reset_exposure = camera_data.fast_change_hist1 && !camera_data.fast_change_hist0; if (reset_exposure) { @@ -854,17 +832,23 @@ namespace rndr { = (texture * (FASTCALL*)(size_t task_movie))0x000000014041ED80; texture* movie_texture = sub_14041ED80(task_movie); if (movie_texture) { - movie_textures[0].Bind(); - gl_rend_state.set_viewport(0, 0, movie_textures_data[0]->width, movie_textures_data[0]->height); - gl_rend_state.active_bind_texture_2d(0, movie_texture->glid); - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(movie_texture->width, movie_texture->height, + movie_textures[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, movie_textures_data[0]->width, movie_textures_data[0]->height); + rend_data_ctx.state.active_bind_texture_2d(0, movie_texture->glid); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, movie_texture->width, movie_texture->height, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.bind_framebuffer(0); } } } + + for (int32_t i = 0; i < GL_REND_STATE_COUNT; i++) { + render_data_context rend_data_ctx((gl_rend_state_index)i); + rend_data_ctx.set_scene_framebuffer_size( + render_width[0], render_height[0], render_width[0], render_height[0]); + } } int32_t Render::render_texture_set(texture* render_texture, bool task_photo) { @@ -923,10 +907,10 @@ namespace rndr { rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); - gl_rend_state.bind_texture_2d(rend_texture[0].GetColorTex()); + gl_state.bind_texture_2d(rend_texture[0].GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl_rend_state.bind_texture_2d(rend_texture[0].GetDepthTex()); + gl_state.bind_texture_2d(rend_texture[0].GetDepthTex()); GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); @@ -948,13 +932,13 @@ namespace rndr { temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); sss_contour_texture = &mlaa_buffer; - gl_rend_state.bind_texture_2d(mlaa_buffer.GetDepthTex()); + gl_state.bind_texture_2d(mlaa_buffer.GetDepthTex()); glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); for (int32_t i = 1; i < downsample_count; i++) { rend_texture[i].Init(render_post_width[i], render_post_height[i], 0, GL_RGBA16F, GL_ZERO); - gl_rend_state.bind_texture_2d(rend_texture[i].GetColorTex()); + gl_state.bind_texture_2d(rend_texture[i].GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } @@ -971,56 +955,56 @@ namespace rndr { render_post_width[0], render_post_height[0]); } - void Render::downsample() { - uniform->arr[U_REDUCE] = 1; - shaders_ft.set(SHADER_FT_REDUCE); + void Render::downsample(render_data_context& rend_data_ctx) { + rend_data_ctx.shader_flags.arr[U_REDUCE] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); for (int32_t i = 1; i < downsample_count - 1; i++) { - rend_texture[i].Bind(); - gl_rend_state.active_bind_texture_2d(0, rend_texture[i - 1].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.set_viewport(0, 0, render_width[i], render_height[i]); - draw_quad( + rend_texture[i].Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, rend_texture[i - 1].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.set_viewport(0, 0, render_width[i], render_height[i]); + draw_quad(rend_data_ctx, render_post_width[i - 1], render_post_height[i - 1], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } - uniform->arr[U_REDUCE] = 3; - shaders_ft.set(SHADER_FT_REDUCE); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 3; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); int32_t downsample = max_def(downsample_count - 2, 0); - gl_rend_state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); - reduce_texture[0].Bind(); - gl_rend_state.active_bind_texture_2d(0, rend_texture[downsample].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - draw_quad( + rend_data_ctx.state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, rend_texture[downsample].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + draw_quad(rend_data_ctx, render_post_width[downsample], render_post_height[downsample], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.1f, 1.1f, 1.1f, 0.0f); - downsample_texture.Bind(); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[0]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); + downsample_texture.Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[0]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); for (int32_t i = 1; i < 5; i++) { float_t scale; if (i == 4) { scale = 1.0f; - uniform->arr[U_EXPOSURE] = 0; - shaders_ft.set(SHADER_FT_EXPOSURE); + rend_data_ctx.shader_flags.arr[U_EXPOSURE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_EXPOSURE); } else { scale = 0.75; - uniform->arr[U_REDUCE] = 1; - shaders_ft.set(SHADER_FT_REDUCE); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); } - gl_rend_state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); - draw_quad(reduce_width[i - 1], reduce_height[i - 1], + rend_data_ctx.state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); + draw_quad(rend_data_ctx, reduce_width[i - 1], reduce_height[i - 1], 1.0f, 1.0f, 0.0f, 0.0f, scale, 1.0f, 1.0f, 1.0f, 1.0f); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[i]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[i]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } } @@ -1034,7 +1018,8 @@ namespace rndr { update = 1; } - void Render::take_ss(texture* tex, bool vertical, float_t horizontal_offset) { + void Render::take_ss(render_data_context& rend_data_ctx, + texture* tex, bool vertical, float_t horizontal_offset) { int32_t index = render_texture_set(tex, true); if (index < 0) return; @@ -1048,30 +1033,30 @@ namespace rndr { x_max = center + area; } - render_textures[index].Bind(); + render_textures[index].Bind(rend_data_ctx.state); texture* rend_tex = render_textures_data[index]; - uniform->arr[U_REDUCE] = 0; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; - gl_rend_state.set_viewport(0, 0, rend_tex->width, rend_tex->height); - gl_rend_state.active_bind_texture_2d(0, rctx->screen_buffer.GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(rend_tex->width, rend_tex->height, + rend_data_ctx.state.set_viewport(0, 0, rend_tex->width, rend_tex->height); + rend_data_ctx.state.active_bind_texture_2d(0, rctx->screen_buffer.GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, rend_tex->width, rend_tex->height, x_max, 1.0f, x_min, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.bind_sampler(0, 0); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.bind_sampler(0, 0); render_texture_free(tex, true); } - void Render::transparency_combine(float_t alpha) { - transparency->combine(rend_texture, alpha); + void Render::transparency_combine(render_data_context& rend_data_ctx, float_t alpha) { + transparency->combine(rend_data_ctx, rend_texture, alpha); } - void Render::transparency_copy() { - transparency->copy(rend_texture[0].GetColorTex()); + void Render::transparency_copy(render_data_context& rend_data_ctx) { + transparency->copy(rend_data_ctx, rend_texture[0].GetColorTex()); } void Render::update_res(bool set, int32_t base_downsample) { @@ -1112,7 +1097,7 @@ namespace rndr { * (float_t)inner_width / (float_t)width * (1.0f / round_val)) * round_val); render_height[0] = (int32_t)(prj::ceilf((float_t)screen_height * (float_t)inner_height / (float_t)height * (1.0f / round_val)) * round_val);*/ - + render_width[0] = (int32_t)prj::ceilf((float_t)screen_width * (float_t)inner_width / (float_t)width); render_height[0] = (int32_t)prj::ceilf((float_t)screen_height @@ -1143,73 +1128,80 @@ namespace rndr { render_post_width_scale = (float_t)render_width[0] / (float_t)render_post_width[0]; render_post_height_scale = (float_t)render_height[0] / (float_t)render_post_height[0]; + for (int32_t i = 0; i < GL_REND_STATE_COUNT; i++) { + render_data_context rend_data_ctx((gl_rend_state_index)i); + rend_data_ctx.set_scene_framebuffer_size( + render_width[0], render_height[0], render_width[0], render_height[0]); + } + taa_blend = -1.0f; } - void Render::apply_mlaa(int32_t destination, int32_t source, int32_t mlaa) { - gl_rend_state.begin_event("PostProcess::mlaa"); + void Render::apply_mlaa(render_data_context& rend_data_ctx, + int32_t destination, int32_t source, int32_t mlaa) { + rend_data_ctx.state.begin_event("PostProcess::mlaa"); if (mlaa) { - mlaa_buffer.Bind(); - gl_rend_state.active_bind_texture_2d(0, taa_tex[source]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - uniform->arr[U_MLAA] = 0; - shaders_ft.set(SHADER_FT_MLAA); - draw_quad(render_post_width[0], render_post_height[0], + mlaa_buffer.Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[source]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.shader_flags.arr[U_MLAA] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_MLAA); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - temp_buffer.Bind(); - gl_rend_state.active_bind_texture_2d(0, mlaa_buffer.GetColorTex()); - gl_rend_state.active_bind_texture_2d(1, mlaa_area_texture); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(1, rctx->render_samplers[3]); - uniform->arr[U_MLAA] = 1; - uniform->arr[U_MLAA_SEARCH] = 2; - shaders_ft.set(SHADER_FT_MLAA); - draw_quad(render_post_width[0], render_post_height[0], + temp_buffer.Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, mlaa_buffer.GetColorTex()); + rend_data_ctx.state.active_bind_texture_2d(1, mlaa_area_texture); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[3]); + rend_data_ctx.shader_flags.arr[U_MLAA] = 1; + rend_data_ctx.shader_flags.arr[U_MLAA_SEARCH] = 2; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_MLAA); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - taa_buffer[destination].Bind(); - gl_rend_state.active_bind_texture_2d(0, taa_tex[source]->glid); - gl_rend_state.active_bind_texture_2d(1, temp_buffer.GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - gl_rend_state.bind_sampler(1, rctx->render_samplers[1]); - uniform->arr[U_MLAA] = 2; - uniform->arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; - shaders_ft.set(SHADER_FT_MLAA); - draw_quad(render_post_width[0], render_post_height[0], + taa_buffer[destination].Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[source]->glid); + rend_data_ctx.state.active_bind_texture_2d(1, temp_buffer.GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[1]); + rend_data_ctx.shader_flags.arr[U_MLAA] = 2; + rend_data_ctx.shader_flags.arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_MLAA); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform->arr[U_ALPHA_MASK] = 0; - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.active_bind_texture_2d(1, 0); + rend_data_ctx.shader_flags.arr[U_ALPHA_MASK] = 0; + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.active_bind_texture_2d(1, 0); } else { - taa_buffer[destination].Bind(); - gl_rend_state.active_bind_texture_2d(0, taa_tex[source]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(render_post_width[0], render_post_height[0], + taa_buffer[destination].Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, taa_tex[source]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, render_post_width[0], render_post_height[0], render_post_width_scale, render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } - void Render::apply_tone_map(texture* light_proj_tex, int32_t npr_param) { + void Render::apply_tone_map(render_data_context& rend_data_ctx, texture* light_proj_tex, int32_t npr_param) { if (!this) return; - - gl_rend_state.begin_event("PostProcess::tone_map"); - update_tone_map_lut(); + rend_data_ctx.state.begin_event("PostProcess::tone_map"); - uniform->arr[U_TONE_MAP] = (int32_t)tone_map; - uniform->arr[U_FLARE] = 0; - uniform->arr[U_AET_BACK] = 0; - uniform->arr[U_LIGHT_PROJ] = 0; + update_tone_map_lut(rend_data_ctx.state); + + rend_data_ctx.shader_flags.arr[U_TONE_MAP] = (int32_t)tone_map; + rend_data_ctx.shader_flags.arr[U_FLARE] = 0; + rend_data_ctx.shader_flags.arr[U_AET_BACK] = 0; + rend_data_ctx.shader_flags.arr[U_LIGHT_PROJ] = 0; int32_t scene_fade_blend_func = this->scene_fade_blend_func[scene_fade_index]; @@ -1236,21 +1228,21 @@ namespace rndr { shader_data.g_texcoord_transforms[2] = { 1.0f, 0.0f, 0.0f, 0.0f }; shader_data.g_texcoord_transforms[3] = { 0.0f, 1.0f, 0.0f, 0.0f }; - gl_rend_state.active_bind_texture_2d(0, rend_texture[0].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - gl_rend_state.active_bind_texture_2d(1, reduce_tex_draw); - gl_rend_state.bind_sampler(1, rctx->render_samplers[2]); - gl_rend_state.active_bind_texture_2d(2, tonemap_lut_texture); - gl_rend_state.bind_sampler(2, rctx->render_samplers[0]); - gl_rend_state.active_bind_texture_2d(3, exposure_tex); - gl_rend_state.bind_sampler(3, rctx->render_samplers[3]); + rend_data_ctx.state.active_bind_texture_2d(0, rend_texture[0].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, reduce_tex_draw); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(2, tonemap_lut_texture); + rend_data_ctx.state.bind_sampler(2, rctx->render_samplers[0]); + rend_data_ctx.state.active_bind_texture_2d(3, exposure_tex); + rend_data_ctx.state.bind_sampler(3, rctx->render_samplers[3]); if (lens_flare_texture) { const float_t aspect = (float_t)height / (float_t)width; - uniform->arr[U_FLARE] = 1; - gl_rend_state.active_bind_texture_2d(4, lens_flare_texture); - gl_rend_state.bind_sampler(4, rctx->render_samplers[2]); + rend_data_ctx.shader_flags.arr[U_FLARE] = 1; + rend_data_ctx.state.active_bind_texture_2d(4, lens_flare_texture); + rend_data_ctx.state.bind_sampler(4, rctx->render_samplers[2]); mat4 mat; mat4_translate(0.5f, 0.5f, 0.0f, &mat); @@ -1265,9 +1257,9 @@ namespace rndr { shader_data.g_texcoord_transforms[5] = mat.row1; if (lens_shaft_scale < 50.0f) { - uniform->arr[U_FLARE] = 2; - gl_rend_state.active_bind_texture_2d(5, lens_shaft_texture); - gl_rend_state.bind_sampler(5, rctx->render_samplers[2]); + rend_data_ctx.shader_flags.arr[U_FLARE] = 2; + rend_data_ctx.state.active_bind_texture_2d(5, lens_shaft_texture); + rend_data_ctx.state.bind_sampler(5, rctx->render_samplers[2]); mat4_translate(0.5f, 0.5f, 0.0f, &mat); mat4_scale_rot(&mat, lens_shaft_scale, lens_shaft_scale, 1.0f, &mat); @@ -1281,18 +1273,18 @@ namespace rndr { shader_data.g_texcoord_transforms[7] = mat.row1; } else { - gl_rend_state.active_bind_texture_2d(5, rctx->empty_texture_2d->glid); - gl_rend_state.bind_sampler(5, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(5, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(5, rctx->render_samplers[2]); shader_data.g_texcoord_transforms[6] = { 1.0f, 0.0f, 0.0f, 0.0f }; shader_data.g_texcoord_transforms[7] = { 0.0f, 1.0f, 0.0f, 0.0f }; } } else { - gl_rend_state.active_bind_texture_2d(4, rctx->empty_texture_2d->glid); - gl_rend_state.bind_sampler(4, rctx->render_samplers[2]); - gl_rend_state.active_bind_texture_2d(5, rctx->empty_texture_2d->glid); - gl_rend_state.bind_sampler(5, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(4, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(4, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(5, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(5, rctx->render_samplers[2]); shader_data.g_texcoord_transforms[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; shader_data.g_texcoord_transforms[5] = { 0.0f, 1.0f, 0.0f, 0.0f }; @@ -1301,42 +1293,41 @@ namespace rndr { } if (aet_back) { - gl_rend_state.active_bind_texture_2d(6, aet_back_tex->glid); - gl_rend_state.bind_sampler(6, rctx->render_samplers[2]); - uniform->arr[U_AET_BACK] = 1; + rend_data_ctx.state.active_bind_texture_2d(6, aet_back_tex->glid); + rend_data_ctx.state.bind_sampler(6, rctx->render_samplers[2]); + rend_data_ctx.shader_flags.arr[U_AET_BACK] = 1; } if (light_proj_tex) { - uniform->arr[U_LIGHT_PROJ] = 1; - gl_rend_state.active_bind_texture_2d(7, light_proj_tex->glid); - gl_rend_state.bind_sampler(7, rctx->render_samplers[2]); + rend_data_ctx.shader_flags.arr[U_LIGHT_PROJ] = 1; + rend_data_ctx.state.active_bind_texture_2d(7, light_proj_tex->glid); + rend_data_ctx.state.bind_sampler(7, rctx->render_samplers[2]); shader_data.g_flare_coef.z = 1.0f; } else { - gl_rend_state.active_bind_texture_2d(7, rctx->empty_texture_2d->glid); - gl_rend_state.bind_sampler(7, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(7, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(7, rctx->render_samplers[2]); } if (aet_back && npr_param == 1) { - gl_rend_state.active_bind_texture_2d(14, rend_texture[0].GetDepthTex()); - gl_rend_state.bind_sampler(14, rctx->render_samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(14, rend_texture[0].GetDepthTex()); + rend_data_ctx.state.bind_sampler(14, rctx->render_samplers[1]); } - rctx->tone_map_ubo.WriteMemory(shader_data); + rctx->tone_map_ubo.WriteMemory(rend_data_ctx.state, shader_data); - gl_rend_state.set_viewport(0, 0, render_width[0], render_height[0]); - taa_buffer[2].Bind(); - shaders_ft.set(SHADER_FT_TONEMAP); - rctx->tone_map_ubo.Bind(1); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.active_bind_texture_2d(2, 0); - gl_rend_state.end_event(); + rend_data_ctx.state.set_viewport(0, 0, render_width[0], render_height[0]); + taa_buffer[2].Bind(rend_data_ctx.state); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_TONEMAP); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->tone_map_ubo); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.active_bind_texture_2d(2, 0); + rend_data_ctx.state.end_event(); } - - void Render::calc_exposure() { + void Render::calc_exposure(render_data_context& rend_data_ctx, const cam_data& cam) { bool v2 = false; if (!reset_exposure) { ExposureCharaData* chara_data = exposure_chara_data; @@ -1354,10 +1345,8 @@ namespace rndr { mat4 v42; mat4 v43; - mat4_mul(&camera_data.view, &v44, &v42); - mat4_mul(&camera_data.projection, &v42, &v43); - mat4_transpose(&v42, &v42); - mat4_transpose(&v43, &v43); + mat4_mul(&v44, &cam.view_mat, &v42); + mat4_mul(&v42, &cam.proj_mat, &v43); vec4 v41; vec4 v40; @@ -1442,41 +1431,40 @@ namespace rndr { for (int32_t i = 0; i < 4 && i < ROB_CHARA_COUNT; i++, chara_data++) for (int32_t j = 0; j < 8; j++) exposure_measure.g_spot_coefficients[i * 8 + j] = chara_data->spot_coefficients[j]; - rctx->exposure_measure_ubo.WriteMemory(exposure_measure); + rctx->exposure_measure_ubo.WriteMemory(rend_data_ctx.state, exposure_measure); - gl_rend_state.set_viewport(0, 0, 32, 1); - downsample_texture.Bind(); + rend_data_ctx.state.set_viewport(0, 0, 32, 1); + downsample_texture.Bind(rend_data_ctx.state); - uniform->arr[U_EXPOSURE] = 1; - shaders_ft.set(SHADER_FT_EXPOSURE); - rctx->exposure_measure_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[4]->glid); - gl_rend_state.active_bind_texture_2d(1, reduce_tex[2]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - gl_rend_state.bind_sampler(1, rctx->render_samplers[2]); - draw_quad(1, 1, 1.0f, 1.0f, + rend_data_ctx.shader_flags.arr[U_EXPOSURE] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_EXPOSURE); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->exposure_measure_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[4]->glid); + rend_data_ctx.state.active_bind_texture_2d(1, reduce_tex[2]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[2]); + draw_quad(rend_data_ctx, 1, 1, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - gl_rend_state.active_bind_texture_2d(0, exposure_history->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(0, exposure_history->glid); if (reset_exposure) - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 32, 1); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 32, 1); else - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, exposure_history_counter, 0, 0, 0, 1, 1); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, 0, exposure_history_counter, 0, 0, 0, 1, 1); exposure_history_counter = (exposure_history_counter + 1) % 32; } - gl_rend_state.set_viewport(0, 0, 1, 1); - exposure_texture.Bind(); - uniform->arr[U_EXPOSURE] = 2; - shaders_ft.set(SHADER_FT_EXPOSURE); - gl_rend_state.active_bind_texture_2d(0, exposure_history->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - draw_quad(1, 1, 1.0f, 1.0f, + rend_data_ctx.state.set_viewport(0, 0, 1, 1); + exposure_texture.Bind(rend_data_ctx.state); + rend_data_ctx.shader_flags.arr[U_EXPOSURE] = 2; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_EXPOSURE); + rend_data_ctx.state.active_bind_texture_2d(0, exposure_history->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + draw_quad(rend_data_ctx, 1, 1, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } - void Render::calc_gaussian_blur(float_t start, float_t step, + void Render::calc_gaussian_blur(render_data_context& rend_data_ctx, float_t start, float_t step, int32_t kernel_size, float_t radius_scale, float_t intensity_scale) { auto calculate_gaussian_kernel = [&](float_t* gaussian_kernel, float_t radius, int32_t stride, int32_t offset) { @@ -1513,7 +1501,53 @@ namespace rndr { *(vec3*)&gaussian_coef.g_coef[i] = gauss[i] * intensity; gaussian_coef.g_coef[i].w = 0.0f; } - rctx->gaussian_coef_ubo.WriteMemory(gaussian_coef); + rctx->gaussian_coef_ubo.WriteMemory(rend_data_ctx.state, gaussian_coef); + } + + void Render::calc_taa_blend() { + taa_blend = 1.0f; + + float_t view_point_dist = vec3::distance(view_point, view_point_prev); + float_t interest_dist = vec3::distance(interest, interest_prev); + float_t dist = max_def(view_point_dist, interest_dist); + + if (!reset_exposure) { + if (dist < 0.0001f) + taa_blend = 0.5f; + else if (dist < 0.005f) + taa_blend = 0.75f; + else if (dist < 0.03f) + taa_blend = 0.875f; + else if (dist <= 0.05f && cam_blur) + taa_blend = 0.999f; + } + } + + void Render::copy_to_frame_texture(render_data_context& rend_data_ctx, + GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex) { + for (Render::FrameTexture& i : frame_texture) { + if (!i.capture) + continue; + + for (auto& j : i.data) { + if (!j.texture || j.render_texture.Bind(rend_data_ctx.state) < 0) + continue; + + texture* dst_tex = j.texture; + + rend_data_ctx.state.active_bind_texture_2d(0, j.type == FRAME_TEXTURE_PRE_PP ? pre_pp_tex : post_pp_tex); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.set_viewport(0, 0, dst_tex->width, dst_tex->height); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + draw_quad(rend_data_ctx, dst_tex->width, dst_tex->height, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + rend_data_ctx.state.bind_framebuffer(0); + } + + if (&i - frame_texture) + i.capture = false; + } } static void make_ghost_quad(uint8_t flags, float_t opacity, mat4* mat, float_t*& data) { @@ -1546,52 +1580,7 @@ namespace rndr { data += 30; } - void Render::calc_taa_blend() { - taa_blend = 1.0f; - - float_t view_point_dist = vec3::distance(view_point, view_point_prev); - float_t interest_dist = vec3::distance(interest, interest_prev); - float_t dist = max_def(view_point_dist, interest_dist); - - if (!reset_exposure) { - if (dist < 0.0001f) - taa_blend = 0.5f; - else if (dist < 0.005f) - taa_blend = 0.75f; - else if (dist < 0.03f) - taa_blend = 0.875f; - else if (dist <= 0.05f && cam_blur) - taa_blend = 0.999f; - } - } - - void Render::copy_to_frame_texture(GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex) { - for (Render::FrameTexture& i : frame_texture) { - if (!i.capture) - continue; - - for (auto& j : i.data) { - if (!j.texture || j.render_texture.Bind() < 0) - continue; - - texture* dst_tex = j.texture; - - gl_rend_state.active_bind_texture_2d(0, j.type == FRAME_TEXTURE_PRE_PP ? pre_pp_tex : post_pp_tex); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.set_viewport(0, 0, dst_tex->width, dst_tex->height); - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - draw_quad(dst_tex->width, dst_tex->height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - gl_rend_state.bind_framebuffer(0); - } - - if (&i - frame_texture) - i.capture = false; - } - } - - void Render::draw_lens_ghost() { + void Render::draw_lens_ghost(render_data_context& rend_data_ctx) { static const float_t v13[16] = { -0.70f, -0.30f, 0.35f, 0.50f, -0.45f, -0.80f, 0.20f, 0.41f, @@ -1633,7 +1622,7 @@ namespace rndr { const float_t angle_sin = sinf(angle); const float_t angle_cos = cosf(angle); - float_t* data = (float_t*)rctx->lens_ghost_vbo.MapMemory(); + float_t* data = (float_t*)rctx->lens_ghost_vbo.MapMemory(rend_data_ctx.state); if (!data) return; @@ -1651,23 +1640,23 @@ namespace rndr { make_ghost_quad((uint8_t)(i & 0x03), opacity, &mat, data); } - rctx->lens_ghost_vbo.UnmapMemory(); + rctx->lens_ghost_vbo.UnmapMemory(rend_data_ctx.state); - gl_rend_state.set_viewport(0, 0, render_width[0], render_height[0]); - rend_texture[0].Bind(); - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_ONE, GL_ONE); + rend_data_ctx.state.set_viewport(0, 0, render_width[0], render_height[0]); + rend_texture[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ONE); - uniform->arr[U_REDUCE] = 4; - shaders_ft.set(SHADER_FT_REDUCE); - gl_rend_state.active_bind_texture_2d(0, lens_ghost_texture); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->lens_ghost_vao); - shaders_ft.draw_arrays(GL_TRIANGLES, 0, (GLsizei)(lens_ghost_count * 6LL)); - gl_rend_state.bind_vertex_array(0); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 4; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + rend_data_ctx.state.active_bind_texture_2d(0, lens_ghost_texture); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->lens_ghost_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLES, 0, (GLsizei)(lens_ghost_count * 6LL)); + rend_data_ctx.state.bind_vertex_array(0); - gl_rend_state.disable_blend(); - gl_rend_state.set_blend_func(GL_ONE, GL_ZERO); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.set_blend_func(GL_ONE, GL_ZERO); } void Render::generate_mlaa_area_texture() { @@ -1680,68 +1669,70 @@ namespace rndr { calculate_mlaa_area_texture_data(data, cross1, cross2); glGenTextures(1, &mlaa_area_texture); - gl_rend_state.bind_texture_2d(mlaa_area_texture); + gl_state.bind_texture_2d(mlaa_area_texture); glPixelStoreiDLL(GL_UNPACK_ALIGNMENT, 1); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG8, MLAA_SIDE_LEN, MLAA_SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data); - gl_rend_state.bind_texture_2d(0); + gl_state.bind_texture_2d(0); free_def(data); } - void Render::get_blur() { - uniform->arr[U_ALPHA_MASK] = 0; - uniform->arr[U_GAUSS] = 0; - shaders_ft.set(SHADER_FT_GAUSS); - calc_gaussian_blur(1.0f, 1.0f, 7, 0.8f, 1.0f); - rctx->gaussian_coef_ubo.Bind(1); + void Render::get_blur(render_data_context& rend_data_ctx) { + rend_data_ctx.shader_flags.arr[U_ALPHA_MASK] = 0; + rend_data_ctx.shader_flags.arr[U_GAUSS] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_GAUSS); + calc_gaussian_blur(rend_data_ctx, 1.0f, 1.0f, 7, 0.8f, 1.0f); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->gaussian_coef_ubo); - downsample_texture.Bind(); + downsample_texture.Bind(rend_data_ctx.state); for (int32_t i = 1; i < 4; i++) { - gl_rend_state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[i]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - draw_quad(reduce_width[i], reduce_height[i], + rend_data_ctx.state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[i]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + draw_quad(rend_data_ctx, reduce_width[i], reduce_height[i], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f); - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } for (int32_t i = 1; i < 4; i++) { - gl_rend_state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[i]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - draw_quad(reduce_width[i], reduce_height[i], + rend_data_ctx.state.set_viewport(0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[i]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + draw_quad(rend_data_ctx, reduce_width[i], reduce_height[i], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, + 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); } - uniform->arr[U_GAUSS] = 1; - shaders_ft.set(SHADER_FT_GAUSS); + rend_data_ctx.shader_flags.arr[U_GAUSS] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_GAUSS); - gl_rend_state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); - gl_rend_state.active_bind_texture_2d(0, reduce_tex[0]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - draw_quad(reduce_width[0], reduce_height[0], + rend_data_ctx.state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); + rend_data_ctx.state.active_bind_texture_2d(0, reduce_tex[0]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + draw_quad(rend_data_ctx, reduce_width[0], reduce_height[0], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, intensity.x * 0.5f, intensity.y * 0.5f, intensity.z * 0.5f, 1.0f); - uniform->arr[U_REDUCE] = 7; - shaders_ft.set(SHADER_FT_REDUCE); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 7; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); - gl_rend_state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); - reduce_texture[0].Bind(); - gl_rend_state.active_bind_texture_2d(0, downsample_texture.GetColorTex()); - gl_rend_state.active_bind_texture_2d(1, reduce_tex[1]->glid); - gl_rend_state.active_bind_texture_2d(2, reduce_tex[2]->glid); - gl_rend_state.active_bind_texture_2d(3, reduce_tex[3]->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[2]); - gl_rend_state.bind_sampler(1, rctx->render_samplers[2]); - gl_rend_state.bind_sampler(2, rctx->render_samplers[2]); - gl_rend_state.bind_sampler(3, rctx->render_samplers[2]); - draw_quad(reduce_width[3], reduce_height[3], + rend_data_ctx.state.set_viewport(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.active_bind_texture_2d(0, downsample_texture.GetColorTex()); + rend_data_ctx.state.active_bind_texture_2d(1, reduce_tex[1]->glid); + rend_data_ctx.state.active_bind_texture_2d(2, reduce_tex[2]->glid); + rend_data_ctx.state.active_bind_texture_2d(3, reduce_tex[3]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[2]); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[2]); + rend_data_ctx.state.bind_sampler(2, rctx->render_samplers[2]); + rend_data_ctx.state.bind_sampler(3, rctx->render_samplers[2]); + draw_quad(rend_data_ctx, reduce_width[3], reduce_height[3], 1.0f, 1.0f, 0.0f, 0.0f, 0.25f, 0.15f, 0.25f, 0.25f, 0.25f); reduce_tex_draw = reduce_tex[0]->glid; } - void Render::update_tone_map_lut() { + void Render::update_tone_map_lut(p_gl_rend_state& p_gl_rend_st) { if (!update_lut) return; @@ -1777,7 +1768,7 @@ namespace rndr { glTextureSubImage2D(tonemap_lut_texture, 0, 0, 0, 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); else { - gl_rend_state.bind_texture_2d(tonemap_lut_texture); + p_gl_rend_st.bind_texture_2d(tonemap_lut_texture); glTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); } @@ -1797,7 +1788,7 @@ namespace rndr { _data += MLAA_GRID_SIDE_LEN * 4 * 2; } } - + static float_t calc_area_tex_val(int32_t a1, int32_t a2) { float_t v2 = (float_t)(-0.5 / ((float_t)a2 - 0.5)); float_t v3 = (float_t)a1 * v2 + 0.5f; diff --git a/src/DivaGL/render.hpp b/src/DivaGL/render.hpp index b84eef0..412c0e1 100644 --- a/src/DivaGL/render.hpp +++ b/src/DivaGL/render.hpp @@ -19,6 +19,10 @@ enum tone_map_method { TONE_MAP_MAX = 3, }; +struct cam_data; +struct p_gl_rend_state; +struct render_data_context; + namespace rndr { struct Render { enum MagFilterType { @@ -173,44 +177,48 @@ namespace rndr { int32_t update; FrameTexture frame_texture[6]; - void apply_post_process(texture* light_proj_tex, int32_t npr_param); - void bind_render_texture(bool aet_back = false); - void calc_exposure_chara_data(); - void calc_projection_matrix(mat4* mat, float_t fov, float_t aspect, float_t z_near, float_t z_far, - float_t left_offset, float_t right_offset, float_t bottom_offset, float_t top_offset); - void draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, + void apply_post_process(render_data_context& rend_data_ctx, + const cam_data& cam, texture* light_proj_tex, int32_t npr_param); + void bind_render_texture(p_gl_rend_state& p_gl_rend_st, bool aet_back = false); + void calc_exposure_chara_data(render_data_context& rend_data_ctx, const cam_data& cam); + void draw_quad(render_data_context& rend_data_ctx, + int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w); - void draw_lens_flare(); + void draw_lens_flare(render_data_context& rend_data_ctx, const cam_data& cam); void free(); + vec2 get_taa_offset(); void init_render_buffers(int32_t width, int32_t height, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask); - void init_tone_map_buffers(); + void init_post_process_buffers(); int32_t movie_texture_set(texture* movie_texture); void movie_texture_free(texture* movie_texture); void post_proc(); - void pre_proc(); + void pre_proc(render_data_context& rend_data_ctx); int32_t render_texture_set(texture* render_texture, bool task_photo); void render_texture_free(texture* render_texture, bool task_photo); void resize(int32_t width, int32_t height); void set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height); - void take_ss(texture* tex, bool vertical, float_t horizontal_offset); - void transparency_combine(float_t alpha); - void transparency_copy(); + void take_ss(render_data_context& rend_data_ctx, + texture* tex, bool vertical, float_t horizontal_offset); + void transparency_combine(render_data_context& rend_data_ctx, float_t alpha); + void transparency_copy(render_data_context& rend_data_ctx); void update_res(bool set, int32_t base_downsample); private: - void apply_mlaa(int32_t destination, int32_t source, int32_t mlaa); - void apply_tone_map(texture* light_proj_tex, int32_t npr_param); - void calc_exposure(); - void calc_gaussian_blur(float_t start, float_t step, + void apply_mlaa(render_data_context& rend_data_ctx, + int32_t destination, int32_t source, int32_t mlaa); + void apply_tone_map(render_data_context& rend_data_ctx, texture* light_proj_tex, int32_t npr_param); + void calc_exposure(render_data_context& rend_data_ctx, const cam_data& cam); + void calc_gaussian_blur(render_data_context& rend_data_ctx, float_t start, float_t step, int32_t kernel_size, float_t radius_scale, float_t intensity_scale); void calc_taa_blend(); - void copy_to_frame_texture(GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex); - void draw_lens_ghost(); - void downsample(); + void copy_to_frame_texture(render_data_context& rend_data_ctx, + GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex); + void draw_lens_ghost(render_data_context& rend_data_ctx); + void downsample(render_data_context& rend_data_ctx); void generate_mlaa_area_texture(); - void get_blur(); - void update_tone_map_lut(); + void get_blur(render_data_context& rend_data_ctx); + void update_tone_map_lut(p_gl_rend_state& p_gl_rend_st); }; static_assert(sizeof(rndr::Render) == 0x1510, "\"rndr::Render\" struct should have a size of 0x1510"); diff --git a/src/DivaGL/render_context.cpp b/src/DivaGL/render_context.cpp index 5e545e0..3a7c5b2 100644 --- a/src/DivaGL/render_context.cpp +++ b/src/DivaGL/render_context.cpp @@ -5,6 +5,8 @@ #include "render_context.hpp" #include "../AFTModsShared/uniform.hpp" +#include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "render_manager.hpp" #include "shader_ft.hpp" #include "static_var.hpp" @@ -18,9 +20,9 @@ render_context* rctx; extern bool config_shared_storage_uniform_buffer; void draw_state_stats::reset() { - object_draw_count = 0; - object_translucent_draw_count = 0; - object_reflect_draw_count = 0; + sub_mesh_count = 0; + sub_mesh_no_mat_count = 0; + sub_mesh_cheap_count = 0; field_C = 0; field_10 = 0; draw_count = 0; @@ -47,9 +49,13 @@ void sss_data::init() { init_data = true; } -void sss_data::set_texture(int32_t texture_index) { - gl_rend_state.active_bind_texture_2d(16, textures[texture_index].GetColorTex()); - gl_rend_state.active_texture(0); +void sss_data::set_texture(struct p_gl_rend_state& p_gl_rend_st, int32_t texture_index) { + p_gl_rend_st.active_bind_texture_2d(16, textures[texture_index].GetColorTex()); + p_gl_rend_st.active_texture(0); +} + +draw_state_struct::render_data::render_data() : self_shadow(), shadow(), blend(), cull_front(), field_8() { + shader_index = -1; } void draw_state_struct::set_fog_height(bool value) { @@ -258,13 +264,13 @@ void render_data::obj_batch_data::reset() { } void render_data::init() { - buffer_shader.Create(sizeof(obj_shader_data)); - buffer_scene.Create(sizeof(obj_scene_data)); - buffer_batch.Create(sizeof(obj_batch_data)); + buffer_shader.Create(gl_state, sizeof(obj_shader_data)); + buffer_scene.Create(gl_state, sizeof(obj_scene_data)); + buffer_batch.Create(gl_state, sizeof(obj_batch_data)); if (DIVA_GL_VERSION_4_3) - buffer_skinning.Create(sizeof(obj_skinning_data)); + buffer_skinning.Create(gl_state, sizeof(obj_skinning_data)); else - buffer_skinning_ubo.Create(sizeof(obj_skinning_data)); + buffer_skinning_ubo.Create(gl_state, sizeof(obj_skinning_data)); buffer_shader_data.reset(); enum_or(flags, RENDER_DATA_SHADER_UPDATE); @@ -272,6 +278,7 @@ void render_data::init() { enum_or(flags, RENDER_DATA_SCENE_UPDATE); buffer_batch_data.reset(); enum_or(flags, RENDER_DATA_BATCH_UPDATE); + inv_view_mat = mat4_identity; } void render_data::free() { @@ -284,16 +291,61 @@ void render_data::free() { buffer_shader.Destroy(); } -void render_data::set(render_context* rctx) { - shaders_ft.set(shader_index); +void render_data::set_skinning_data(p_gl_rend_state& p_gl_rend_st, const mat4* mats, int32_t count) { + if (count == 2) { + mat4 temp; + mat4_transpose(&mats[0], &temp); + if (buffer_batch_data.g_joint[0] != temp.row0 + || buffer_batch_data.g_joint[1] != temp.row1 + || buffer_batch_data.g_joint[2] != temp.row2) { + buffer_batch_data.g_joint[0] = temp.row0; + buffer_batch_data.g_joint[1] = temp.row1; + buffer_batch_data.g_joint[2] = temp.row2; + enum_or(flags, RENDER_DATA_BATCH_UPDATE); + } + } + + if (config_shared_storage_uniform_buffer) { + GLuint buffer = 0; + size_t offset = 0; + size_t size = 0; + if (rctx->get_shared_storage_uniform_buffer_data( + (size_t)mats, buffer, offset, size, !!DIVA_GL_VERSION_4_3)) + if (DIVA_GL_VERSION_4_3) + p_gl_rend_st.bind_shader_storage_buffer_range(0, buffer, (GLintptr)offset, (GLsizeiptr)size); + else + p_gl_rend_st.bind_uniform_buffer_range(6, buffer, (GLintptr)offset, (GLsizeiptr)size); + } + else { + vec4* g_joint_transforms = buffer_skinning_data.g_joint_transforms; + + mat4 mat; + for (int32_t i = 0; i < count; i++, mats++, g_joint_transforms += 3) { + mat4_transpose(mats, &mat); + g_joint_transforms[0] = mat.row0; + g_joint_transforms[1] = mat.row1; + g_joint_transforms[2] = mat.row2; + } + + if (DIVA_GL_VERSION_4_3) + buffer_skinning.WriteMemory(p_gl_rend_st, + 0, sizeof(vec4) * 3 * count, &buffer_skinning_data); + else + buffer_skinning_ubo.WriteMemory(p_gl_rend_st, + 0, sizeof(vec4) * 3 * count, &buffer_skinning_data); + } +} + +void render_data::set_state(p_gl_rend_state& p_gl_rend_st) { + shaders_ft.set(p_gl_rend_st, shader_flags, shader_index); if (flags & RENDER_DATA_SHADER_UPDATE) { - buffer_shader.WriteMemory(buffer_shader_data); + buffer_shader.WriteMemory(p_gl_rend_st, buffer_shader_data); enum_and(flags, ~RENDER_DATA_SHADER_UPDATE); } if (flags & RENDER_DATA_SCENE_UPDATE) { - buffer_scene.WriteMemory(buffer_scene_data); + buffer_scene.WriteMemory(p_gl_rend_st, buffer_scene_data); enum_and(flags, ~RENDER_DATA_SCENE_UPDATE); } @@ -306,7 +358,7 @@ void render_data::set(render_context* rctx) { mat4_transpose(&worlds, &worlds); mat4 temp; - mat4_mul(&worlds, &rctx->vp_mat, &temp); + mat4_mul(&worlds, &cam.view_proj_mat, &temp); mat4_transpose(&temp, &temp); buffer_batch_data.g_transforms[0] = temp.row0; buffer_batch_data.g_transforms[1] = temp.row1; @@ -319,7 +371,7 @@ void render_data::set(render_context* rctx) { buffer_batch_data.g_worlds_invtrans[1] = temp.row1; buffer_batch_data.g_worlds_invtrans[2] = temp.row2; - mat4_mul(&worlds, &rctx->view_mat, &worlds); + mat4_mul(&worlds, &cam.view_mat, &worlds); mat4_transpose(&worlds, &temp); buffer_batch_data.g_worldview[0] = temp.row0; buffer_batch_data.g_worldview[1] = temp.row1; @@ -340,28 +392,343 @@ void render_data::set(render_context* rctx) { buffer_batch_data.g_joint_inverse[1] = temp.row1; buffer_batch_data.g_joint_inverse[2] = temp.row2; - buffer_batch.WriteMemory(buffer_batch_data); + buffer_batch.WriteMemory(p_gl_rend_st, buffer_batch_data); enum_and(flags, ~RENDER_DATA_BATCH_UPDATE); } - buffer_shader.Bind(0); - buffer_scene.Bind(1); - buffer_batch.Bind(2); + p_gl_rend_st.bind_uniform_buffer_base(0, buffer_shader); + p_gl_rend_st.bind_uniform_buffer_base(1, buffer_scene); + p_gl_rend_st.bind_uniform_buffer_base(2, buffer_batch); - if (uniform->arr[U_SKINNING] && !config_shared_storage_uniform_buffer) + if (shader_flags.arr[U_SKINNING] && !config_shared_storage_uniform_buffer) if (DIVA_GL_VERSION_4_3) - buffer_skinning.Bind(0); + p_gl_rend_st.bind_shader_storage_buffer_base(0, buffer_skinning); else - buffer_skinning_ubo.Bind(6); + p_gl_rend_st.bind_uniform_buffer_base(6, buffer_skinning_ubo); } void render_data::set_shader(uint32_t index) { shader_index = index; - buffer_shader_data.set_shader_flags(uniform->arr); + buffer_shader_data.set_shader_flags(shader_flags.arr); enum_or(flags, RENDER_DATA_SHADER_UPDATE); } +render_data_context::render_data_context(gl_rend_state_index index) : state(index), index(index), +data(rctx->data[index]), shader_flags(rctx->data[index].shader_flags) { + +} + +void render_data_context::get_scene_fog_params(render_data_context::fog_params& value) { + value.depth_color = data.buffer_scene_data.g_fog_depth_color; + value.height_params = data.buffer_scene_data.g_fog_height_params; + value.height_color = data.buffer_scene_data.g_fog_height_color; + value.bump_params = data.buffer_scene_data.g_fog_bump_params; + value.density = data.buffer_scene_data.g_fog_state_params.x; + value.start = data.buffer_scene_data.g_fog_state_params.y; + value.end = data.buffer_scene_data.g_fog_state_params.z; +} + +void render_data_context::get_scene_light(vec4* light_env_stage_diffuse, + vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, + vec4* light_env_chara_diffuse, vec4* light_env_chara_specular) { + if (light_env_stage_diffuse) + *light_env_stage_diffuse = data.buffer_scene_data.g_light_env_stage_diffuse; + if (light_env_stage_specular) + *light_env_stage_specular = data.buffer_scene_data.g_light_env_stage_specular; + if (light_chara_dir) + *light_chara_dir = data.buffer_scene_data.g_light_chara_dir; + if (light_chara_luce) + *light_chara_luce = data.buffer_scene_data.g_light_chara_luce; + if (light_env_chara_diffuse) + *light_env_chara_diffuse = data.buffer_scene_data.g_light_env_chara_diffuse; + if (light_env_chara_specular) + *light_env_chara_specular = data.buffer_scene_data.g_light_env_chara_specular; +} + +void render_data_context::reset_shader_flags() { + shader_flags.arr[U_TEXTURE_COUNT] = 0; + shader_flags.arr[U_TEXTURE_BLEND] = 0; + shader_flags.arr[U_NORMAL] = 0; + shader_flags.arr[U_SPECULAR] = 0; + shader_flags.arr[U_TRANSPARENCY] = 0; + shader_flags.arr[U_TRANSLUCENCY] = 0; + shader_flags.arr[U_ENV_MAP] = 0; + shader_flags.arr[U0B] = 0; + shader_flags.arr[U_SPECULAR_IBL] = 0; + shader_flags.arr[U_FOG_STAGE] = 0; + shader_flags.arr[U_FOG_CHARA] = 0; + shader_flags.arr[U_ANISO] = 0; + shader_flags.arr[U_STAGE_SHADOW] = 0; + shader_flags.arr[U45] = 0; + shader_flags.arr[U_TEX_0_TYPE] = 0; + shader_flags.arr[U_TEX_1_TYPE] = 0; +} + +void render_data_context::set_batch_alpha_threshold(const float_t value) { + data.buffer_batch_data.g_max_alpha.z = value; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_blend_color_offset_color( + const vec4& blend_color, const vec4& offset_color) { + data.buffer_batch_data.g_blend_color = blend_color; + data.buffer_batch_data.g_offset_color = offset_color; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_material_color(const vec4& diffuse, const vec4& ambient, + const vec4& emission, const float_t material_shininess, const vec4& specular, + const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, + const vec4& texture_color_offset, const vec4& texture_specular_coefficients, + const vec4& texture_specular_offset, const float_t shininess) { + data.buffer_batch_data.g_material_state_diffuse = diffuse; + data.buffer_batch_data.g_material_state_ambient = ambient; + data.buffer_batch_data.g_material_state_emission = emission; + data.buffer_batch_data.g_material_state_shininess = { material_shininess, 0.0f, 0.0f, 1.0f }; + data.buffer_batch_data.g_material_state_specular = specular; + data.buffer_batch_data.g_fresnel_coefficients = fresnel_coefficients; + data.buffer_batch_data.g_texture_color_coefficients = texture_color_coefficients; + data.buffer_batch_data.g_texture_color_offset = texture_color_offset; + data.buffer_batch_data.g_texture_specular_coefficients = texture_specular_coefficients; + data.buffer_batch_data.g_shininess.x = shininess; + data.buffer_batch_data.g_texture_specular_offset = texture_specular_offset; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_material_color_emission(const vec4& emission) { + data.buffer_batch_data.g_material_state_emission = emission; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, + const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale) { + if (specular) + data.buffer_batch_data.g_material_state_specular = *specular; + data.buffer_batch_data.g_bump_depth = bump_depth; + data.buffer_batch_data.g_intensity = intensity; + data.buffer_batch_data.g_reflect_uv_scale.x = reflect_uv_scale; + data.buffer_batch_data.g_reflect_uv_scale.y = reflect_uv_scale; + data.buffer_batch_data.g_reflect_uv_scale.z = refract_uv_scale; + data.buffer_batch_data.g_reflect_uv_scale.w = refract_uv_scale; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_min_alpha(const float_t value) { + data.buffer_batch_data.g_max_alpha.w = value; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_morph_weight(const float_t value) { + data.buffer_batch_data.g_morph_weight.x = value; + data.buffer_batch_data.g_morph_weight.y = 1.0f - value; + data.buffer_batch_data.g_morph_weight.z = 0.0f; + data.buffer_batch_data.g_morph_weight.w = 0.0f; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_scene_camera(const cam_data& cam) { + data.cam = cam; + + mat4_invert(&data.cam.get_view_mat(), &data.inv_view_mat); + + mat4 temp; + mat4_transpose(&data.cam.get_view_mat(), &temp); + data.buffer_scene_data.g_view[0] = temp.row0; + data.buffer_scene_data.g_view[1] = temp.row1; + data.buffer_scene_data.g_view[2] = temp.row2; + + mat4_invert(&data.cam.get_view_mat(), &temp); + mat4_transpose(&temp, &temp); + data.buffer_scene_data.g_view_inverse[0] = temp.row0; + data.buffer_scene_data.g_view_inverse[1] = temp.row1; + data.buffer_scene_data.g_view_inverse[2] = temp.row2; + + mat4_transpose(&data.cam.get_view_proj_mat(), &temp); + data.buffer_scene_data.g_projection_view[0] = temp.row0; + data.buffer_scene_data.g_projection_view[1] = temp.row1; + data.buffer_scene_data.g_projection_view[2] = temp.row2; + data.buffer_scene_data.g_projection_view[3] = temp.row3; + + *(vec3*)&data.buffer_scene_data.g_view_position = cam.get_view_point(); + data.buffer_scene_data.g_view_position.w = 0.0f; + //enum_or(data.flags, RENDER_DATA_BATCH_UPDATE | RENDER_DATA_SCENE_UPDATE); + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_data_context::set_batch_sss_param(const vec4& sss_param) { + data.buffer_batch_data.g_sss_param = sss_param; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_texcoord_transforms(const mat4 mats[2]) { + mat4 temp; + mat4_transpose(&mats[0], &temp); + data.buffer_batch_data.g_texcoord_transforms[0] = temp.row0; + data.buffer_batch_data.g_texcoord_transforms[1] = temp.row1; + mat4_transpose(&mats[1], &temp); + data.buffer_batch_data.g_texcoord_transforms[2] = temp.row0; + data.buffer_batch_data.g_texcoord_transforms[3] = temp.row1; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_data_context::set_batch_worlds(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + if (data.buffer_batch_data.g_worlds[0] != temp.row0 + || data.buffer_batch_data.g_worlds[1] != temp.row1 + || data.buffer_batch_data.g_worlds[2] != temp.row2) { + data.buffer_batch_data.g_worlds[0] = temp.row0; + data.buffer_batch_data.g_worlds[1] = temp.row1; + data.buffer_batch_data.g_worlds[2] = temp.row2; + enum_or(data.flags, RENDER_DATA_BATCH_UPDATE); + } +} + +void render_data_context::set_glitter_render_data_state() { + data.buffer_shader_data.set_shader_flags(data.shader_flags.arr); + data.buffer_shader.WriteMemory(state, data.buffer_shader_data); + state.bind_uniform_buffer_base(0, data.buffer_shader); + + if (data.flags & RENDER_DATA_SCENE_UPDATE) { + data.buffer_scene.WriteMemory(state, data.buffer_scene_data); + enum_and(data.flags, ~RENDER_DATA_SCENE_UPDATE); + } + state.bind_uniform_buffer_base(1, data.buffer_scene); +} + +void render_data_context::set_render_data_state() { + data.set_state(state); +} + +void render_data_context::set_scene_fog_params(const render_data_context::fog_params& value) { + data.buffer_scene_data.g_fog_depth_color = value.depth_color; + data.buffer_scene_data.g_fog_height_params = value.height_params; + data.buffer_scene_data.g_fog_height_color = value.height_color; + data.buffer_scene_data.g_fog_bump_params = value.bump_params; + const float_t start = value.start; + const float_t end = value.end; + data.buffer_scene_data.g_fog_state_params.x = value.density; + data.buffer_scene_data.g_fog_state_params.y = value.start; + data.buffer_scene_data.g_fog_state_params.z = value.end; + data.buffer_scene_data.g_fog_state_params.w = end - start > 0.0f ? 1.0f / (end - start) : 0.0f; + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_data_context::set_scene_framebuffer_size(const int32_t width, const int32_t height, + const int32_t render_width, const int32_t render_height) { + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); + data.buffer_scene_data.g_framebuffer_size.x = 1.0f / (float_t)width; + data.buffer_scene_data.g_framebuffer_size.y = 1.0f / (float_t)height; + data.buffer_scene_data.g_framebuffer_size.w = 1.0f / (float_t)render_height; + data.buffer_scene_data.g_framebuffer_size.z = 1.0f / (float_t)render_width; +} + +void render_data_context::set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, + const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, + const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, + const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, + const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, + const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, + const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, + const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, + const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, + const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, + const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, + const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color) { + mat4 temp; + mat4_transpose(&irradiance_r_transforms, &temp); + data.buffer_scene_data.g_irradiance_r_transforms[0] = temp.row0; + data.buffer_scene_data.g_irradiance_r_transforms[1] = temp.row1; + data.buffer_scene_data.g_irradiance_r_transforms[2] = temp.row2; + data.buffer_scene_data.g_irradiance_r_transforms[3] = temp.row3; + mat4_transpose(&irradiance_g_transforms, &temp); + data.buffer_scene_data.g_irradiance_g_transforms[0] = temp.row0; + data.buffer_scene_data.g_irradiance_g_transforms[1] = temp.row1; + data.buffer_scene_data.g_irradiance_g_transforms[2] = temp.row2; + data.buffer_scene_data.g_irradiance_g_transforms[3] = temp.row3; + mat4_transpose(&irradiance_b_transforms, &temp); + data.buffer_scene_data.g_irradiance_b_transforms[0] = temp.row0; + data.buffer_scene_data.g_irradiance_b_transforms[1] = temp.row1; + data.buffer_scene_data.g_irradiance_b_transforms[2] = temp.row2; + data.buffer_scene_data.g_irradiance_b_transforms[3] = temp.row3; + data.buffer_scene_data.g_light_env_stage_diffuse = light_env_stage_diffuse; + data.buffer_scene_data.g_light_env_stage_specular = light_env_stage_specular; + data.buffer_scene_data.g_light_env_chara_diffuse = light_env_chara_diffuse; + data.buffer_scene_data.g_light_env_chara_ambient = light_env_chara_ambient; + data.buffer_scene_data.g_light_env_chara_specular = light_env_chara_specular; + data.buffer_scene_data.g_light_env_reflect_diffuse = light_env_reflect_diffuse; + data.buffer_scene_data.g_light_env_reflect_ambient = light_env_reflect_ambient; + data.buffer_scene_data.g_light_env_proj_diffuse = light_env_proj_diffuse; + data.buffer_scene_data.g_light_env_proj_specular = light_env_proj_specular; + data.buffer_scene_data.g_light_env_proj_position = light_env_proj_position; + data.buffer_scene_data.g_light_stage_dir = light_stage_dir; + data.buffer_scene_data.g_light_stage_diff = light_stage_diff; + data.buffer_scene_data.g_light_stage_spec = light_stage_spec; + data.buffer_scene_data.g_light_chara_dir = light_chara_dir; + data.buffer_scene_data.g_light_chara_spec = light_chara_spec; + data.buffer_scene_data.g_light_chara_luce = light_chara_luce; + data.buffer_scene_data.g_light_chara_back = light_chara_back; + data.buffer_scene_data.g_light_face_diff = light_face_diff; + data.buffer_scene_data.g_chara_color0 = chara_color0; + data.buffer_scene_data.g_chara_color1 = chara_color1; + data.buffer_scene_data.g_chara_f_dir = chara_f_dir; + data.buffer_scene_data.g_chara_f_ambient = chara_f_ambient; + data.buffer_scene_data.g_chara_f_diffuse = chara_f_diffuse; + data.buffer_scene_data.g_chara_tc_param = chara_tc_param; + mat4_transpose(&normal_tangent_transforms, &temp); + data.buffer_scene_data.g_normal_tangent_transforms[0] = temp.row0; + data.buffer_scene_data.g_normal_tangent_transforms[1] = temp.row1; + data.buffer_scene_data.g_normal_tangent_transforms[2] = temp.row2; + data.buffer_scene_data.g_light_reflect_dir = light_reflect_dir; + data.buffer_scene_data.g_clip_plane = clip_plane; + data.buffer_scene_data.g_npr_cloth_spec_color = npr_cloth_spec_color; + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_data_context::set_scene_light_projection(const mat4& light_projection) { + mat4 temp; + mat4_transpose(&light_projection, &temp); + data.buffer_scene_data.g_light_projection[0] = temp.row0; + data.buffer_scene_data.g_light_projection[1] = temp.row1; + data.buffer_scene_data.g_light_projection[2] = temp.row2; + data.buffer_scene_data.g_light_projection[3] = temp.row3; + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_data_context::set_scene_shadow_params(const float_t esm_param, + const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1) { + data.buffer_scene_data.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f }; + mat4 temp; + mat4_transpose(&mats[0], &temp); + data.buffer_scene_data.g_self_shadow_receivers[0] = temp.row0; + data.buffer_scene_data.g_self_shadow_receivers[1] = temp.row1; + data.buffer_scene_data.g_self_shadow_receivers[2] = temp.row2; + mat4_transpose(&mats[1], &temp); + data.buffer_scene_data.g_self_shadow_receivers[3] = temp.row0; + data.buffer_scene_data.g_self_shadow_receivers[4] = temp.row1; + data.buffer_scene_data.g_self_shadow_receivers[5] = temp.row2; + data.buffer_scene_data.g_shadow_ambient = shadow_ambient; + data.buffer_scene_data.g_shadow_ambient1 = shadow_ambient1; + enum_or(data.flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_data_context::set_self_shadow(bool value) { + rctx->draw_state_rend_data[index].self_shadow = value; +} + +void render_data_context::set_shader(uint32_t index) { + data.set_shader(index); +} + +void render_data_context::set_shadow(bool value) { + rctx->draw_state_rend_data[index].shadow = value; +} + +void render_data_context::set_skinning_data(p_gl_rend_state& p_gl_rend_st, const mat4* mats, int32_t count) { + data.set_skinning_data(p_gl_rend_st, mats, count); +} + bool render_context::shared_storage_buffer::can_fill_data(size_t size) { return (size + align_val(offset, sv_min_storage_buffer_alignment)) <= this->size; } @@ -372,7 +739,7 @@ void render_context::shared_storage_buffer::create(size_t size) { size = size / sv_min_storage_buffer_alignment * sv_min_storage_buffer_alignment; - buffer.Create(size); + buffer.Create(gl_state, size); data = _operator_new(size); memset(data, 0, size); offset = 0; @@ -407,7 +774,7 @@ void render_context::shared_uniform_buffer::create(size_t size) { size = size / sv_min_uniform_buffer_alignment * sv_min_uniform_buffer_alignment; - buffer.Create(size); + buffer.Create(gl_state, size); data = _operator_new(size); memset(data, 0, size); offset = 0; @@ -435,6 +802,8 @@ size_t render_context::shared_uniform_buffer::fill_data(const void* data, size_t render_context::render_context() : box_vao(), lens_ghost_vao(), common_vao(), reflect_buffer(), render_buffer(), screen_buffer(), shadow_buffer(), empty_texture_2d(), empty_texture_cube_map(), samplers(), render_samplers(), sprite_samplers(), screen_width(), screen_height() { + gl_state.get(); + static const float_t box_texcoords[] = { 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, @@ -471,10 +840,10 @@ samplers(), render_samplers(), sprite_samplers(), screen_width(), screen_height( }; glGenVertexArrays(1, &box_vao); - gl_rend_state.bind_vertex_array(box_vao); + gl_state.bind_vertex_array(box_vao); - box_vbo.Create(sizeof(box_texcoords), box_texcoords); - box_vbo.Bind(); + box_vbo.Create(gl_state, sizeof(box_texcoords), box_texcoords); + gl_state.bind_array_buffer(box_vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)0); @@ -486,39 +855,41 @@ samplers(), render_samplers(), sprite_samplers(), screen_width(), screen_height( glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 12)); glGenVertexArrays(1, &lens_ghost_vao); - gl_rend_state.bind_vertex_array(lens_ghost_vao); + gl_state.bind_vertex_array(lens_ghost_vao); - lens_ghost_vbo.Create(sizeof(float_t) * 5 * (6 * 16)); - lens_ghost_vbo.Bind(); + lens_ghost_vbo.Create(gl_state, sizeof(float_t) * 5 * (6 * 16)); + gl_state.bind_array_buffer(lens_ghost_vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)(sizeof(float_t) * 2)); - gl_rend_state.bind_array_buffer(0); - gl_rend_state.bind_vertex_array(0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); glGenVertexArrays(1, &common_vao); - camera_blur_ubo.Create(sizeof(camera_blur_shader_data)); - contour_coef_ubo.Create(sizeof(contour_coef_shader_data)); - contour_params_ubo.Create(sizeof(contour_params_shader_data)); - filter_scene_ubo.Create(sizeof(filter_scene_shader_data)); - esm_filter_batch_ubo.Create(sizeof(esm_filter_batch_shader_data)); - imgfilter_batch_ubo.Create(sizeof(imgfilter_batch_shader_data)); - exposure_measure_ubo.Create(sizeof(exposure_measure_shader_data)); - gaussian_coef_ubo.Create(sizeof(gaussian_coef_shader_data)); - glass_eye_batch_ubo.Create(sizeof(glass_eye_batch_shader_data)); - glitter_batch_ubo.Create(sizeof(glitter_batch_shader_data)); - quad_ubo.Create(sizeof(quad_shader_data)); - sprite_scene_ubo.Create(sizeof(sprite_scene_shader_data)); - sss_filter_gaussian_coef_ubo.Create(sizeof(sss_filter_gaussian_coef_shader_data)); - sun_quad_ubo.Create(sizeof(sun_quad_shader_data)); - tone_map_ubo.Create(sizeof(tone_map_shader_data)); - transparency_batch_ubo.Create(sizeof(transparency_batch_shader_data)); + camera_blur_ubo.Create(gl_state, sizeof(camera_blur_shader_data)); + contour_coef_ubo.Create(gl_state, sizeof(contour_coef_shader_data)); + contour_params_ubo.Create(gl_state, sizeof(contour_params_shader_data)); + filter_scene_ubo.Create(gl_state, sizeof(filter_scene_shader_data)); + esm_filter_batch_ubo.Create(gl_state, sizeof(esm_filter_batch_shader_data)); + imgfilter_batch_ubo.Create(gl_state, sizeof(imgfilter_batch_shader_data)); + exposure_measure_ubo.Create(gl_state, sizeof(exposure_measure_shader_data)); + gaussian_coef_ubo.Create(gl_state, sizeof(gaussian_coef_shader_data)); + glass_eye_batch_ubo.Create(gl_state, sizeof(glass_eye_batch_shader_data)); + glitter_batch_ubo.Create(gl_state, sizeof(glitter_batch_shader_data)); + quad_ubo.Create(gl_state, sizeof(quad_shader_data)); + sprite_scene_ubo.Create(gl_state, sizeof(sprite_scene_shader_data)); + sss_filter_gaussian_coef_ubo.Create(gl_state, sizeof(sss_filter_gaussian_coef_shader_data)); + sun_quad_ubo.Create(gl_state, sizeof(sun_quad_shader_data)); + tone_map_ubo.Create(gl_state, sizeof(tone_map_shader_data)); + transparency_batch_ubo.Create(gl_state, sizeof(transparency_batch_shader_data)); - data = {}; - data.init(); + for (render_data& i : data) { + i = {}; + i.init(); + } static const vec4 border_color = 0.0f; @@ -639,7 +1010,8 @@ render_context::~render_context() { glDeleteSamplers(4, render_samplers); glDeleteSamplers(18, samplers); - data.free(); + for (render_data& i : data) + i.free(); transparency_batch_ubo.Destroy(); tone_map_ubo.Destroy(); @@ -711,7 +1083,7 @@ void render_context::ctrl(bool change_res) { /*if (render_res_change) render.resize(render_width, render_height);*/ - + if (!change_res || /*!render_res_change && */!screen_res_change) return; @@ -837,35 +1209,6 @@ void render_context::add_shared_storage_uniform_buffer_data(size_t index, } } -void render_context::get_scene_fog_params(render_context::fog_params& value) { - render_data* data = &this->data; - value.depth_color = data->buffer_scene_data.g_fog_depth_color; - value.height_params = data->buffer_scene_data.g_fog_height_params; - value.height_color = data->buffer_scene_data.g_fog_height_color; - value.bump_params = data->buffer_scene_data.g_fog_bump_params; - value.density = data->buffer_scene_data.g_fog_state_params.x; - value.start = data->buffer_scene_data.g_fog_state_params.y; - value.end = data->buffer_scene_data.g_fog_state_params.z; -} - -void render_context::get_scene_light(vec4* light_env_stage_diffuse, - vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, - vec4* light_env_chara_diffuse, vec4* light_env_chara_specular) { - render_data* data = &this->data; - if (light_env_stage_diffuse) - *light_env_stage_diffuse = data->buffer_scene_data.g_light_env_stage_diffuse; - if (light_env_stage_specular) - *light_env_stage_specular = data->buffer_scene_data.g_light_env_stage_specular; - if (light_chara_dir) - *light_chara_dir = data->buffer_scene_data.g_light_chara_dir; - if (light_chara_luce) - *light_chara_luce = data->buffer_scene_data.g_light_chara_luce; - if (light_env_chara_diffuse) - *light_env_chara_diffuse = data->buffer_scene_data.g_light_env_chara_diffuse; - if (light_env_chara_specular) - *light_env_chara_specular = data->buffer_scene_data.g_light_env_chara_specular; -} - bool render_context::get_shared_storage_uniform_buffer_data(size_t index, GLuint& buffer, size_t& offset, size_t& size, bool storage) { if (storage) { @@ -909,20 +1252,21 @@ void render_context::pre_proc() { const int32_t mat_count = min_def(args->mat_count, 256); const mat4* mats = args->mats; - vec4* g_joint_transforms = rctx->data.buffer_skinning_data.g_joint_transforms; + vec4 g_joint_transforms[768]; + vec4* g_joint_transform = g_joint_transforms; mat4 mat; - for (int32_t i = 0; i < mat_count; i++, mats++, g_joint_transforms += 3) { + for (int32_t i = 0; i < mat_count; i++, mats++, g_joint_transform += 3) { mat4_transpose(mats, &mat); - g_joint_transforms[0] = mat.row0; - g_joint_transforms[1] = mat.row1; - g_joint_transforms[2] = mat.row2; + g_joint_transform[0] = mat.row0; + g_joint_transform[1] = mat.row1; + g_joint_transform[2] = mat.row2; } const size_t buffer_size = sizeof(vec4) * 3 * 256; const size_t size = sizeof(vec4) * 3 * mat_count; rctx->add_shared_storage_uniform_buffer_data((size_t)args->mats, - rctx->data.buffer_skinning_data.g_joint_transforms, size, buffer_size, !!DIVA_GL_VERSION_4_3); + g_joint_transforms, size, buffer_size, !!DIVA_GL_VERSION_4_3); }; for (int32_t type = 0; type < mdl::OBJ_TYPE_MAX; type++) @@ -970,7 +1314,7 @@ void render_context::pre_proc() { const size_t align = size - i.offset; if (align) memset((void*)((size_t)i.data + i.offset), 0, align); - i.buffer.WriteMemory(0, size, i.data); + i.buffer.WriteMemory(gl_state, 0, size, i.data); } for (render_context::shared_uniform_buffer& i : shared_uniform_buffers) { @@ -981,7 +1325,7 @@ void render_context::pre_proc() { const size_t align = size - i.offset; if (align) memset((void*)((size_t)i.data + i.offset), 0, align); - i.buffer.WriteMemory(0, size, i.data); + i.buffer.WriteMemory(gl_state, 0, size, i.data); } } } @@ -1002,298 +1346,6 @@ void render_context::post_proc() { } } -void render_context::set_batch_alpha_threshold(const float_t value) { - render_data* data = &this->data; - data->buffer_batch_data.g_max_alpha.z = value; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_blend_color(const vec4& blend_color) { - render_data* data = &this->data; - data->buffer_batch_data.g_blend_color = blend_color; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_blend_color_offset_color( - const vec4& blend_color, const vec4& offset_color) { - render_data* data = &this->data; - data->buffer_batch_data.g_blend_color = blend_color; - data->buffer_batch_data.g_offset_color = offset_color; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_joint(const mat4& mat) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&mat, &temp); - if (data->buffer_batch_data.g_joint[0] != temp.row0 - || data->buffer_batch_data.g_joint[1] != temp.row1 - || data->buffer_batch_data.g_joint[2] != temp.row2) { - data->buffer_batch_data.g_joint[0] = temp.row0; - data->buffer_batch_data.g_joint[1] = temp.row1; - data->buffer_batch_data.g_joint[2] = temp.row2; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); - } -} - -void render_context::set_batch_material_color(const vec4& diffuse, const vec4& ambient, - const vec4& emission, const float_t material_shininess, const vec4& specular, - const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, - const vec4& texture_color_offset, const vec4& texture_specular_coefficients, - const vec4& texture_specular_offset, const float_t shininess) { - render_data* data = &this->data; - data->buffer_batch_data.g_material_state_diffuse = diffuse; - data->buffer_batch_data.g_material_state_ambient = ambient; - data->buffer_batch_data.g_material_state_emission = emission; - data->buffer_batch_data.g_material_state_shininess = { material_shininess, 0.0f, 0.0f, 1.0f }; - data->buffer_batch_data.g_material_state_specular = specular; - data->buffer_batch_data.g_fresnel_coefficients = fresnel_coefficients; - data->buffer_batch_data.g_texture_color_coefficients = texture_color_coefficients; - data->buffer_batch_data.g_texture_color_offset = texture_color_offset; - data->buffer_batch_data.g_texture_specular_coefficients = texture_specular_coefficients; - data->buffer_batch_data.g_shininess.x = shininess; - data->buffer_batch_data.g_texture_specular_offset = texture_specular_offset; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_material_color_emission(const vec4& emission) { - render_data* data = &this->data; - data->buffer_batch_data.g_material_state_emission = emission; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, - const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale) { - render_data* data = &this->data; - if (specular) - data->buffer_batch_data.g_material_state_specular = *specular; - data->buffer_batch_data.g_bump_depth = bump_depth; - data->buffer_batch_data.g_intensity = intensity; - data->buffer_batch_data.g_reflect_uv_scale.x = reflect_uv_scale; - data->buffer_batch_data.g_reflect_uv_scale.y = reflect_uv_scale; - data->buffer_batch_data.g_reflect_uv_scale.z = refract_uv_scale; - data->buffer_batch_data.g_reflect_uv_scale.w = refract_uv_scale; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_min_alpha(const float_t value) { - render_data* data = &this->data; - data->buffer_batch_data.g_max_alpha.w = value; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_morph_weight(const float_t value) { - render_data* data = &this->data; - data->buffer_batch_data.g_morph_weight.x = value; - data->buffer_batch_data.g_morph_weight.y = 1.0f - value; - data->buffer_batch_data.g_morph_weight.z = 0.0f; - data->buffer_batch_data.g_morph_weight.w = 0.0f; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_offset_color(const vec4& offset_color) { - render_data* data = &this->data; - data->buffer_batch_data.g_offset_color = offset_color; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_sss_param(const vec4& sss_param) { - render_data* data = &this->data; - data->buffer_batch_data.g_sss_param = sss_param; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_texcoord_transforms(const mat4 mats[2]) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&mats[0], &temp); - data->buffer_batch_data.g_texcoord_transforms[0] = temp.row0; - data->buffer_batch_data.g_texcoord_transforms[1] = temp.row1; - mat4_transpose(&mats[1], &temp); - data->buffer_batch_data.g_texcoord_transforms[2] = temp.row0; - data->buffer_batch_data.g_texcoord_transforms[3] = temp.row1; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); -} - -void render_context::set_batch_worlds(const mat4& mat) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&mat, &temp); - if (data->buffer_batch_data.g_worlds[0] != temp.row0 - || data->buffer_batch_data.g_worlds[1] != temp.row1 - || data->buffer_batch_data.g_worlds[2] != temp.row2) { - data->buffer_batch_data.g_worlds[0] = temp.row0; - data->buffer_batch_data.g_worlds[1] = temp.row1; - data->buffer_batch_data.g_worlds[2] = temp.row2; - enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); - } -} - -void render_context::set_glitter_render_data() { - render_data* data = &this->data; - data->buffer_shader_data.set_shader_flags(uniform->arr); - data->buffer_shader.WriteMemory(data->buffer_shader_data); - data->buffer_shader.Bind(0); - - if (data->flags & RENDER_DATA_SCENE_UPDATE) { - data->buffer_scene.WriteMemory(data->buffer_scene_data); - enum_and(data->flags, ~RENDER_DATA_SCENE_UPDATE); - } - data->buffer_scene.Bind(1); -} - -void render_context::set_render_data() { - data.set(this); -} - -void render_context::set_scene_fog_params(const render_context::fog_params& value) { - render_data* data = &this->data; - data->buffer_scene_data.g_fog_depth_color = value.depth_color; - data->buffer_scene_data.g_fog_height_params = value.height_params; - data->buffer_scene_data.g_fog_height_color = value.height_color; - data->buffer_scene_data.g_fog_bump_params = value.bump_params; - const float_t start = value.start; - const float_t end = value.end; - data->buffer_scene_data.g_fog_state_params.x = value.density; - data->buffer_scene_data.g_fog_state_params.y = value.start; - data->buffer_scene_data.g_fog_state_params.z = value.end; - data->buffer_scene_data.g_fog_state_params.w = end - start > 0.0f ? 1.0f / (end - start) : 0.0f; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); -} - -void render_context::set_scene_framebuffer_size(const int32_t width, const int32_t height, - const int32_t render_width, const int32_t render_height) { - render_data* data = &this->data; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); - data->buffer_scene_data.g_framebuffer_size.x = 1.0f / (float_t)width; - data->buffer_scene_data.g_framebuffer_size.y = 1.0f / (float_t)height; - data->buffer_scene_data.g_framebuffer_size.w = 1.0f / (float_t)render_height; - data->buffer_scene_data.g_framebuffer_size.z = 1.0f / (float_t)render_width; -} - -void render_context::set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, - const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, - const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, - const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, - const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, - const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, - const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, - const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, - const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, - const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, - const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, - const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&irradiance_r_transforms, &temp); - data->buffer_scene_data.g_irradiance_r_transforms[0] = temp.row0; - data->buffer_scene_data.g_irradiance_r_transforms[1] = temp.row1; - data->buffer_scene_data.g_irradiance_r_transforms[2] = temp.row2; - data->buffer_scene_data.g_irradiance_r_transforms[3] = temp.row3; - mat4_transpose(&irradiance_g_transforms, &temp); - data->buffer_scene_data.g_irradiance_g_transforms[0] = temp.row0; - data->buffer_scene_data.g_irradiance_g_transforms[1] = temp.row1; - data->buffer_scene_data.g_irradiance_g_transforms[2] = temp.row2; - data->buffer_scene_data.g_irradiance_g_transforms[3] = temp.row3; - mat4_transpose(&irradiance_b_transforms, &temp); - data->buffer_scene_data.g_irradiance_b_transforms[0] = temp.row0; - data->buffer_scene_data.g_irradiance_b_transforms[1] = temp.row1; - data->buffer_scene_data.g_irradiance_b_transforms[2] = temp.row2; - data->buffer_scene_data.g_irradiance_b_transforms[3] = temp.row3; - data->buffer_scene_data.g_light_env_stage_diffuse = light_env_stage_diffuse; - data->buffer_scene_data.g_light_env_stage_specular = light_env_stage_specular; - data->buffer_scene_data.g_light_env_chara_diffuse = light_env_chara_diffuse; - data->buffer_scene_data.g_light_env_chara_ambient = light_env_chara_ambient; - data->buffer_scene_data.g_light_env_chara_specular = light_env_chara_specular; - data->buffer_scene_data.g_light_env_reflect_diffuse = light_env_reflect_diffuse; - data->buffer_scene_data.g_light_env_reflect_ambient = light_env_reflect_ambient; - data->buffer_scene_data.g_light_env_proj_diffuse = light_env_proj_diffuse; - data->buffer_scene_data.g_light_env_proj_specular = light_env_proj_specular; - data->buffer_scene_data.g_light_env_proj_position = light_env_proj_position; - data->buffer_scene_data.g_light_stage_dir = light_stage_dir; - data->buffer_scene_data.g_light_stage_diff = light_stage_diff; - data->buffer_scene_data.g_light_stage_spec = light_stage_spec; - data->buffer_scene_data.g_light_chara_dir = light_chara_dir; - data->buffer_scene_data.g_light_chara_spec = light_chara_spec; - data->buffer_scene_data.g_light_chara_luce = light_chara_luce; - data->buffer_scene_data.g_light_chara_back = light_chara_back; - data->buffer_scene_data.g_light_face_diff = light_face_diff; - data->buffer_scene_data.g_chara_color0 = chara_color0; - data->buffer_scene_data.g_chara_color1 = chara_color1; - data->buffer_scene_data.g_chara_f_dir = chara_f_dir; - data->buffer_scene_data.g_chara_f_ambient = chara_f_ambient; - data->buffer_scene_data.g_chara_f_diffuse = chara_f_diffuse; - data->buffer_scene_data.g_chara_tc_param = chara_tc_param; - mat4_transpose(&normal_tangent_transforms, &temp); - data->buffer_scene_data.g_normal_tangent_transforms[0] = temp.row0; - data->buffer_scene_data.g_normal_tangent_transforms[1] = temp.row1; - data->buffer_scene_data.g_normal_tangent_transforms[2] = temp.row2; - data->buffer_scene_data.g_light_reflect_dir = light_reflect_dir; - data->buffer_scene_data.g_clip_plane = clip_plane; - data->buffer_scene_data.g_npr_cloth_spec_color = npr_cloth_spec_color; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); -} - -void render_context::set_scene_light_projection(const mat4& light_projection) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&light_projection, &temp); - data->buffer_scene_data.g_light_projection[0] = temp.row0; - data->buffer_scene_data.g_light_projection[1] = temp.row1; - data->buffer_scene_data.g_light_projection[2] = temp.row2; - data->buffer_scene_data.g_light_projection[3] = temp.row3; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); -} - -void render_context::set_scene_projection_view(const mat4& view, const mat4& proj, const vec3& view_position) { - render_data* data = &this->data; - mat4 temp; - mat4_transpose(&view, &temp); - data->buffer_scene_data.g_view[0] = temp.row0; - data->buffer_scene_data.g_view[1] = temp.row1; - data->buffer_scene_data.g_view[2] = temp.row2; - - mat4_invert(&view, &temp); - mat4_transpose(&temp, &temp); - data->buffer_scene_data.g_view_inverse[0] = temp.row0; - data->buffer_scene_data.g_view_inverse[1] = temp.row1; - data->buffer_scene_data.g_view_inverse[2] = temp.row2; - - mat4_mul(&view, &proj, &temp); - mat4_transpose(&temp, &temp); - data->buffer_scene_data.g_projection_view[0] = temp.row0; - data->buffer_scene_data.g_projection_view[1] = temp.row1; - data->buffer_scene_data.g_projection_view[2] = temp.row2; - data->buffer_scene_data.g_projection_view[3] = temp.row3; - data->buffer_scene_data.g_view_position.x = view_position.x; - data->buffer_scene_data.g_view_position.y = view_position.y; - data->buffer_scene_data.g_view_position.z = view_position.z; - data->buffer_scene_data.g_view_position.w = 0.0f; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); -} - -void render_context::set_scene_shadow_params(const float_t esm_param, - const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1) { - render_data* data = &this->data; - data->buffer_scene_data.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f }; - mat4 temp; - mat4_transpose(&mats[0], &temp); - data->buffer_scene_data.g_self_shadow_receivers[0] = temp.row0; - data->buffer_scene_data.g_self_shadow_receivers[1] = temp.row1; - data->buffer_scene_data.g_self_shadow_receivers[2] = temp.row2; - mat4_transpose(&mats[1], &temp); - data->buffer_scene_data.g_self_shadow_receivers[3] = temp.row0; - data->buffer_scene_data.g_self_shadow_receivers[4] = temp.row1; - data->buffer_scene_data.g_self_shadow_receivers[5] = temp.row2; - data->buffer_scene_data.g_shadow_ambient = shadow_ambient; - data->buffer_scene_data.g_shadow_ambient1 = shadow_ambient1; - enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); -} - -void render_context::set_shader(uint32_t index) { - data.set_shader(index); -} - sss_data* sss_data_get() { return &_sss_data; } diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp index 9f9f700..25ca5da 100644 --- a/src/DivaGL/render_context.hpp +++ b/src/DivaGL/render_context.hpp @@ -10,6 +10,7 @@ #include "../KKdLib/vec.hpp" #include "../AFTModsShared/light_param/fog.hpp" #include "../AFTModsShared/light_param/light.hpp" +#include "../AFTModsShared/uniform.hpp" #include "GL/array_buffer.hpp" #include "GL/shader_storage_buffer.hpp" #include "GL/uniform_buffer.hpp" @@ -26,9 +27,9 @@ enum render_data_flags { }; struct draw_state_stats { - int32_t object_draw_count; - int32_t object_translucent_draw_count; - int32_t object_reflect_draw_count; + int32_t sub_mesh_count; + int32_t sub_mesh_no_mat_count; + int32_t sub_mesh_cheap_count; int32_t field_C; int32_t field_10; int32_t draw_count; @@ -49,7 +50,7 @@ struct sss_data { void free(); void init(); - void set_texture(int32_t); + void set_texture(struct p_gl_rend_state& p_gl_rend_st, int32_t texture_index); }; static_assert(sizeof(sss_data) == 0xD8, "\"sss_data\" struct should have a size of 0xD8"); @@ -65,6 +66,18 @@ struct global_material_struct { static_assert(sizeof(global_material_struct) == 0x14, "\"global_material_struct\" struct should have a size of 0x14"); struct draw_state_struct { + struct render_data { + int32_t shader_index; + bool self_shadow; + bool shadow; + bool blend; + bool cull_front; + int32_t field_8; + draw_state_stats stats; + + render_data(); + }; + draw_state_stats stats; draw_state_stats stats_prev; bool vertex_buffer; @@ -376,7 +389,10 @@ struct render_data { }; render_data_flags flags; + cam_data cam; + mat4 inv_view_mat; int32_t shader_index; + uniform_value shader_flags; obj_shader_data buffer_shader_data; obj_scene_data buffer_scene_data; obj_batch_data buffer_batch_data; @@ -389,11 +405,12 @@ struct render_data { void init(); void free(); - void set(render_context* rctx); + void set_skinning_data(struct p_gl_rend_state& p_gl_rend_st, const mat4* mats, int32_t count); + void set_state(struct p_gl_rend_state& p_gl_rend_st); void set_shader(uint32_t index); }; -struct render_context { +struct render_data_context { struct fog_params { vec4 depth_color; vec4 height_params; @@ -404,6 +421,61 @@ struct render_context { float_t end; }; + p_gl_rend_state state; + gl_rend_state_index index; + render_data& data; + uniform_value& shader_flags; + + render_data_context(gl_rend_state_index index); + + void get_scene_fog_params(render_data_context::fog_params& value); + void get_scene_light(vec4* light_env_stage_diffuse, + vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, + vec4* light_env_chara_diffuse, vec4* light_env_chara_specular); + void reset_shader_flags(); + void set_batch_alpha_threshold(const float_t value); + void set_batch_blend_color_offset_color(const vec4& blend_color, const vec4& offset_color); + void set_batch_material_color(const vec4& diffuse, const vec4& ambient, + const vec4& emission, const float_t material_shininess, const vec4& specular, + const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, + const vec4& texture_color_offset, const vec4& texture_specular_coefficients, + const vec4& texture_specular_offset, const float_t shininess); + void set_batch_material_color_emission(const vec4& emission); + void set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, + const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale); + void set_batch_min_alpha(const float_t value); + void set_batch_morph_weight(const float_t value); + void set_batch_scene_camera(const cam_data& cam); + void set_batch_sss_param(const vec4& sss_param); + void set_batch_texcoord_transforms(const mat4 mats[2]); + void set_batch_worlds(const mat4& mat); + void set_glitter_render_data_state(); + void set_render_data_state(); + void set_scene_fog_params(const render_data_context::fog_params& value); + void set_scene_framebuffer_size(const int32_t width, const int32_t height, + const int32_t render_width, const int32_t render_height); + void set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, + const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, + const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, + const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, + const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, + const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, + const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, + const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, + const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, + const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, + const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, + const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color); + void set_scene_light_projection(const mat4& light_projection); + void set_scene_shadow_params(const float_t esm_param, + const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1); + void set_self_shadow(bool value); + void set_shader(uint32_t index); + void set_shadow(bool value); + void set_skinning_data(p_gl_rend_state& p_gl_rend_st, const mat4* mats, int32_t count); +}; + +struct render_context { struct shared_storage_buffer { void* data; size_t offset; @@ -434,11 +506,6 @@ struct render_context { size_t size; }; - mat4 view_mat; - mat4 proj_mat; - mat4 vp_mat; - vec4 g_near_far; - GLuint box_vao; GL::ArrayBuffer box_vbo; @@ -470,7 +537,9 @@ struct render_context { GL::UniformBuffer tone_map_ubo; GL::UniformBuffer transparency_batch_ubo; - render_data data; + render_data data[GL_REND_STATE_COUNT]; + draw_state_struct::render_data draw_state_rend_data[GL_REND_STATE_COUNT]; + cam_data render_manager_cam; texture* empty_texture_2d; texture* empty_texture_cube_map; @@ -502,54 +571,10 @@ struct render_context { void add_shared_storage_uniform_buffer_data(size_t index, const void* data, size_t size, size_t max_size, bool storage = false); - void get_scene_fog_params(render_context::fog_params& value); - void get_scene_light(vec4* light_env_stage_diffuse, - vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, - vec4* light_env_chara_diffuse, vec4* light_env_chara_specular); bool get_shared_storage_uniform_buffer_data(size_t index, GLuint& buffer, size_t& offset, size_t& size, bool storage = false); void post_proc(); void pre_proc(); - void set_batch_alpha_threshold(const float_t value); - void set_batch_blend_color(const vec4& blend_color); - void set_batch_blend_color_offset_color(const vec4& blend_color, const vec4& offset_color); - void set_batch_joint(const mat4& mat); - void set_batch_material_color(const vec4& diffuse, const vec4& ambient, - const vec4& emission, const float_t material_shininess, const vec4& specular, - const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, - const vec4& texture_color_offset, const vec4& texture_specular_coefficients, - const vec4& texture_specular_offset, const float_t shininess); - void set_batch_material_color_emission(const vec4& emission); - void set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, - const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale); - void set_batch_min_alpha(const float_t value); - void set_batch_morph_weight(const float_t value); - void set_batch_offset_color(const vec4& offset_color); - void set_batch_sss_param(const vec4& sss_param); - void set_batch_texcoord_transforms(const mat4 mats[2]); - void set_batch_worlds(const mat4& mat); - void set_glitter_render_data(); - void set_render_data(); - void set_scene_fog_params(const render_context::fog_params& value); - void set_scene_framebuffer_size(const int32_t width, const int32_t height, - const int32_t render_width, const int32_t render_height); - void set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, - const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, - const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, - const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, - const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, - const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, - const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, - const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, - const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, - const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, - const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, - const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color); - void set_scene_light_projection(const mat4& light_projection); - void set_scene_projection_view(const mat4& view, const mat4& proj, const vec3& view_position); - void set_scene_shadow_params(const float_t esm_param, - const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1); - void set_shader(uint32_t index); }; extern draw_state_struct& draw_state; diff --git a/src/DivaGL/render_manager.cpp b/src/DivaGL/render_manager.cpp index 5e30d90..c8c5a21 100644 --- a/src/DivaGL/render_manager.cpp +++ b/src/DivaGL/render_manager.cpp @@ -13,7 +13,7 @@ #include "rob/rob.hpp" #include "clear_color.hpp" #include "effect.hpp" -#include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "light_param.hpp" #include "render.hpp" #include "render_context.hpp" @@ -54,44 +54,48 @@ RenderTexture* litproj_shadow = (RenderTexture*)0x0000000141194DA0; RenderTexture* litproj_texture = (RenderTexture*)0x0000000141194E00; rndr::RenderManager& render_manager = *(rndr::RenderManager*)0x00000001411AD320; -static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); -static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); -static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, - RenderTexture* a3, float_t sigma, float_t far_texel_offset, bool enable_lit_proj); -static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src); -static bool draw_pass_shadow_litproj(); -static bool draw_pass_shadow_litproj_set(); -static bool draw_pass_shadow_litproj_set_mat(bool set_mat); -static void draw_pass_sss_contour(rndr::Render* rend); -static void draw_pass_sss_filter(sss_data* sss); +static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, + render_data_context& rend_data_ctx, cam_data& cam, int32_t index, int32_t a3); +static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, + render_data_context& rend_data_ctx, int32_t index, int32_t a3); +static void draw_pass_shadow_filter(render_data_context& rend_data_ctx, + RenderTexture* a1, RenderTexture* a2, RenderTexture* a3, + float_t sigma, float_t far_texel_offset, bool enable_lit_proj); +static void draw_pass_shadow_esm_filter(render_data_context& rend_data_ctx, + RenderTexture* dst, RenderTexture* buf, RenderTexture* src); +static bool draw_pass_shadow_litproj(render_data_context& rend_data_ctx, cam_data& cam); +static bool draw_pass_shadow_litproj_set(render_data_context& rend_data_ctx, cam_data& cam); +static bool draw_pass_shadow_litproj_set_mat(render_data_context& rend_data_ctx, cam_data& cam, bool set_mat); +static void draw_pass_sss_contour(render_data_context& rend_data_ctx, rndr::Render* rend, cam_data& cam); +static void draw_pass_sss_filter(render_data_context& rend_data_ctx, sss_data* sss); static int32_t draw_pass_3d_get_translucent_count(); -static void draw_pass_3d_shadow_reset(); -static void draw_pass_3d_shadow_set(Shadow* shad); -extern void draw_pass_3d_translucent(mdl::ObjType opaque, - mdl::ObjType transparent, mdl::ObjType translucent); +static void draw_pass_3d_shadow_reset(render_data_context& rend_data_ctx); +static void draw_pass_3d_shadow_set(render_data_context& rend_data_ctx, Shadow* shad); +extern void draw_pass_3d_translucent(render_data_context& rend_data_ctx, + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam); static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, - mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent); -static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type); + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam); +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type, cam_data& cam); -static void draw_pass_reflect_full(rndr::RenderManager& render_manager); +static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::RenderManager& render_manager); static bool draw_pass_reflect_get_obj_reflect_surface(); static bool draw_pass_reflect_get_obj_reflect_surface(mdl::ObjType type); -static void blur_filter_apply(RenderTexture* dst, RenderTexture* src, +static void blur_filter_apply(render_data_context& rend_data_ctx, RenderTexture* dst, RenderTexture* src, blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset); -static void fog_set(fog_id id); +static void fog_set(render_data_context& rend_data_ctx, fog_id id); static void light_get_direction_from_position(vec4* pos_dir, const light_data* light, bool force = false); static void light_get_light_color(const light_data* light, light_data_color& value, light_id id); -static void lighting_set(light_set_id set_id); +static void lighting_set(render_data_context& rend_data_ctx, light_set_id set_id); static void render_manager_free_render_textures(); static void render_manager_init_render_textures(int32_t multisample); -static void set_reflect_mat(render_context* rctx); +static void set_reflect_mat(render_data_context& rend_data_ctx, cam_data& cam); namespace rndr { struct RenderTextureData { @@ -113,7 +117,7 @@ namespace rndr { static const RenderTextureIndex* render_manager_render_texture_index_array = (const RenderTextureIndex*)0x0000000140A244E0; - void RenderManager::add_pre_process(int32_t type, void(*func)(void*), void* data) { + void RenderManager::add_pre_process(int32_t type, draw_pre_process_func func, void* data) { pre_process.push_back({ type, func, data }); } @@ -214,7 +218,7 @@ namespace rndr { void RenderManager::set_clear(bool value) { clear = value; } - + void RenderManager::set_effect_texture(texture* value) { effect_texture = value; } @@ -268,53 +272,68 @@ namespace rndr { if (!rctx) return; + gl_state.get(); sprite_manager_pre_draw(); - light_param_data_storage_data_set_ibl(); - static const vec4 color_clear = 0.0f; + { + render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); + rend_data_ctx.state.get(); + rend_data_ctx.state.bind_framebuffer(0); + static const vec4 color_clear = 0.0f; + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + } - gl_rend_state.bind_framebuffer(0); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); + { + render_data_context rend_data_ctx(GL_REND_STATE_PRE_3D); + rend_data_ctx.state.begin_event("rndpass_render_all_pass::Caller::execute_pre3d"); + for (int32_t i = RND_PASSID_SHADOW; i <= RND_PASSID_CLEAR; i++) + RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); + rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); + } - rctx->set_scene_framebuffer_size(render->render_width[0], - render->render_height[0], render->render_width[0], render->render_height[0]); + { + render_data_context rend_data_ctx(GL_REND_STATE_3D); + rend_data_ctx.state.get(); + rend_data_ctx.state.begin_event("rndpass_render_all_pass::Caller::execute_3d"); + for (int32_t i = RND_PASSID_PRE_SPRITE; i <= RND_PASSID_3D; i++) + RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); + rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); + } - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - - gl_rend_state.begin_event("rndpass_render_all_pass::Caller::execute_pre3d"); - for (int32_t i = RND_PASSID_SHADOW; i <= RND_PASSID_CLEAR; i++) - RenderManager::render_single_pass((RenderPassID)i); - gl_rend_state.end_event(); - - gl_rend_state.begin_event("rndpass_render_all_pass::Caller::execute_3d"); - for (int32_t i = RND_PASSID_PRE_SPRITE; i <= RND_PASSID_3D; i++) - RenderManager::render_single_pass((RenderPassID)i); - gl_rend_state.end_event(); - - gl_rend_state.begin_event("rndpass_render_all_pass::Caller::execute_2d"); - for (int32_t i = RND_PASSID_SHOW_VECTOR; i <= RND_PASSID_12; i++) - RenderManager::render_single_pass((RenderPassID)i); - gl_rend_state.end_event(); + { + render_data_context rend_data_ctx(GL_REND_STATE_2D); + rend_data_ctx.state.get(); + rend_data_ctx.state.begin_event("rndpass_render_all_pass::Caller::execute_2d"); + for (int32_t i = RND_PASSID_SHOW_VECTOR; i <= RND_PASSID_12; i++) + RenderManager::render_single_pass(rend_data_ctx, (RenderPassID)i); + rend_data_ctx.state.end_event(); + rend_data_ctx.state.update(); + } disp_manager->check_vertex_arrays(); sprite_manager_post_draw(); - gl_rend_state.bind_vertex_array(0); - gl_rend_state.disable_primitive_restart(); - gl_rend_state.bind_uniform_buffer(0); - gl_rend_state.bind_uniform_buffer_base(0, 0); - gl_rend_state.bind_uniform_buffer_base(1, 0); - gl_rend_state.bind_uniform_buffer_base(2, 0); - gl_rend_state.bind_uniform_buffer_base(3, 0); - gl_rend_state.bind_uniform_buffer_base(4, 0); - gl_rend_state.bind_shader_storage_buffer(0); - gl_rend_state.bind_shader_storage_buffer_base(0, 0); + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + rend_data_ctx.state.get(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.disable_primitive_restart(); + rend_data_ctx.state.bind_uniform_buffer(0); + rend_data_ctx.state.bind_uniform_buffer_base(0, 0); + rend_data_ctx.state.bind_uniform_buffer_base(1, 0); + rend_data_ctx.state.bind_uniform_buffer_base(2, 0); + rend_data_ctx.state.bind_uniform_buffer_base(3, 0); + rend_data_ctx.state.bind_uniform_buffer_base(4, 0); + rend_data_ctx.state.bind_shader_storage_buffer(0); + rend_data_ctx.state.bind_shader_storage_buffer_base(0, 0); } - void RenderManager::render_single_pass(RenderPassID id) { + void RenderManager::render_single_pass(render_data_context& rend_data_ctx, RenderPassID id) { cpu_time[id] = 0.0; gpu_time[id] = 0.0; if (!pass_sw[id]) { @@ -325,37 +344,37 @@ namespace rndr { render_pass_begin(); switch (id) { case RND_PASSID_SHADOW: - pass_shadow(); + pass_shadow(rend_data_ctx); break; case RND_PASSID_SS_SSS: - pass_ss_sss(); + pass_ss_sss(rend_data_ctx); break; case RND_PASSID_REFLECT: - pass_reflect(); + pass_reflect(rend_data_ctx); break; case RND_PASSID_REFRACT: - pass_refract(); + pass_refract(rend_data_ctx); break; case RND_PASSID_PRE_PROCESS: - pass_pre_process(); + pass_pre_process(rend_data_ctx); break; case RND_PASSID_CLEAR: - pass_clear(); + pass_clear(rend_data_ctx); break; case RND_PASSID_PRE_SPRITE: - pass_pre_sprite(); + pass_pre_sprite(rend_data_ctx); break; case RND_PASSID_3D: - pass_3d(); + pass_3d(rend_data_ctx); break; case RND_PASSID_SHOW_VECTOR: - pass_show_vector(); + pass_show_vector(rend_data_ctx); break; case RND_PASSID_POST_PROCESS: - pass_post_process(); + pass_post_process(rend_data_ctx); break; case RND_PASSID_SPRITE: - pass_sprite(); + pass_sprite(rend_data_ctx); break; } render_pass_end(id); @@ -379,36 +398,41 @@ namespace rndr { gpu_time[id] = 0; } - void RenderManager::pass_shadow() { - gl_rend_state.begin_event("pass_shadow"); - gl_rend_state.begin_event("texproj"); - if (draw_pass_shadow_litproj_set()) { - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); - disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); - disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); + void RenderManager::pass_shadow(render_data_context& rend_data_ctx) { + cam_data& cam = rctx->render_manager_cam; - draw_state.shader_index = -1; - uniform->arr[U_DEPTH] = 0; - draw_pass_shadow_filter(&litproj_shadow[0], &litproj_shadow[1], 0, 1.5f, 0.01f, true); + rend_data_ctx.state.begin_event("pass_shadow"); + rend_data_ctx.state.begin_event("texproj"); + cam_data texproj_cam; + if (draw_pass_shadow_litproj_set(rend_data_ctx, texproj_cam)) { + rend_data_ctx.set_batch_scene_camera(texproj_cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE, texproj_cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSPARENT, texproj_cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT, texproj_cam); - if (draw_pass_shadow_litproj()) { - draw_pass_set_camera(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + rend_data_ctx.shader_flags.arr[U_DEPTH] = 0; + draw_pass_shadow_filter(rend_data_ctx, &litproj_shadow[0], + &litproj_shadow[1], 0, 1.5f, 0.01f, true); + if (draw_pass_shadow_litproj(rend_data_ctx, texproj_cam)) { for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); - disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.enable_blend(); - disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); - gl_rend_state.disable_blend(); - draw_state.shader_index = -1; - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.set_batch_scene_camera(cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE, cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSPARENT, cam); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT, 1, cam); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.enable_blend(); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT, cam); + rend_data_ctx.state.disable_blend(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + rend_data_ctx.state.bind_framebuffer(0); } } - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); bool v3 = false; int32_t v10[2]; @@ -427,19 +451,23 @@ namespace rndr { shad->curr_render_textures[1] = &shad->render_textures[1]; shad->curr_render_textures[2] = &shad->render_textures[2]; + cam_data cam; for (int32_t i = 0, j = 0; i < 2; i++) { if (!v10[i]) continue; - draw_pass_shadow_begin_make_shadowmap(shad, index[i], j); - disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + index[i])); + draw_pass_shadow_begin_make_shadowmap(shad, rend_data_ctx, cam, index[i], j); + rend_data_ctx.set_batch_scene_camera(cam); + disp_manager->draw(rend_data_ctx, + (mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + index[i]), cam); if (disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + index[i])) > 0) { - gl_rend_state.set_color_mask(show_stage_shadow + rend_data_ctx.state.set_color_mask(show_stage_shadow ? GL_TRUE : GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + i)); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + disp_manager->draw(rend_data_ctx, + (mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + i), cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } - draw_pass_shadow_end_make_shadowmap(shad, index[i], j); + draw_pass_shadow_end_make_shadowmap(shad, rend_data_ctx, index[i], j); j++; } } @@ -447,30 +475,26 @@ namespace rndr { shad->curr_render_textures[0] = &shad->render_textures[0]; shad->curr_render_textures[1] = &shad->render_textures[1]; shad->curr_render_textures[2] = &shad->render_textures[2]; - - for (int32_t i = 1; i < 3; i++) { - shad->curr_render_textures[i]->Bind(); - glClearColorDLL(1.0f, 1.0f, 1.0f, 1.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - } + shad->clear_textures(rend_data_ctx.state); } - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_ss_sss() { + void RenderManager::pass_ss_sss(render_data_context& rend_data_ctx) { ::sss_data* sss = sss_data_get(); if (!sss->init_data || !sss->enable) return; - gl_rend_state.begin_event("pass_ss_sss"); + cam_data& cam = rctx->render_manager_cam; + rend_data_ctx.state.begin_event("pass_ss_sss"); rndr::Render* rend = render; extern bool reflect_full; if (reflect_full && pass_sw[rndr::RND_PASSID_REFLECT] && draw_pass_reflect_get_obj_reflect_surface() && disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS) && reflect_full_ptr) { - gl_rend_state.begin_event("reflect"); + rend_data_ctx.state.begin_event("reflect"); reflect_draw = true; rndr::Render* rend = render; @@ -479,647 +503,628 @@ namespace rndr { // sss->npr_contour = false; //if (sss->npr_contour) { - refl_tex.Bind(); - refl_tex.SetViewport(); + refl_tex.Bind(rend_data_ctx.state); + refl_tex.SetViewport(rend_data_ctx.state); //} //else { - // sss->textures[0].Bind(); - // gl_rend_state.set_viewport(0, 0, 640, 360); + // sss->textures[0].Bind(rend_data_ctx.state); + // rend_data_ctx.state.set_viewport(0, 0, 640, 360); //} - glClearColorDLL(sss->param.x, sss->param.y, sss->param.z, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(sss->param.x, sss->param.y, sss->param.z, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); if (shadow) - draw_pass_3d_shadow_set(shadow_ptr); + draw_pass_3d_shadow_set(rend_data_ctx, shadow_ptr); else - draw_pass_3d_shadow_reset(); + draw_pass_3d_shadow_reset(rend_data_ctx); - set_reflect_mat(rctx); + cam_data reflect_cam = cam; + set_reflect_mat(rend_data_ctx, reflect_cam); + rend_data_ctx.set_batch_scene_camera(reflect_cam); - draw_state.shader_index = SHADER_FT_SSS_SKIN; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_rend_state.disable_depth_test(); - draw_state.shader_index = -1; - draw_pass_3d_shadow_reset(); - uniform->arr[U_NPR] = 0; + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_SSS, reflect_cam); + rend_data_ctx.state.disable_depth_test(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + draw_pass_3d_shadow_reset(rend_data_ctx); + rend_data_ctx.shader_flags.arr[U_NPR] = 0; if (npr_param == 1) { if (sss->enable && sss->npr_contour) { - uniform->arr[U_NPR] = 1; - draw_pass_sss_contour(rend); + rend_data_ctx.shader_flags.arr[U_NPR] = 1; + draw_pass_sss_contour(rend_data_ctx, rend, reflect_cam); } else if (npr) { - refl_tex.Bind(); - refl_tex.SetViewport(); - glClearDLL(GL_DEPTH_BUFFER_BIT); - draw_state.shader_index = SHADER_FT_SSS_SKIN; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_rend_state.disable_depth_test(); - draw_state.shader_index = -1; - gl_rend_state.bind_framebuffer(0); - uniform->arr[U_NPR] = 1; - draw_pass_sss_contour(rend); + refl_tex.Bind(rend_data_ctx.state); + refl_tex.SetViewport(rend_data_ctx.state); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_SSS, reflect_cam); + rend_data_ctx.state.disable_depth_test(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.shader_flags.arr[U_NPR] = 1; + draw_pass_sss_contour(rend_data_ctx, rend, reflect_cam); } } if (!sss->npr_contour) { - sss->textures[0].Bind(); - gl_rend_state.set_viewport(0, 0, 640, 360); + sss->textures[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 640, 360); filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); imgfilter_batch_shader_data imgfilter_batch = {}; imgfilter_batch.g_color_scale = 1.0f; imgfilter_batch.g_color_offset = 0.0f; imgfilter_batch.g_texture_lod = 0.0f; - rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + rctx->imgfilter_batch_ubo.WriteMemory(rend_data_ctx.state, imgfilter_batch); - uniform->arr[U_IMAGE_FILTER] = 5; - shaders_ft.set(SHADER_FT_IMGFILT); - rctx->filter_scene_ubo.Bind(0); - rctx->imgfilter_batch_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, refl_tex.GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.shader_flags.arr[U_IMAGE_FILTER] = 5; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_IMGFILT); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->imgfilter_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, refl_tex.GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); } - draw_pass_sss_filter(sss); + draw_pass_sss_filter(rend_data_ctx, sss); reflect_draw = false; - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } //if (rend->render_width > 1280.0) // sss->npr_contour = false; //if (sss->npr_contour) { - rend->rend_texture[0].Bind(); - rend->rend_texture[0].SetViewport(); + rend->rend_texture[0].Bind(rend_data_ctx.state); + rend->rend_texture[0].SetViewport(rend_data_ctx.state); //} //else { - // sss->textures[0].Bind(); - // gl_rend_state.set_viewport(0, 0, 640, 360); + // sss->textures[0].Bind(rend_data_ctx.state); + // rend_data_ctx.state.set_viewport(0, 0, 640, 360); //} - glClearColorDLL(sss->param.x, sss->param.y, sss->param.z, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(sss->param.x, sss->param.y, sss->param.z, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); if (shadow) - draw_pass_3d_shadow_set(shadow_ptr); + draw_pass_3d_shadow_set(rend_data_ctx, shadow_ptr); else - draw_pass_3d_shadow_reset(); + draw_pass_3d_shadow_reset(rend_data_ctx); - draw_state.shader_index = SHADER_FT_SSS_SKIN; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_rend_state.disable_depth_test(); - draw_state.shader_index = -1; - draw_pass_3d_shadow_reset(); - uniform->arr[U_NPR] = 0; + rend_data_ctx.set_batch_scene_camera(cam); + + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_SSS, cam); + rend_data_ctx.state.disable_depth_test(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + draw_pass_3d_shadow_reset(rend_data_ctx); + rend_data_ctx.shader_flags.arr[U_NPR] = 0; if (npr_param == 1) { if (sss->enable && sss->npr_contour) { - uniform->arr[U_NPR] = 1; - draw_pass_sss_contour(rend); + rend_data_ctx.shader_flags.arr[U_NPR] = 1; + draw_pass_sss_contour(rend_data_ctx, rend, cam); } else if (npr) { - rend->rend_texture[0].Bind(); - rend->rend_texture[0].SetViewport(); - glClearDLL(GL_DEPTH_BUFFER_BIT); - draw_state.shader_index = SHADER_FT_SSS_SKIN; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_rend_state.disable_depth_test(); - draw_state.shader_index = -1; - gl_rend_state.bind_framebuffer(0); - uniform->arr[U_NPR] = 1; - draw_pass_sss_contour(rend); + rend->rend_texture[0].Bind(rend_data_ctx.state); + rend->rend_texture[0].SetViewport(rend_data_ctx.state); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SSS_SKIN; + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_SSS, cam); + rend_data_ctx.state.disable_depth_test(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.shader_flags.arr[U_NPR] = 1; + draw_pass_sss_contour(rend_data_ctx, rend, cam); } } if (!sss->npr_contour) { - sss->textures[0].Bind(); - gl_rend_state.set_viewport(0, 0, 640, 360); + sss->textures[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 640, 360); filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); imgfilter_batch_shader_data imgfilter_batch = {}; imgfilter_batch.g_color_scale = 1.0f; imgfilter_batch.g_color_offset = 0.0f; imgfilter_batch.g_texture_lod = 0.0f; - rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + rctx->imgfilter_batch_ubo.WriteMemory(rend_data_ctx.state, imgfilter_batch); - uniform->arr[U_IMAGE_FILTER] = 5; - shaders_ft.set(SHADER_FT_IMGFILT); - rctx->filter_scene_ubo.Bind(0); - rctx->imgfilter_batch_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.shader_flags.arr[U_IMAGE_FILTER] = 5; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_IMGFILT); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->imgfilter_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); } - draw_pass_sss_filter(sss); - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + draw_pass_sss_filter(rend_data_ctx, sss); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_reflect() { + void RenderManager::pass_reflect(render_data_context& rend_data_ctx) { extern bool reflect_full; if (reflect_full) { - draw_pass_reflect_full(*this); + draw_pass_reflect_full(rend_data_ctx, *this); return; } - gl_rend_state.begin_event("pass_reflect"); + cam_data& cam = rctx->render_manager_cam; + rend_data_ctx.state.begin_event("pass_reflect"); RenderTexture& refl_tex = render_manager.get_render_texture(0); RenderTexture& refl_buf_tex = rctx->reflect_buffer; - refl_tex.Bind(); + refl_tex.Bind(rend_data_ctx.state); if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSPARENT) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT)) { - refl_tex.SetViewport(); - - draw_pass_set_camera(); + refl_tex.SetViewport(rend_data_ctx.state); + rend_data_ctx.set_batch_scene_camera(cam); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) - fog_set((fog_id)i); + fog_set(rend_data_ctx, (fog_id)i); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_state.shader_index = SHADER_FT_S_REFL; + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_S_REFL; light_set* set = &light_set_data[LIGHT_SET_MAIN]; light_clip_plane clip_plane; set->lights[LIGHT_SPOT].get_clip_plane(clip_plane); - uniform->arr[U_REFLECT] = 2; - uniform->arr[U_CLIP_PLANE] = clip_plane.data[1]; + rend_data_ctx.shader_flags.arr[U_REFLECT] = 2; + rend_data_ctx.shader_flags.arr[U_CLIP_PLANE] = clip_plane.data[1]; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE, 0, reflect_texture_mask); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_OPAQUE, cam, 0, reflect_texture_mask); if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.set_blend_equation(GL_FUNC_ADD); - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); - gl_rend_state.disable_blend(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.set_blend_equation(GL_FUNC_ADD); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, cam); + rend_data_ctx.state.disable_blend(); } if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { - uniform->arr[U_REFLECT] = reflect_tone_curve ? 1 : 0; - uniform->arr[U_CLIP_PLANE] = clip_plane.data[0]; - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE); + rend_data_ctx.shader_flags.arr[U_REFLECT] = reflect_tone_curve ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_CLIP_PLANE] = clip_plane.data[0]; + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE, cam); } - gl_rend_state.disable_depth_test(); - uniform->arr[U_REFLECT] = 0; - draw_state.shader_index = -1; + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.shader_flags.arr[U_REFLECT] = 0; + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; for (int32_t i = reflect_blur_num, j = 0; i > 0; i--, j++) { - blur_filter_apply(&refl_buf_tex, &refl_tex, + blur_filter_apply(rend_data_ctx, &refl_buf_tex, &refl_tex, reflect_blur_filter, 1.0f, 1.0f, 0.0f); - image_filter_scale(&refl_tex, refl_buf_tex.color_texture); + image_filter_scale(rend_data_ctx, &refl_tex, refl_buf_tex.color_texture); } } else { vec4 clear_color; - glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_refract() { - gl_rend_state.begin_event("pass_refract"); + void RenderManager::pass_refract(render_data_context& rend_data_ctx) { + cam_data& cam = rctx->render_manager_cam; + rend_data_ctx.state.begin_event("pass_refract"); RenderTexture& refract_texture = render_manager.get_render_texture(1); - refract_texture.Bind(); + refract_texture.Bind(rend_data_ctx.state); if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_OPAQUE) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSPARENT) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT)) { - texture* refr_tex = refract_texture.color_texture; - gl_rend_state.set_viewport(0, 0, refr_tex->width, refr_tex->height); - - draw_pass_set_camera(); + refract_texture.SetViewport(rend_data_ctx.state); + rend_data_ctx.set_batch_scene_camera(cam); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) - fog_set((fog_id)i); + fog_set(rend_data_ctx, (fog_id)i); vec4 clear_color; - glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - draw_state.shader_index = SHADER_FT_S_REFR; - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_REFRACT_OPAQUE); - disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSPARENT); - disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT); - gl_rend_state.disable_depth_test(); - draw_state.shader_index = -1; + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_S_REFR; + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFRACT_OPAQUE, cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFRACT_TRANSPARENT, cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFRACT_TRANSLUCENT, cam); + rend_data_ctx.state.disable_depth_test(); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; } else { vec4 clear_color; - glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_pre_process() { - gl_rend_state.begin_event("pass_pre_process"); + void RenderManager::pass_pre_process(render_data_context& rend_data_ctx) { + rend_data_ctx.state.begin_event("pass_pre_process"); for (draw_pre_process& i : pre_process) if (i.func) - i.func(i.data); - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + i.func(rend_data_ctx, i.data, rctx->render_manager_cam); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_clear() { - gl_rend_state.begin_event("pass_clear"); + void RenderManager::pass_clear(render_data_context& rend_data_ctx) { + rend_data_ctx.state.begin_event("pass_clear"); if (clear) { - rctx->screen_buffer.Bind(); - clear_color_set_gl(); - //glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClearDLL(GL_COLOR_BUFFER_BIT); - gl_rend_state.bind_framebuffer(0); + rctx->screen_buffer.Bind(rend_data_ctx.state); + clear_color_set_gl(rend_data_ctx.state); + //rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(0); } rndr::Render* rend = render; if (!sss_data_get()->enable || !sss_data_get()->npr_contour) { - rend->bind_render_texture(); + rend->bind_render_texture(rend_data_ctx.state); if (sprite_manager_get_reqlist_count(2)) { - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepthf(1.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_depth(1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(0); } else { - clear_color_set_gl(); - glClearDepthf(1.0f); + clear_color_set_gl(rend_data_ctx.state); + rend_data_ctx.state.clear_depth(1.0f); if (clear) - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else - glClearDLL(GL_DEPTH_BUFFER_BIT); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(0); } } else { if (sprite_manager_get_reqlist_count(2)) { - rend->bind_render_texture(); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - gl_rend_state.bind_framebuffer(0); + rend->bind_render_texture(rend_data_ctx.state); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(0); } else if (clear) { - rend->bind_render_texture(); - clear_color_set_gl(); - glClearDLL(GL_COLOR_BUFFER_BIT); - gl_rend_state.bind_framebuffer(0); + rend->bind_render_texture(rend_data_ctx.state); + clear_color_set_gl(rend_data_ctx.state); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(0); } } gl_get_error_print(); - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_pre_sprite() { + void RenderManager::pass_pre_sprite(render_data_context& rend_data_ctx) { if (!sprite_manager_get_reqlist_count(2)) return; - gl_rend_state.begin_event("pass_pre_sprite"); + rend_data_ctx.state.begin_event("pass_pre_sprite"); rndr::Render* rend = render; - rend->bind_render_texture(true); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); + rend->bind_render_texture(rend_data_ctx.state, true); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); sprite_manager_set_view_projection(true); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.disable_depth_test(); - gl_rend_state.enable_blend(); - gl_rend_state.disable_cull_face(); - sprite_manager_draw(2, true, + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); + sprite_manager_draw(rend_data_ctx, 2, true, rend->temp_buffer.color_texture); - gl_rend_state.enable_cull_face(); - gl_rend_state.disable_blend(); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - shader::unbind(); - gl_rend_state.bind_framebuffer(0); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); gl_get_error_print(); - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_3d() { - render->bind_render_texture(); - draw_pass_set_camera(); + void RenderManager::pass_3d(render_data_context& rend_data_ctx) { + cam_data& cam = rctx->render_manager_cam; + render->bind_render_texture(rend_data_ctx.state); if (!sss_data_get()->enable || !sss_data_get()->npr_contour || draw_pass_3d_get_translucent_count()) { - gl_rend_state.set_depth_mask(GL_TRUE); - glClearDLL(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); } - gl_rend_state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.set_batch_scene_camera(cam); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); for (int32_t i = FOG_DEPTH; i < FOG_MAX; i++) - fog_set((fog_id)i); + fog_set(rend_data_ctx, (fog_id)i); if (shadow) - draw_pass_3d_shadow_set(shadow_ptr); + draw_pass_3d_shadow_set(rend_data_ctx, shadow_ptr); else - draw_pass_3d_shadow_reset(); + draw_pass_3d_shadow_reset(rend_data_ctx); if (effect_texture) - gl_rend_state.active_bind_texture_2d(14, effect_texture->glid); + rend_data_ctx.state.active_bind_texture_2d(14, effect_texture->glid); else - gl_rend_state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); if (pass_sw[RND_PASSID_REFLECT] && reflect) { extern bool reflect_full; RenderTexture& refl_tex = reflect_full && reflect_full_ptr ? reflect_full_ptr->reflect_texture : get_render_texture(0); - gl_rend_state.active_bind_texture_2d(15, refl_tex.GetColorTex()); - uniform->arr[U_WATER_REFLECT] = 1; + rend_data_ctx.state.active_bind_texture_2d(15, refl_tex.GetColorTex()); + rend_data_ctx.shader_flags.arr[U_WATER_REFLECT] = 1; } else { - gl_rend_state.active_bind_texture_2d(15, rctx->empty_texture_2d->glid); - uniform->arr[U_WATER_REFLECT] = 0; + rend_data_ctx.state.active_bind_texture_2d(15, rctx->empty_texture_2d->glid); + rend_data_ctx.shader_flags.arr[U_WATER_REFLECT] = 0; } - sss_data_get()->set_texture(1); + sss_data_get()->set_texture(rend_data_ctx.state, 1); - gl_rend_state.bind_sampler(14, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(15, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(16, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(14, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(15, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(16, rctx->render_samplers[0]); - uniform->arr[U_STAGE_AMBIENT] = light_stage_ambient ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_STAGE_AMBIENT] = light_stage_ambient ? 1 : 0; if (alpha_z_sort) { - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1, field_31F); - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, 2); - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, 1, field_31F); - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, 1, field_31F); - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, 1, field_31F); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, 2, cam); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, 1, cam, field_31F); } if (opaque_z_sort) - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE, 0, cam); if (draw_pass_3d[DRAW_PASS_3D_OPAQUE]) { - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE, cam); + rend_data_ctx.state.disable_depth_test(); } - Glitter::glt_particle_manager->DispScenes(Glitter::DISP_OPAQUE); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_OPAQUE); + Glitter::glt_particle_manager->DispScenes(rend_data_ctx, Glitter::DISP_OPAQUE, cam); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_OPAQUE, cam); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) - disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSPARENT, cam); if (render_manager.field_120) - disp_manager->draw(mdl::OBJ_TYPE_TYPE_7); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TYPE_7, cam); - render->calc_exposure_chara_data(); + render->calc_exposure_chara_data(rend_data_ctx, cam); if (npr_param == 1) - pass_3d_contour(); + pass_3d_contour(rend_data_ctx); - render->draw_lens_flare(); - star_catalog_draw(); + render->draw_lens_flare(rend_data_ctx, cam); + star_catalog_draw(rend_data_ctx, cam); - draw_pass_3d_translucent( + draw_pass_3d_translucent(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, - mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3); + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, cam); - snow_particle_draw(); - rain_particle_draw(); - leaf_particle_draw(); - particle_draw(); - gl_rend_state.disable_depth_test(); + snow_particle_draw(rend_data_ctx, cam); + rain_particle_draw(rend_data_ctx, cam); + leaf_particle_draw(rend_data_ctx, cam); + particle_draw(rend_data_ctx, cam); + rend_data_ctx.state.disable_depth_test(); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager->DispScenes(Glitter::DISP_ALPHA); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_ALPHA); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager->DispScenes(rend_data_ctx, Glitter::DISP_ALPHA, cam); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_ALPHA, cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); /*if (npr_param == 1) { - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); }*/ - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_depth_test(); if (draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.set_depth_mask(GL_FALSE); - disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS); - disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); - gl_rend_state.disable_blend(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT, cam); + rend_data_ctx.state.disable_blend(); } - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_TYPE_2); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_TYPE_2, cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.set_depth_mask(GL_TRUE); - draw_pass_3d_translucent( + rend_data_ctx.state.set_depth_mask(GL_TRUE); + draw_pass_3d_translucent(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, - mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2); - gl_rend_state.disable_depth_test(); + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, cam); + rend_data_ctx.state.disable_depth_test(); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager->DispScenes(Glitter::DISP_NORMAL); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_NORMAL); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager->DispScenes(rend_data_ctx, Glitter::DISP_NORMAL, cam); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_NORMAL, cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - draw_pass_3d_translucent( + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + draw_pass_3d_translucent(rend_data_ctx, mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, - mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, cam); if (Glitter::glt_particle_manager_x->CheckHasLocalEffect()) { // X - gl_rend_state.begin_event("local"); + rend_data_ctx.state.begin_event("local"); + + cam_data local_cam = cam; + local_cam.set_fov(32.2673416137695f); + local_cam.calc_persp_proj_mat_offset(1.0f, render_get()->get_taa_offset()); + local_cam.calc_view_proj_mat(); + rend_data_ctx.set_batch_scene_camera(local_cam); if (alpha_z_sort) - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, 1, field_31F); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, 1, local_cam); if (opaque_z_sort) - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_LOCAL_OPAQUE, 0); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_OPAQUE, 0, local_cam); - float_t fov = camera_data.fov; - camera_data.fov = 32.2673416137695f; - draw_pass_set_camera(); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_OPAQUE, local_cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_TRANSPARENT, local_cam); + rend_data_ctx.state.enable_blend(); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, local_cam); + rend_data_ctx.state.disable_blend(); - disp_manager->draw(mdl::OBJ_TYPE_LOCAL_OPAQUE); - disp_manager->draw(mdl::OBJ_TYPE_LOCAL_TRANSPARENT); - gl_rend_state.enable_blend(); - disp_manager->draw(mdl::OBJ_TYPE_LOCAL_TRANSLUCENT); - gl_rend_state.disable_blend(); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_LOCAL, local_cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_LOCAL); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - camera_data.fov = fov; + rend_data_ctx.state.end_event(); - gl_rend_state.end_event(); - - draw_pass_set_camera(); + rend_data_ctx.set_batch_scene_camera(cam); } - gl_rend_state.active_bind_texture_2d(14, 0); - gl_rend_state.active_bind_texture_2d(15, 0); + rend_data_ctx.state.active_bind_texture_2d(14, 0); + rend_data_ctx.state.active_bind_texture_2d(15, 0); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.disable_depth_test(); if (shadow) - draw_pass_3d_shadow_reset(); - pass_sprite_surf(); - shader::unbind(); - gl_rend_state.bind_framebuffer(0); + draw_pass_3d_shadow_reset(rend_data_ctx); + pass_sprite_surf(rend_data_ctx); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); } - void RenderManager::pass_show_vector() { - return; - /*if (!show_vector_flags) - return; - - gl_rend_state.begin_event("pass_show_vector"); - - render->bind_render_texture(); - draw_pass_set_camera(); - - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - - //shaders_ft.env_vert_set(20, show_vector_length, show_vector_z_offset, 0.0f, 0.0f); - for (int32_t i = 1; i < 4; i++) { - if (!(show_vector_flags & (1 << (i - 1)))) - continue; - - if (draw_pass_3d[DRAW_PASS_3D_OPAQUE]) - draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_OPAQUE, i); - if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) - draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSPARENT, i); - if (draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { - draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, i); - draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSLUCENT, i); - } + void RenderManager::pass_show_vector(render_data_context& rend_data_ctx) { + if (show_vector_flags) { + rend_data_ctx.state.begin_event("pass_show_vector"); + rend_data_ctx.state.end_event(); } - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event();*/ } - void RenderManager::pass_post_process() { - gl_rend_state.begin_event("pass_post_process"); + void RenderManager::pass_post_process(render_data_context& rend_data_ctx) { + rend_data_ctx.state.begin_event("pass_post_process"); static texture* (FASTCALL * litproj_texture_get)() = (texture * (FASTCALL*)())0x0000000140350600; - render->apply_post_process(litproj_texture_get(), npr_param); - gl_rend_state.end_event(); + render->apply_post_process(rend_data_ctx, + rctx->render_manager_cam, litproj_texture_get(), npr_param); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_sprite() { - gl_rend_state.begin_event("pass_sprite"); + void RenderManager::pass_sprite(render_data_context& rend_data_ctx) { + rend_data_ctx.state.begin_event("pass_sprite"); if (sprite_manager_get_reqlist_count(0)) { rndr::Render* rend = render; - gl_rend_state.set_viewport(0, 0, rend->screen_width, rend->screen_height); + rend_data_ctx.state.set_viewport(0, 0, rend->screen_width, rend->screen_height); if (multisample && multisample_framebuffer) { - gl_rend_state.bind_framebuffer(multisample_framebuffer); - gl_rend_state.enable_multisample(); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.bind_framebuffer(multisample_framebuffer); + rend_data_ctx.state.enable_multisample(); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); } else - rctx->screen_buffer.Bind(); + rctx->screen_buffer.Bind(rend_data_ctx.state); sprite_manager_set_view_projection(false); - gl_rend_state.disable_depth_test(); - gl_rend_state.enable_blend(); - gl_rend_state.disable_cull_face(); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); sprite_manager_set_res((double_t)rctx->screen_width / (double_t)rctx->screen_height, rctx->screen_width, rctx->screen_height); - sprite_manager_draw(0, true, + sprite_manager_draw(rend_data_ctx, 0, true, rctx->screen_overlay_buffer.color_texture); - gl_rend_state.enable_cull_face(); - gl_rend_state.disable_blend(); - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.enable_depth_test(); if (multisample && multisample_framebuffer) { - gl_rend_state.bind_framebuffer(0); - gl_rend_state.disable_multisample(); - fbo_blit(multisample_framebuffer, rctx->screen_buffer.fbos[0], + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.disable_multisample(); + fbo_blit(rend_data_ctx.state, multisample_framebuffer, rctx->screen_buffer.fbos[0], 0, 0, rctx->screen_width, rctx->screen_height, 0, 0, rctx->screen_width, rctx->screen_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } - shader::unbind(); + shader::unbind(rend_data_ctx.state); gl_get_error_print(); } - fbo_blit(rctx->screen_buffer.fbos[0], 0, + fbo_blit(rend_data_ctx.state, rctx->screen_buffer.fbos[0], 0, 0, 0, rctx->screen_width, rctx->screen_height, 0, 0, rctx->screen_width, rctx->screen_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_3d_contour() { + void RenderManager::pass_3d_contour(render_data_context& rend_data_ctx) { + cam_data& cam = rctx->render_manager_cam; + RenderTexture* rt; RenderTexture* contour_rt; if (reflect_draw) { @@ -1131,107 +1136,97 @@ namespace rndr { contour_rt = render->sss_contour_texture; } - gl_rend_state.begin_event("`anonymous-namespace'::draw_npr_frame"); - gl_rend_state.enable_blend(); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.set_blend_equation(GL_FUNC_ADD); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.begin_event("`anonymous-namespace'::draw_npr_frame"); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.set_blend_equation(GL_FUNC_ADD); + rend_data_ctx.state.disable_depth_test(); quad_shader_data quad_data = {}; quad_data.g_texcoord_modifier = { 0.5f, 0.5f, 0.5f, 0.5f }; - rctx->quad_ubo.WriteMemory(quad_data); + rctx->quad_ubo.WriteMemory(rend_data_ctx.state, quad_data); contour_params_shader_data contour_params_data = {}; - contour_params_data.g_near_far = rctx->g_near_far; - rctx->contour_params_ubo.WriteMemory(contour_params_data); + const float_t max_distance = cam.get_max_distance(); + const float_t min_distance = cam.get_min_distance(); + contour_params_data.g_near_far = { + (float_t)(max_distance / (max_distance - min_distance)), + (float_t)(-(max_distance * min_distance) / (max_distance - min_distance)), + min_distance, max_distance + }; + rctx->contour_params_ubo.WriteMemory(rend_data_ctx.state, contour_params_data); - shaders_ft.set(SHADER_FT_CONTOUR_NPR); - gl_rend_state.active_bind_texture_2d(14, rt->GetDepthTex()); - gl_rend_state.active_bind_texture_2d(16, contour_rt->GetColorTex()); - gl_rend_state.active_bind_texture_2d(17, contour_rt->GetDepthTex()); - gl_rend_state.bind_sampler(14, rctx->render_samplers[1]); - gl_rend_state.bind_sampler(16, rctx->render_samplers[1]); - gl_rend_state.bind_sampler(17, rctx->render_samplers[1]); - rctx->quad_ubo.Bind(0); - rctx->contour_params_ubo.Bind(2); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_CONTOUR_NPR); + rend_data_ctx.state.active_bind_texture_2d(14, rt->GetDepthTex()); + rend_data_ctx.state.active_bind_texture_2d(16, contour_rt->GetColorTex()); + rend_data_ctx.state.active_bind_texture_2d(17, contour_rt->GetDepthTex()); + rend_data_ctx.state.bind_sampler(14, rctx->render_samplers[1]); + rend_data_ctx.state.bind_sampler(16, rctx->render_samplers[1]); + rend_data_ctx.state.bind_sampler(17, rctx->render_samplers[1]); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->quad_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(2, rctx->contour_params_ubo); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); if (effect_texture) - gl_rend_state.active_bind_texture_2d(14, effect_texture->glid); + rend_data_ctx.state.active_bind_texture_2d(14, effect_texture->glid); else - gl_rend_state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); - gl_rend_state.bind_sampler(14, rctx->render_samplers[0]); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.enable_depth_test(); - gl_rend_state.disable_blend(); - gl_rend_state.end_event(); + rend_data_ctx.state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(14, rctx->render_samplers[0]); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.end_event(); } - void RenderManager::pass_sprite_surf() { + void RenderManager::pass_sprite_surf(render_data_context& rend_data_ctx) { if (!sprite_manager_get_reqlist_count(1)) return; rndr::Render* rend = render; sprite_manager_set_view_projection(false); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.disable_depth_test(); - gl_rend_state.disable_depth_test(); - gl_rend_state.enable_blend(); - gl_rend_state.disable_cull_face(); - sprite_manager_draw(1, true, + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); + sprite_manager_draw(rend_data_ctx, 1, true, rend->temp_buffer.color_texture); } } -void image_filter_scale(RenderTexture* dst, texture* src, const vec4& scale) { +void image_filter_scale(render_data_context& rend_data_ctx, + RenderTexture* dst, texture* src, const vec4& scale) { if (!dst || !dst->color_texture->glid || !dst->color_texture || !src || !src->glid) return; - gl_rend_state.begin_event("`anonymous-namespace'::Impl::apply_no_filter_sub"); + rend_data_ctx.state.begin_event("`anonymous-namespace'::Impl::apply_no_filter_sub"); - dst->Bind(); - dst->SetViewport(); + dst->Bind(rend_data_ctx.state); + dst->SetViewport(rend_data_ctx.state); filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); imgfilter_batch_shader_data imgfilter_batch = {}; imgfilter_batch.g_color_scale = scale; imgfilter_batch.g_color_offset = 0.0f; imgfilter_batch.g_texture_lod = 0.0f; - rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + rctx->imgfilter_batch_ubo.WriteMemory(rend_data_ctx.state, imgfilter_batch); - uniform->arr[U_IMAGE_FILTER] = 5; - shaders_ft.set(SHADER_FT_IMGFILT); - rctx->filter_scene_ubo.Bind(0); - rctx->imgfilter_batch_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, src->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); -} - -void draw_pass_set_camera() { - mat4_transpose(&camera_data.view, &rctx->view_mat); - mat4_transpose(&camera_data.projection, &rctx->proj_mat); - mat4_transpose(&camera_data.view_projection, &rctx->vp_mat); - vec3 view_point; - camera_data.get_view_point(view_point); - rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point); - - float_t max_distance = camera_data.max_distance; - float_t min_distance = camera_data.min_distance; - rctx->g_near_far = { - (float_t)(max_distance / (max_distance - min_distance)), - (float_t)(-(max_distance * min_distance) / (max_distance - min_distance)), - min_distance, max_distance - }; + rend_data_ctx.shader_flags.arr[U_IMAGE_FILTER] = 5; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_IMGFILT); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->imgfilter_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, src->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); } HOOK(void, FASTCALL, render_manager_init_render_textures, 0x0000000140502560, int32_t multisample) { @@ -1267,7 +1262,7 @@ HOOK(void, FASTCALL, render_manager_init_data, 0x0000000140502A2A, int32_t ssaa, render_manager.width = res_wind->width; render_manager.height = res_wind->height; render_manager_init_render_textures(1); - render_manager.render->init_tone_map_buffers(); + render_manager.render->init_post_process_buffers(); shadow_ptr_init(); render_manager.shadow_ptr = shadow_ptr_get(); @@ -1383,19 +1378,17 @@ void get_reflect_mat() { reflect_mat.row3.w = 1.0f; } -static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { - shad->curr_render_textures[0]->Bind(); - shad->curr_render_textures[0]->SetViewport(); +static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, + render_data_context& rend_data_ctx, cam_data& cam, int32_t index, int32_t a3) { + shad->curr_render_textures[0]->Bind(rend_data_ctx.state); texture* tex = shad->curr_render_textures[0]->color_texture; - gl_rend_state.set_scissor(0, 0, tex->width, tex->height); - gl_rend_state.enable_depth_test(); - gl_rend_state.enable_scissor_test(); - glClearColorDLL(1.0, 1.0, 1.0, 1.0); + rend_data_ctx.state.set_viewport(1, 1, tex->width - 2, tex->width - 2); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.clear_color(1.0f, 1.0f, 1.0f, 1.0f); if (!a3) - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else if (shad->separate) - glClearDLL(GL_COLOR_BUFFER_BIT); - gl_rend_state.set_scissor(1, 1, tex->width - 2, tex->height - 2); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); float_t shadow_range = shad->get_shadow_range(); float_t offset; @@ -1412,61 +1405,58 @@ static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, i view_point = &shad->view_point_shared; } - mat4 temp; - mat4_translate(offset, 0.0f, 0.0f, &temp); - - mat4 proj; - mat4_ortho(-shadow_range, shadow_range, - -shadow_range, shadow_range, shad->z_near, shad->z_far, &proj); - mat4_mul(&proj, &temp, &rctx->proj_mat); - mat4_look_at(view_point, interest, &rctx->view_mat); - mat4_mul(&rctx->view_mat, &rctx->proj_mat, &rctx->vp_mat); - rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, *view_point); - - draw_state.shader_index = SHADER_FT_SIL; - uniform->arr[U_DEPTH] = 0; + const float_t scale = (float_t)(tex->width / 2) / (float_t)((tex->width - 2) / 2); + shad->calc_proj_view_mat(cam, *view_point, *interest, shadow_range, offset, scale); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SIL; + rend_data_ctx.shader_flags.arr[U_DEPTH] = 0; } -static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { - gl_rend_state.disable_depth_test(); - gl_rend_state.disable_scissor_test(); +static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, + render_data_context& rend_data_ctx, int32_t index, int32_t a3) { + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.disable_scissor_test(); - draw_state.shader_index = -1; + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; if (a3 == shad->num_shadow - 1) { - draw_pass_shadow_filter(&shad->render_textures[3], + draw_pass_shadow_filter(rend_data_ctx, &shad->render_textures[3], &shad->render_textures[4], shad->curr_render_textures[0], shad->field_2DC, shad->field_2E0 / (shad->z_half_range * 2.0f), false); - draw_pass_shadow_esm_filter(&shad->render_textures[5], + draw_pass_shadow_esm_filter(rend_data_ctx, &shad->render_textures[5], &shad->render_textures[6], &shad->render_textures[3]); } RenderTexture* rend_tex = shad->curr_render_textures[1 + index]; RenderTexture& rend_buf_tex = rctx->shadow_buffer; - image_filter_scale(rend_tex, + image_filter_scale(rend_data_ctx, rend_tex, shad->curr_render_textures[0]->color_texture); if (shad->blur_filter_enable[index]) { for (int32_t i = shad->near_blur, j = 0; i > 0; i--, j++) { - blur_filter_apply(&rend_buf_tex, rend_tex, + blur_filter_apply(rend_data_ctx, &rend_buf_tex, rend_tex, shad->blur_filter, 1.0f, 1.0f, 0.0f); - image_filter_scale(rend_tex, rend_buf_tex.color_texture); + image_filter_scale(rend_data_ctx, rend_tex, rend_buf_tex.color_texture); } } else { - rend_buf_tex.Bind(); - glClearColorDLL(1.0f, 1.0f, 1.0f, 1.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); + rend_buf_tex.Bind(rend_data_ctx.state); + rend_data_ctx.state.clear_color(1.0f, 1.0f, 1.0f, 1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); } - gl_rend_state.bind_framebuffer(0); - gl_rend_state.bind_texture_2d(rend_tex->GetColorTex()); - glGenerateMipmap(GL_TEXTURE_2D); - gl_rend_state.bind_texture_2d(0); + rend_data_ctx.state.bind_framebuffer(0); + if (DIVA_GL_VERSION_4_5) + rend_data_ctx.state.generate_texture_mipmap(rend_tex->GetColorTex()); + else { + rend_data_ctx.state.bind_texture_2d(rend_tex->GetColorTex()); + rend_data_ctx.state.generate_mipmap(GL_TEXTURE_2D); + rend_data_ctx.state.bind_texture_2d(0); + } } -static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, - RenderTexture* a3, float_t sigma, float_t far_texel_offset, bool enable_lit_proj) { +static void draw_pass_shadow_filter(render_data_context& rend_data_ctx, + RenderTexture* a1, RenderTexture* a2, RenderTexture* a3, + float_t sigma, float_t far_texel_offset, bool enable_lit_proj) { texture* v7 = a1->color_texture; texture* v9 = a2->color_texture; texture* v11 = v7; @@ -1476,11 +1466,11 @@ static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, if (!v7 || !v9 || !v11 || v7->width != v9->width || v7->height != v9->height) return; - gl_rend_state.begin_event("`anonymous-namespace'::Impl::apply_esm_filter"); + rend_data_ctx.state.begin_event("`anonymous-namespace'::Impl::apply_esm_filter"); filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = 0.0f; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); esm_filter_batch_shader_data esm_filter_batch = {}; esm_filter_batch.g_params = { 1.0f / (float_t)v7->width, 0.0f, far_texel_offset, far_texel_offset }; @@ -1489,98 +1479,91 @@ static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, for (int32_t i = 0; i < 8; i++) ((float_t*)esm_filter_batch.g_gauss)[i] = (float_t)(exp((double_t)((ssize_t)i * i) * v8) * v6); - uniform->arr[U_LIGHT_PROJ] = enable_lit_proj ? 1 : 0; - shaders_ft.set(SHADER_FT_ESMGAUSS); - rctx->filter_scene_ubo.Bind(0); - rctx->esm_filter_batch_ubo.Bind(1); + rend_data_ctx.shader_flags.arr[U_LIGHT_PROJ] = enable_lit_proj ? 1 : 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_ESMGAUSS); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->esm_filter_batch_ubo); - gl_rend_state.set_viewport(0, 0, v7->width, v7->height); + rend_data_ctx.state.set_viewport(0, 0, v7->width, v7->height); - a2->Bind(); + a2->Bind(rend_data_ctx.state); esm_filter_batch.g_params = { 1.0f / (float_t)v7->width, 0.0f, far_texel_offset, far_texel_offset }; - rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + rctx->esm_filter_batch_ubo.WriteMemory(rend_data_ctx.state, esm_filter_batch); - gl_rend_state.active_bind_texture_2d(0, v11->glid); - if (a3) { - GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - } - else { - GLint swizzle[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - } - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.active_bind_texture_2d(0, v11->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - a1->Bind(); + a1->Bind(rend_data_ctx.state); esm_filter_batch.g_params = { 0.0f, 1.0f / (float_t)v7->height, far_texel_offset, far_texel_offset }; - rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + rctx->esm_filter_batch_ubo.WriteMemory(rend_data_ctx.state, esm_filter_batch); - gl_rend_state.active_bind_texture_2d(0, v9->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - shader::unbind(); - gl_rend_state.end_event(); + rend_data_ctx.state.active_bind_texture_2d(0, v9->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.end_event(); } -static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src) { +static void draw_pass_shadow_esm_filter(render_data_context& rend_data_ctx, + RenderTexture* dst, RenderTexture* buf, RenderTexture* src) { texture* dst_tex = dst->color_texture; texture* buf_tex = buf->color_texture; texture* src_tex = src->color_texture; - gl_rend_state.begin_event("`anonymous-namespace'::Impl::apply_esm_min_filter"); + rend_data_ctx.state.begin_event("`anonymous-namespace'::Impl::apply_esm_min_filter"); if (!dst_tex || !dst_tex->glid || !buf_tex || !buf_tex->glid || !src_tex || !src_tex->glid) { - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); return; } - gl_rend_state.begin_event("minimize"); + rend_data_ctx.state.begin_event("minimize"); filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = 0.0f; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); esm_filter_batch_shader_data esm_filter_batch = {}; esm_filter_batch.g_gauss[0] = 0.0f; esm_filter_batch.g_gauss[1] = 0.0f; - rctx->filter_scene_ubo.Bind(0); - rctx->esm_filter_batch_ubo.Bind(1); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->esm_filter_batch_ubo); - gl_rend_state.set_viewport(0, 0, dst_tex->width, dst_tex->height); + rend_data_ctx.state.set_viewport(0, 0, dst_tex->width, dst_tex->height); - buf->Bind(); + buf->Bind(rend_data_ctx.state); esm_filter_batch.g_params = { 1.0f / (float_t)src_tex->width, 1.0f / (float_t)src_tex->height, 0.0f, 0.0f }; - rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + rctx->esm_filter_batch_ubo.WriteMemory(rend_data_ctx.state, esm_filter_batch); - uniform->arr[U_ESM_FILTER] = 0; - shaders_ft.set(SHADER_FT_ESMFILT); - gl_rend_state.active_bind_texture_2d(0, src_tex->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); + rend_data_ctx.shader_flags.arr[U_ESM_FILTER] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_ESMFILT); + rend_data_ctx.state.active_bind_texture_2d(0, src_tex->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); - gl_rend_state.begin_event("erosion"); - dst->Bind(); + rend_data_ctx.state.begin_event("erosion"); + dst->Bind(rend_data_ctx.state); esm_filter_batch.g_params = { 0.75f / (float_t)buf_tex->width, 0.75f / (float_t)buf_tex->height, 0.0f, 0.0f }; - rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + rctx->esm_filter_batch_ubo.WriteMemory(rend_data_ctx.state, esm_filter_batch); - uniform->arr[U_ESM_FILTER] = 1; - shaders_ft.set(SHADER_FT_ESMFILT); - gl_rend_state.active_bind_texture_2d(0, buf_tex->glid); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); - gl_rend_state.end_event(); + rend_data_ctx.shader_flags.arr[U_ESM_FILTER] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_ESMFILT); + rend_data_ctx.state.active_bind_texture_2d(0, buf_tex->glid); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); + rend_data_ctx.state.end_event(); } -static bool draw_pass_shadow_litproj() { +static bool draw_pass_shadow_litproj(render_data_context& rend_data_ctx, cam_data& cam) { if (!stage_param_data_litproj_current) return false; @@ -1588,58 +1571,79 @@ static bool draw_pass_shadow_litproj() { if (!tex) return false; - litproj_texture->Bind(); - litproj_texture->SetViewport(); - gl_rend_state.enable_depth_test(); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepthf(1.0f); - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + litproj_texture->Bind(rend_data_ctx.state); + litproj_texture->SetViewport(rend_data_ctx.state); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_depth(1.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (!draw_pass_shadow_litproj_set_mat(true)) { - gl_rend_state.bind_framebuffer(0); + if (!draw_pass_shadow_litproj_set_mat(rend_data_ctx, cam, true)) { + rend_data_ctx.state.bind_framebuffer(0); return false; } - draw_state.shader_index = SHADER_FT_LITPROJ; - gl_rend_state.active_bind_texture_2d(17, tex->glid); - gl_rend_state.bind_sampler(17, rctx->render_samplers[2]); - gl_rend_state.active_bind_texture_2d(18, litproj_shadow[0].GetColorTex()); - gl_rend_state.bind_sampler(18, rctx->render_samplers[2]); - gl_rend_state.active_texture(0); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_LITPROJ; + rend_data_ctx.state.active_bind_texture_2d(17, tex->glid); + rend_data_ctx.state.bind_sampler(17, rctx->render_samplers[2]); + rend_data_ctx.state.active_bind_texture_2d(18, litproj_shadow[0].GetColorTex()); + rend_data_ctx.state.bind_sampler(18, rctx->render_samplers[2]); + rend_data_ctx.state.active_texture(0); return true; } -static bool draw_pass_shadow_litproj_set() { +static bool draw_pass_shadow_litproj_set(render_data_context& rend_data_ctx, cam_data& cam) { if (!stage_param_data_litproj_current) return 0; static const vec4 color_clear = 0.0f; static const GLfloat depth_clear = 1.0f; - litproj_shadow[0].Bind(); - gl_rend_state.set_viewport(0, 0, 2048, 512); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - glClearBufferfv(GL_DEPTH, 0, &depth_clear); + litproj_shadow[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 2048, 512); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.clear_buffer(GL_DEPTH, 0, &depth_clear); - if (draw_pass_shadow_litproj_set_mat(false)) { - draw_state.shader_index = SHADER_FT_SIL; - uniform->arr[U_DEPTH] = 1; + if (draw_pass_shadow_litproj_set_mat(rend_data_ctx, cam, false)) { + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = SHADER_FT_SIL; + rend_data_ctx.shader_flags.arr[U_DEPTH] = 1; return true; } else { - litproj_texture->Bind(); - litproj_texture->SetViewport(); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - glClearBufferfv(GL_DEPTH, 0, &depth_clear); + litproj_texture->Bind(rend_data_ctx.state); + litproj_texture->SetViewport(rend_data_ctx.state); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.clear_buffer(GL_COLOR, 0, (float_t*)&color_clear); + rend_data_ctx.state.clear_buffer(GL_DEPTH, 0, &depth_clear); } return false; } -static bool draw_pass_shadow_litproj_set_mat(bool set_mat) { +static void light_proj_get_view_proj_mat(cam_data& cam, const vec3& view_point, const vec3& interest, + const float_t fov, const float_t aspect, const float_t min_distance, const float_t max_distance, mat4* mat) { + cam.set_view_point(view_point); + cam.set_interest(interest); + cam.set_up({ 0.0f, 1.0f, 0.0f }); + cam.calc_view_mat(); + cam.set_fov(fov * DEG_TO_RAD_FLOAT); + cam.set_aspect(aspect); + cam.set_min_distance(min_distance); + cam.set_max_distance(max_distance); + if (mat) { + cam.calc_persp_proj_mat_offset(0.5f, 0.5f); + cam.calc_view_proj_mat(); + *mat = cam.get_view_proj_mat(); + } + else { + cam.calc_persp_proj_mat(); + cam.calc_view_proj_mat(); + } +} + +static bool draw_pass_shadow_litproj_set_mat(render_data_context& rend_data_ctx, cam_data& cam, bool set_mat) { light_set* set = &light_set_data[LIGHT_SET_MAIN]; light_data* data = &set->lights[LIGHT_PROJECTION]; if (data->get_type() != LIGHT_SPOT) @@ -1658,64 +1662,46 @@ static bool draw_pass_shadow_litproj_set_mat(bool set_mat) { vec3 interest = position + spot_direction; if (set_mat) { - mat4 temp; - mat4_translate(0.5f, 0.5f, 0.5f, &temp); - mat4_scale_rot(&temp, 0.5f, 0.5f, 0.5f, &temp); - - mat4 proj; - mat4_persp(fov, 4.0f, 0.1f, 10.0f, &proj); - mat4_mul(&proj, &temp, &proj); - - mat4 view; - vec3 up = { 0.0f, 1.0f, 0.0f }; - mat4_look_at(&position, &interest, &up, &view); - mat4 mat; - mat4_mul(&view, &proj, &mat); - rctx->set_scene_light_projection(mat); - } - else { - mat4_persp(fov, 4.0f, 0.1f, 10.0f, &rctx->proj_mat); - - vec3 up = { 0.0f, 1.0f, 0.0f }; - mat4_look_at(&position, &interest, &up, &rctx->view_mat); - - mat4_mul(&rctx->view_mat, &rctx->proj_mat, &rctx->vp_mat); - - rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, position); + light_proj_get_view_proj_mat(cam, position, interest, + fov * RAD_TO_DEG_FLOAT, 4.0f, 0.1f, 10.0f, &mat); + rend_data_ctx.set_scene_light_projection(mat); } + else + light_proj_get_view_proj_mat(cam, position, interest, + fov * RAD_TO_DEG_FLOAT, 4.0f, 0.1f, 10.0f, 0); return true; } -static void draw_pass_sss_contour(rndr::Render* rend) { +static void draw_pass_sss_contour(render_data_context& rend_data_ctx, rndr::Render* rend, cam_data& cam) { if (reflect_draw) - reflect_full_ptr->reflect_buffer_texture.Bind(); + reflect_full_ptr->reflect_buffer_texture.Bind(rend_data_ctx.state); else - rend->sss_contour_texture->Bind(); + rend->sss_contour_texture->Bind(rend_data_ctx.state); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_ALWAYS); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_ALWAYS); + rend_data_ctx.state.set_depth_mask(GL_TRUE); if (reflect_draw) { RenderTexture& refl_tex = reflect_full_ptr->reflect_texture; - gl_rend_state.set_viewport(0, 0, refl_tex.GetWidth(), refl_tex.GetHeight()); - gl_rend_state.active_bind_texture_2d(0, refl_tex.GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - gl_rend_state.active_bind_texture_2d(1, refl_tex.GetDepthTex()); - gl_rend_state.bind_sampler(1, rctx->render_samplers[1]); + rend_data_ctx.state.set_viewport(0, 0, refl_tex.GetWidth(), refl_tex.GetHeight()); + rend_data_ctx.state.active_bind_texture_2d(0, refl_tex.GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, refl_tex.GetDepthTex()); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[1]); } else { - gl_rend_state.set_viewport(0, 0, rend->render_width[0], rend->render_height[0]); - gl_rend_state.active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - gl_rend_state.active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex()); - gl_rend_state.bind_sampler(1, rctx->render_samplers[1]); + rend_data_ctx.state.set_viewport(0, 0, rend->render_width[0], rend->render_height[0]); + rend_data_ctx.state.active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex()); + rend_data_ctx.state.bind_sampler(1, rctx->render_samplers[1]); } - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_texture(0); - float_t v3 = 1.0f / tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT); + float_t v3 = 1.0f / tanf(cam.get_fov() * 0.5f); - vec3 direction = camera_data.interest - camera_data.view_point; + vec3 direction = cam.get_interest() - cam.get_view_point(); float_t length = vec3::length(direction); float_t v7 = direction.y; if (length != 0.0f) @@ -1727,19 +1713,25 @@ static void draw_pass_sss_contour(rndr::Render* rend) { contour_coef_shader_data shader_data = {}; shader_data.g_contour = { v9 * 0.004f + 0.0027f, 0.003f, v3 * 0.35f, 0.0008f }; - shader_data.g_near_far = rctx->g_near_far; - rctx->contour_coef_ubo.WriteMemory(shader_data); + const float_t max_distance = cam.get_max_distance(); + const float_t min_distance = cam.get_min_distance(); + shader_data.g_near_far = { + (float_t)(max_distance / (max_distance - min_distance)), + (float_t)(-(max_distance * min_distance) / (max_distance - min_distance)), + min_distance, max_distance + }; + rctx->contour_coef_ubo.WriteMemory(rend_data_ctx.state, shader_data); - shaders_ft.set(SHADER_FT_CONTOUR); - rctx->contour_coef_ubo.Bind(2); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_CONTOUR); + rend_data_ctx.state.bind_uniform_buffer_base(2, rctx->contour_coef_ubo); if (reflect_draw) { RenderTexture& refl_tex = reflect_full_ptr->reflect_texture; - render_get()->draw_quad(refl_tex.GetWidth(), refl_tex.GetHeight(), 1.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + render_get()->draw_quad(rend_data_ctx, refl_tex.GetWidth(), refl_tex.GetHeight(), + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); } else - render_get()->draw_quad( + render_get()->draw_quad(rend_data_ctx, rend->render_post_width[0], rend->render_post_height[0], rend->render_post_width_scale, rend->render_post_height_scale, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); @@ -1783,7 +1775,7 @@ static void draw_pass_sss_filter_calc_coef(double_t step, int32_t size, double_t } } -static void draw_pass_sss_filter(sss_data* sss) { +static void draw_pass_sss_filter(render_data_context& rend_data_ctx, sss_data* sss) { const int32_t sss_count = 6; vec3 interest = camera_data.interest; vec3 view_point = camera_data.view_point; @@ -1822,30 +1814,30 @@ static void draw_pass_sss_filter(sss_data* sss) { float_t v34 = (float_t)(1.0 / clamp_def(v31 * v29, 0.25f, 100.0f)); if (v34 < 0.145f) v33 = max_def(v34 - 0.02f, 0.0f) * 8.0f * 0.6f; - rctx->set_batch_sss_param({ v33, 0.0f, 0.0f, 0.0f }); + rend_data_ctx.set_batch_sss_param({ v33, 0.0f, 0.0f, 0.0f }); - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_texture(0); if (sss->npr_contour) { - sss->textures[0].Bind(); - gl_rend_state.set_viewport(0, 0, 640, 360); + sss->textures[0].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 640, 360); rndr::Render* rend = render_get(); - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); RenderTexture& rt = reflect_draw ? reflect_full_ptr->reflect_texture : rend->rend_texture[0]; - gl_rend_state.bind_texture_2d(rt.GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - render_get()->draw_quad(rt.GetWidth(), rt.GetHeight(), 1.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); + rend_data_ctx.state.bind_texture_2d(rt.GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + render_get()->draw_quad(rend_data_ctx, rt.GetWidth(), rt.GetHeight(), + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); } - sss->textures[2].Bind(); - gl_rend_state.set_viewport(0, 0, 320, 180); - uniform->arr[U_SSS_FILTER] = 0; - shaders_ft.set(SHADER_FT_SSS_FILT); - gl_rend_state.bind_texture_2d(sss->textures[0].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - render_get()->draw_quad(sss->textures[0].GetWidth(), sss->textures[0].GetHeight(), + sss->textures[2].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 320, 180); + rend_data_ctx.shader_flags.arr[U_SSS_FILTER] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SSS_FILT); + rend_data_ctx.state.bind_texture_2d(sss->textures[0].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + render_get()->draw_quad(rend_data_ctx, sss->textures[0].GetWidth(), sss->textures[0].GetHeight(), 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); sss_filter_gaussian_coef_shader_data shader_data = {}; @@ -1857,17 +1849,17 @@ static void draw_pass_sss_filter(sss_data* sss) { const double_t a8[] = { 0.3, 0.7, 2.0 }; draw_pass_sss_filter_calc_coef(1.0, sss_count, v34, 3, a5, a6, a7, a8, shader_data.g_coef); - rctx->sss_filter_gaussian_coef_ubo.WriteMemory(shader_data); - sss->textures[reflect_draw ? 3 : 1].Bind(); - gl_rend_state.set_viewport(0, 0, 320, 180); - uniform->arr[U_SSS_FILTER] = 3; - shaders_ft.set(SHADER_FT_SSS_FILT); - gl_rend_state.bind_texture_2d(sss->textures[2].GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - rctx->sss_filter_gaussian_coef_ubo.Bind(1); - render_get()->draw_quad(sss->textures[2].GetWidth(), sss->textures[2].GetHeight(), + rctx->sss_filter_gaussian_coef_ubo.WriteMemory(rend_data_ctx.state, shader_data); + sss->textures[reflect_draw ? 3 : 1].Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, 320, 180); + rend_data_ctx.shader_flags.arr[U_SSS_FILTER] = 3; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_SSS_FILT); + rend_data_ctx.state.bind_texture_2d(sss->textures[2].GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->sss_filter_gaussian_coef_ubo); + render_get()->draw_quad(rend_data_ctx, sss->textures[2].GetWidth(), sss->textures[2].GetHeight(), 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.96f, 1.0f, 0.0f); - gl_rend_state.bind_texture_2d(0); + rend_data_ctx.state.bind_texture_2d(0); } static int32_t draw_pass_3d_get_translucent_count() { @@ -1884,32 +1876,32 @@ static int32_t draw_pass_3d_get_translucent_count() { return count; } -static void draw_pass_3d_shadow_reset() { - gl_rend_state.active_bind_texture_2d(6, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_2d(7, rctx->empty_texture_2d->glid); - draw_state.self_shadow = false; - draw_state.shadow = false; +static void draw_pass_3d_shadow_reset(render_data_context& rend_data_ctx) { + rend_data_ctx.state.active_bind_texture_2d(6, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(7, rctx->empty_texture_2d->glid); + rctx->draw_state_rend_data[rend_data_ctx.index].self_shadow = false; + rctx->draw_state_rend_data[rend_data_ctx.index].shadow = false; } -static void draw_pass_3d_shadow_set(Shadow* shad) { +static void draw_pass_3d_shadow_set(render_data_context& rend_data_ctx, Shadow* shad) { float_t esm_param; if (shad->self_shadow && shad->num_shadow > 0) { - gl_rend_state.active_bind_texture_2d(19, shad->render_textures[3].GetColorTex()); - gl_rend_state.active_bind_texture_2d(20, shad->render_textures[5].GetColorTex()); - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_bind_texture_2d(19, shad->render_textures[3].GetColorTex()); + rend_data_ctx.state.active_bind_texture_2d(20, shad->render_textures[5].GetColorTex()); + rend_data_ctx.state.active_texture(0); esm_param = (shad->field_2D8 * shad->z_half_range * 2.0f) * 1.442695f; - draw_state.self_shadow = true; + rctx->draw_state_rend_data[rend_data_ctx.index].self_shadow = true; } else { - gl_rend_state.active_bind_texture_2d(19, rctx->empty_texture_2d->glid); - gl_rend_state.active_bind_texture_2d(20, rctx->empty_texture_2d->glid); - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_bind_texture_2d(19, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(20, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_texture(0); esm_param = 0.0f; - draw_state.self_shadow = false; + rctx->draw_state_rend_data[rend_data_ctx.index].self_shadow = false; } - gl_rend_state.bind_sampler(19, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(20, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(19, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(20, rctx->render_samplers[0]); mat4 mats[2]; mats[0] = mat4_identity; @@ -1917,8 +1909,8 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { vec4 shadow_ambient; vec4 shadow_ambient1; if (shad->num_shadow > 0) { - draw_state.shadow = true; - uniform->arr[U_STAGE_SHADOW2] = shad->num_shadow > 1 ? 1 : 0; + rctx->draw_state_rend_data[rend_data_ctx.index].shadow = true; + rend_data_ctx.shader_flags.arr[U_STAGE_SHADOW2] = shad->num_shadow > 1 ? 1 : 0; float_t shadow_range = shad->get_shadow_range(); for (int32_t i = 0; i < 2; i++) { @@ -1955,14 +1947,14 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { int32_t j = 0; for (int32_t i = 0; i < 2; i++) if (shad->shadow_enable[i]) { - gl_rend_state.active_bind_texture_2d(6 + j, shad->curr_render_textures[1 + i]->GetColorTex()); + rend_data_ctx.state.active_bind_texture_2d(6 + j, shad->curr_render_textures[1 + i]->GetColorTex()); glTexParameterfDLL(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); j++; } for (; j < 2; j++) - gl_rend_state.active_bind_texture_2d(6 + j, rctx->empty_texture_2d->glid); - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_bind_texture_2d(6 + j, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_texture(0); light_set* set = &light_set_data[LIGHT_SET_MAIN]; light_data* data = &set->lights[LIGHT_SHADOW]; @@ -1977,24 +1969,24 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { shadow_ambient1 = { 1.0f - ambient.x, 1.0f - ambient.y, 1.0f - ambient.z, 0.0f }; } else { - draw_state.shadow = false; + rctx->draw_state_rend_data[rend_data_ctx.index].shadow = false; for (int32_t i = 0; i < 2; i++) - gl_rend_state.active_bind_texture_2d(6 + i, shad->curr_render_textures[1 + i]->GetColorTex()); - gl_rend_state.active_texture(0); + rend_data_ctx.state.active_bind_texture_2d(6 + i, shad->curr_render_textures[1 + i]->GetColorTex()); + rend_data_ctx.state.active_texture(0); shadow_ambient = 1.0f; shadow_ambient1 = 0.0f; } - rctx->set_scene_shadow_params(esm_param, mats, shadow_ambient, shadow_ambient1); + rend_data_ctx.set_scene_shadow_params(esm_param, mats, shadow_ambient, shadow_ambient1); - gl_rend_state.bind_sampler(6, 0); - gl_rend_state.bind_sampler(7, 0); + rend_data_ctx.state.bind_sampler(6, 0); + rend_data_ctx.state.bind_sampler(7, 0); } -static void draw_pass_3d_translucent(mdl::ObjType opaque, - mdl::ObjType transparent, mdl::ObjType translucent) { +static void draw_pass_3d_translucent(render_data_context& rend_data_ctx, + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam) { if (disp_manager->get_obj_count(opaque) < 1 && disp_manager->get_obj_count(transparent) < 1 && disp_manager->get_obj_count(translucent) < 1) @@ -2004,30 +1996,30 @@ static void draw_pass_3d_translucent(mdl::ObjType opaque, int32_t alpha_array[256]; int32_t count = draw_pass_3d_translucent_count_layers( - alpha_array, opaque, transparent, translucent); + alpha_array, opaque, transparent, translucent, cam); for (int32_t i = 0; i < count; i++) { int32_t alpha = alpha_array[i]; - rend->transparency_copy(); + rend->transparency_copy(rend_data_ctx); if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE] && disp_manager->get_obj_count(opaque)) - disp_manager->draw(opaque, 0, true, alpha); + disp_manager->draw(rend_data_ctx, opaque, cam, 0, true, alpha); if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT] && disp_manager->get_obj_count(transparent)) - disp_manager->draw(transparent, 0, true, alpha); + disp_manager->draw(rend_data_ctx, transparent, cam, 0, true, alpha); if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT] && disp_manager->get_obj_count(translucent)) { - gl_rend_state.enable_blend(); - disp_manager->draw(translucent, 0, true, alpha); - gl_rend_state.disable_blend(); + rend_data_ctx.state.enable_blend(); + disp_manager->draw(rend_data_ctx, translucent, cam, 0, true, alpha); + rend_data_ctx.state.disable_blend(); } - rend->transparency_combine((float_t)alpha * (float_t)(1.0 / 255.0)); + rend->transparency_combine(rend_data_ctx, (float_t)alpha * (float_t)(1.0 / 255.0)); } } static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, - mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent) { + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam) { bool arr[0x100] = { false }; - draw_pass_3d_translucent_has_objects(arr, opaque); - draw_pass_3d_translucent_has_objects(arr, transparent); - draw_pass_3d_translucent_has_objects(arr, translucent); + draw_pass_3d_translucent_has_objects(arr, opaque, cam); + draw_pass_3d_translucent_has_objects(arr, transparent, cam); + draw_pass_3d_translucent_has_objects(arr, translucent, cam); int32_t count = 0; for (int32_t i = 0xFF; i >= 0; i--) @@ -2038,8 +2030,8 @@ static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, return count; } -static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type) { - disp_manager->calc_obj_radius(&rctx->view_mat, type); +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type, cam_data& cam) { + disp_manager->calc_obj_radius(cam, type); for (mdl::ObjData*& i : disp_manager->get_obj_list(type)) switch (i->kind) { case mdl::OBJ_KIND_NORMAL: { @@ -2057,164 +2049,161 @@ static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type) { } } -static void draw_pass_reflect_full(rndr::RenderManager& render_manager) { - gl_rend_state.begin_event("pass_reflect"); +static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::RenderManager& render_manager) { + rend_data_ctx.state.begin_event("pass_reflect"); RenderTexture& refl_tex = reflect_full_ptr->reflect_texture; RenderTexture& refl_buf_tex = reflect_full_ptr->reflect_buffer_texture; - refl_tex.Bind(); + refl_tex.Bind(rend_data_ctx.state); if (draw_pass_reflect_get_obj_reflect_surface() && (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS) || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT))) { - refl_tex.SetViewport(); + refl_tex.SetViewport(rend_data_ctx.state); - draw_pass_set_camera(); if (!sss_data_get()->enable || !sss_data_get()->npr_contour) - glClearDLL(GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_DEPTH_BUFFER_BIT); - gl_rend_state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) - lighting_set((light_set_id)i); + lighting_set(rend_data_ctx, (light_set_id)i); for (int32_t i = FOG_DEPTH; i < FOG_MAX; i++) - fog_set((fog_id)i); + fog_set(rend_data_ctx, (fog_id)i); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); if (disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) - glClearDLL(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); else - glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_func(GL_LEQUAL); - gl_rend_state.set_depth_mask(GL_TRUE); - gl_rend_state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); reflect_draw = true; - draw_state.shader_index = -1; - - int32_t render_width = refl_tex.GetWidth(); - int32_t render_height = refl_tex.GetHeight(); - rctx->set_scene_framebuffer_size(render_width, render_height, render_width, render_height); + rctx->draw_state_rend_data[rend_data_ctx.index].shader_index = -1; if (render_manager.shadow) - draw_pass_3d_shadow_set(render_manager.shadow_ptr); + draw_pass_3d_shadow_set(rend_data_ctx, render_manager.shadow_ptr); else - draw_pass_3d_shadow_reset(); + draw_pass_3d_shadow_reset(rend_data_ctx); if (render_manager.effect_texture) - gl_rend_state.active_bind_texture_2d(14, render_manager.effect_texture->glid); + rend_data_ctx.state.active_bind_texture_2d(14, render_manager.effect_texture->glid); else - gl_rend_state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(14, rctx->empty_texture_2d->glid); - uniform->arr[U_WATER_REFLECT] = 0; + rend_data_ctx.shader_flags.arr[U_WATER_REFLECT] = 0; - sss_data_get()->set_texture(3); + sss_data_get()->set_texture(rend_data_ctx.state, 3); - gl_rend_state.bind_sampler(14, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(15, rctx->render_samplers[0]); - gl_rend_state.bind_sampler(16, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(14, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(15, rctx->render_samplers[0]); + rend_data_ctx.state.bind_sampler(16, rctx->render_samplers[0]); - uniform->arr[U_STAGE_AMBIENT] = render_manager.light_stage_ambient ? 1 : 0; + rend_data_ctx.shader_flags.arr[U_STAGE_AMBIENT] = render_manager.light_stage_ambient ? 1 : 0; - set_reflect_mat(rctx); + cam_data reflect_cam = rctx->render_manager_cam; + set_reflect_mat(rend_data_ctx, reflect_cam); + rend_data_ctx.set_batch_scene_camera(reflect_cam); if (render_manager.alpha_z_sort) { - disp_manager->obj_sort(&rctx->view_mat, - mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, 1, render_manager.field_31F); - disp_manager->obj_sort(&rctx->view_mat, - mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, 2); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, 1, reflect_cam, render_manager.field_31F); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, 2, reflect_cam); } if (render_manager.opaque_z_sort) - disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_REFLECT_OPAQUE, 0); + disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_OPAQUE, 0, reflect_cam); - uniform->arr[U_REFLECT] = 1; + rend_data_ctx.shader_flags.arr[U_REFLECT] = 1; if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE]) { - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_OPAQUE, reflect_cam); + rend_data_ctx.state.disable_depth_test(); } - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_OPAQUE); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_OPAQUE, reflect_cam); - gl_rend_state.enable_depth_test(); - gl_rend_state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSPARENT); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_TRANSPARENT, reflect_cam); if (render_manager.npr_param == 1) - render_manager.pass_3d_contour(); + render_manager.pass_3d_contour(rend_data_ctx); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.disable_depth_test(); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_ALPHA); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_ALPHA, reflect_cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); /*if (npr_param == 1) { - gl_rend_state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); }*/ - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_depth_test(); if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_rend_state.set_depth_mask(GL_FALSE); - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS); - disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); - gl_rend_state.disable_blend(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, reflect_cam); + disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, reflect_cam); + rend_data_ctx.state.disable_blend(); } - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_TYPE_2); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_TYPE_2, reflect_cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.disable_depth_test(); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_NORMAL); - gl_rend_state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_NORMAL, reflect_cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_rend_state.active_bind_texture_2d(14, 0); - gl_rend_state.active_bind_texture_2d(15, 0); + rend_data_ctx.state.active_bind_texture_2d(14, 0); + rend_data_ctx.state.active_bind_texture_2d(15, 0); if (render_manager.shadow) - draw_pass_3d_shadow_reset(); + draw_pass_3d_shadow_reset(rend_data_ctx); - gl_rend_state.set_cull_face_mode(GL_BACK); - gl_rend_state.disable_depth_test(); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); + rend_data_ctx.state.disable_depth_test(); - reflect_full_ptr->dof->apply(&refl_tex, &refl_buf_tex); - - rndr::Render* render = render_manager.render; - rctx->set_scene_framebuffer_size(render->render_width[0], - render->render_height[0], render->render_width[0], render->render_height[0]); + reflect_full_ptr->dof->apply(rend_data_ctx, &refl_tex, &refl_buf_tex); reflect_draw = false; - uniform->arr[U_REFLECT] = 0; + rend_data_ctx.shader_flags.arr[U_REFLECT] = 0; for (int32_t i = render_manager.reflect_blur_num, j = 0; i > 0; i--, j++) { - blur_filter_apply(&refl_buf_tex, &refl_tex, + blur_filter_apply(rend_data_ctx, &refl_buf_tex, &refl_tex, render_manager.reflect_blur_filter, 1.0f, 1.0f, 0.0f); - image_filter_scale(&refl_tex, refl_buf_tex.color_texture); + image_filter_scale(rend_data_ctx, &refl_tex, refl_buf_tex.color_texture); } } else { vec4 clear_color; - glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); - glClearDLL(GL_COLOR_BUFFER_BIT); - glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.get_clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend_data_ctx.state.clear_color(0.0f, 0.0f, 0.0f, 0.0f); + rend_data_ctx.state.clear(GL_COLOR_BUFFER_BIT); + rend_data_ctx.state.clear_color(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } - shader::unbind(); - gl_rend_state.bind_framebuffer(0); - gl_rend_state.end_event(); + shader::unbind(rend_data_ctx.state); + rend_data_ctx.state.bind_framebuffer(0); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_func(GL_LEQUAL); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + rend_data_ctx.state.end_event(); } static bool draw_pass_reflect_get_obj_reflect_surface() { @@ -2250,22 +2239,22 @@ static bool draw_pass_reflect_get_obj_reflect_surface(mdl::ObjType type) { return false; } -static void blur_filter_apply(RenderTexture* dst, RenderTexture* src, +static void blur_filter_apply(render_data_context& rend_data_ctx, RenderTexture* dst, RenderTexture* src, blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset) { if (!dst || !src) return; - gl_rend_state.begin_event("`anonymous-namespace'::Impl::apply_blur_filter_sub"); + rend_data_ctx.state.begin_event("`anonymous-namespace'::Impl::apply_blur_filter_sub"); - dst->Bind(); - dst->SetViewport(); + dst->Bind(rend_data_ctx.state); + dst->SetViewport(rend_data_ctx.state); filter_scene_shader_data filter_scene = {}; float_t w = res_scale.x / (float_t)src->GetWidth(); float_t h = res_scale.y / (float_t)src->GetHeight(); filter_scene.g_transform = { w, h, 0.0f, 0.0f }; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; - rctx->filter_scene_ubo.WriteMemory(filter_scene); + rctx->filter_scene_ubo.WriteMemory(rend_data_ctx.state, filter_scene); imgfilter_batch_shader_data imgfilter_batch = {}; if (filter == BLUR_FILTER_32) @@ -2274,20 +2263,20 @@ static void blur_filter_apply(RenderTexture* dst, RenderTexture* src, imgfilter_batch.g_color_scale = scale * (float_t)(1.0 / 4.0); imgfilter_batch.g_color_offset = offset; imgfilter_batch.g_texture_lod = 0.0f; - rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + rctx->imgfilter_batch_ubo.WriteMemory(rend_data_ctx.state, imgfilter_batch); - uniform->arr[U_IMAGE_FILTER] = filter == BLUR_FILTER_32 ? 1 : 0; - gl_rend_state.bind_vertex_array(rctx->box_vao); - shaders_ft.set(SHADER_FT_IMGFILT); - rctx->filter_scene_ubo.Bind(0); - rctx->imgfilter_batch_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, src->GetColorTex()); - gl_rend_state.bind_sampler(0, rctx->render_samplers[0]); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4); - gl_rend_state.end_event(); + rend_data_ctx.shader_flags.arr[U_IMAGE_FILTER] = filter == BLUR_FILTER_32 ? 1 : 0; + rend_data_ctx.state.bind_vertex_array(rctx->box_vao); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_IMGFILT); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->filter_scene_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, rctx->imgfilter_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, src->GetColorTex()); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[0]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4); + rend_data_ctx.state.end_event(); } -static void fog_set(fog_id id) { +static void fog_set(render_data_context& rend_data_ctx, fog_id id) { fog* f = &fog_data[id]; fog_type type = f->get_type(); if (type == FOG_NONE) @@ -2315,13 +2304,13 @@ static void fog_set(fog_id id) { vec4 color; f->get_color(color); - render_context::fog_params params = {}; - rctx->get_scene_fog_params(params); + render_data_context::fog_params params = {}; + rend_data_ctx.get_scene_fog_params(params); params.density = density; params.start = start; params.end = end; params.depth_color = color; - rctx->set_scene_fog_params(params); + rend_data_ctx.set_scene_fog_params(params); } break; case FOG_HEIGHT: { float_t density = f->get_density(); @@ -2332,14 +2321,14 @@ static void fog_set(fog_id id) { vec4 color; f->get_color(color); - render_context::fog_params params = {}; - rctx->get_scene_fog_params(params); + render_data_context::fog_params params = {}; + rend_data_ctx.get_scene_fog_params(params); params.height_params.x = density; params.height_params.y = start; params.height_params.z = end; params.height_params.w = 1.0f / (end - start); params.height_color = color; - rctx->set_scene_fog_params(params); + rend_data_ctx.set_scene_fog_params(params); } break; case FOG_BUMP: { float_t density = f->get_density(); @@ -2348,13 +2337,13 @@ static void fog_set(fog_id id) { if (start >= end) start = end - 0.01f; - render_context::fog_params params = {}; - rctx->get_scene_fog_params(params); + render_data_context::fog_params params = {}; + rend_data_ctx.get_scene_fog_params(params); params.bump_params.x = density; params.bump_params.y = start; params.bump_params.z = end; params.bump_params.w = 1.0f / (end - start); - rctx->set_scene_fog_params(params); + rend_data_ctx.set_scene_fog_params(params); } break; } } @@ -2385,7 +2374,7 @@ static void light_get_light_color(const light_data* light, light_data_color& val value.specular = light->specular; } -static void lighting_set(light_set_id set_id) { +static void lighting_set(render_data_context& rend_data_ctx, light_set_id set_id) { static const float_t spec_coef = (float_t)(1.0 / (1.0 - cos(18.0 * DEG_TO_RAD))); static const float_t luce_coef = (float_t)(1.0 / (1.0 - cos(45.0 * DEG_TO_RAD))); @@ -2475,7 +2464,7 @@ static void lighting_set(light_set_id set_id) { vec4 chara_f_diffuse; vec4 chara_tc_param; if (set->lights[LIGHT_TONE_CURVE].get_type() == LIGHT_PARALLEL) { - uniform->arr[U_TONE_CURVE] = 1; + rend_data_ctx.shader_flags.arr[U_TONE_CURVE] = 1; set->lights[LIGHT_TONE_CURVE].get_position(chara_f_dir); light_get_direction_from_position(&chara_f_dir, &set->lights[LIGHT_TONE_CURVE]); set->lights[LIGHT_TONE_CURVE].get_ambient(chara_f_ambient); @@ -2493,7 +2482,7 @@ static void lighting_set(light_set_id set_id) { chara_tc_param.w = 0.0f; } else { - uniform->arr[U_TONE_CURVE] = 0; + rend_data_ctx.shader_flags.arr[U_TONE_CURVE] = 0; chara_f_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; chara_f_ambient = 0.0f; chara_f_diffuse = 0.0f; @@ -2558,7 +2547,7 @@ static void lighting_set(light_set_id set_id) { static vec4& npr_cloth_spec_color = *(vec4*)0x0000000140C9B2A0; - rctx->set_scene_light(irradiance_r_transforms, irradiance_g_transforms, irradiance_b_transforms, + rend_data_ctx.set_scene_light(irradiance_r_transforms, irradiance_g_transforms, irradiance_b_transforms, light_env_stage_diffuse, light_env_stage_specular, light_env_chara_diffuse, light_env_chara_ambient, light_env_chara_specular, light_env_reflect_diffuse, light_env_reflect_ambient, @@ -2569,6 +2558,15 @@ static void lighting_set(light_set_id set_id) { chara_color0, chara_color1, chara_f_dir, chara_f_ambient, chara_f_diffuse, chara_tc_param, normal_tangent_transforms, light_reflect_dir, clip_plane, npr_cloth_spec_color); + + extern const GLuint* light_param_data_storage_data_get_ibl_textures(); + const GLuint* textures = light_param_data_storage_data_get_ibl_textures(); + static const int32_t ibl_texture_index[] = { + 9, 10, 11, 12, 13 + }; + + for (int32_t i = 0; i < 5; i++) + rend_data_ctx.state.active_bind_texture_cube_map(ibl_texture_index[i], textures[i]); } static void render_manager_free_render_textures() { @@ -2591,7 +2589,7 @@ static void render_manager_init_render_textures(int32_t multisample) { glGenFramebuffers(1, &render_manager.multisample_framebuffer); glGenRenderbuffers(1, &render_manager.multisample_renderbuffer); - gl_rend_state.bind_framebuffer(render_manager.multisample_framebuffer); + gl_state.bind_framebuffer(render_manager.multisample_framebuffer); glBindRenderbuffer(GL_RENDERBUFFER, render_manager.multisample_renderbuffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, render_manager.width, render_manager.height); @@ -2599,7 +2597,7 @@ static void render_manager_init_render_textures(int32_t multisample) { GL_RENDERBUFFER, render_manager.multisample_renderbuffer); glDrawBufferDLL(GL_COLOR_ATTACHMENT0); glDrawBufferDLL(GL_COLOR_ATTACHMENT0); - gl_rend_state.bind_framebuffer(0); + gl_state.bind_framebuffer(0); glBindRenderbuffer(GL_RENDERBUFFER, 0); if (glGetErrorDLL()) { @@ -2618,16 +2616,16 @@ static void render_manager_init_render_textures(int32_t multisample) { RenderTexture& rt = render_manager.render_textures[i]; rt.Init(tex_data->width, tex_data->height, tex_data->max_level, tex_data->color_format, tex_data->depth_format); - rt.Bind(); + rt.Bind(gl_state); glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - gl_rend_state.bind_framebuffer(0); + gl_state.bind_framebuffer(0); } -static void set_reflect_mat(render_context* rctx) { - const vec3 clip_plane = *(vec3*)&rctx->data.buffer_scene_data.g_clip_plane; - const vec4 temp = 2.0f * rctx->data.buffer_scene_data.g_clip_plane; +static void set_reflect_mat(render_data_context& rend_data_ctx, cam_data& cam) { + const vec3 clip_plane = *(vec3*)&rend_data_ctx.data.buffer_scene_data.g_clip_plane; + const vec4 temp = 2.0f * rend_data_ctx.data.buffer_scene_data.g_clip_plane; reflect_mat = mat4_identity; *(vec3*)&reflect_mat.row0 -= temp.x * clip_plane; @@ -2639,16 +2637,10 @@ static void set_reflect_mat(render_context* rctx) { reflect_mat.row2.w = 0.0f; reflect_mat.row3.w = 1.0f; - mat4 cam_view; - mat4 cam_projection; - mat4_transpose(&camera_data.view, &cam_view); - mat4_transpose(&camera_data.projection, &cam_projection); + mat4_mul(&reflect_mat, &cam.view_mat, &cam.view_mat); + cam.calc_view_proj_mat(); - mat4_mul(&reflect_mat, &cam_view, &rctx->view_mat); - rctx->proj_mat = cam_projection; - mat4_mul(&rctx->view_mat, &rctx->proj_mat, &rctx->vp_mat); - - vec3 view_point = camera_data.view_point; + vec3 view_point = cam.get_view_point(); mat4_transform_point(&reflect_mat, &view_point, &view_point); - rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point); + cam.set_view_point(view_point); } diff --git a/src/DivaGL/render_manager.hpp b/src/DivaGL/render_manager.hpp index 57cc21b..5ed8469 100644 --- a/src/DivaGL/render_manager.hpp +++ b/src/DivaGL/render_manager.hpp @@ -20,12 +20,17 @@ enum draw_pass_3d_type { DRAW_PASS_3D_MAX, }; +typedef void(*draw_pre_process_func)(struct render_data_context& rend_data_ctx, + void* data, const struct cam_data& cam); + struct draw_pre_process { int32_t type; - void(FASTCALL* func)(void*); + draw_pre_process_func func; void* data; }; +struct render_data_context; + namespace rndr { enum RenderPassID { RND_PASSID_SHADOW = 0, @@ -88,7 +93,7 @@ namespace rndr { bool light_stage_ambient; bool npr; - void add_pre_process(int32_t type, void(*func)(void*), void* data); + void add_pre_process(int32_t type, draw_pre_process_func func, void* data); void clear_pre_process(int32_t type); RenderTexture& get_render_texture(int32_t index); void reset(); @@ -109,25 +114,25 @@ namespace rndr { void render_all(); - void render_single_pass(rndr::RenderPassID id); + void render_single_pass(render_data_context& rend_data_ct, rndr::RenderPassID id); void render_pass_begin(); void render_pass_end(rndr::RenderPassID id); - void pass_shadow(); - void pass_ss_sss(); - void pass_reflect(); - void pass_refract(); - void pass_pre_process(); - void pass_clear(); - void pass_pre_sprite(); - void pass_3d(); - void pass_show_vector(); - void pass_post_process(); - void pass_sprite(); + void pass_shadow(render_data_context& rend_data_ct); + void pass_ss_sss(render_data_context& rend_data_ct); + void pass_reflect(render_data_context& rend_data_ct); + void pass_refract(render_data_context& rend_data_ct); + void pass_pre_process(render_data_context& rend_data_ct); + void pass_clear(render_data_context& rend_data_ct); + void pass_pre_sprite(render_data_context& rend_data_ct); + void pass_3d(render_data_context& rend_data_ct); + void pass_show_vector(render_data_context& rend_data_ct); + void pass_post_process(render_data_context& rend_data_ct); + void pass_sprite(render_data_context& rend_data_ct); - void pass_3d_contour(); - void pass_sprite_surf(); + void pass_3d_contour(render_data_context& rend_data_ct); + void pass_sprite_surf(render_data_context& rend_data_ct); }; static_assert(sizeof(rndr::RenderManager) == 0x328, "\"rndr::RenderManager\" struct should have a size of 0x328"); @@ -137,9 +142,8 @@ extern RenderTexture* litproj_shadow; extern RenderTexture* litproj_texture; extern rndr::RenderManager& render_manager; -extern void image_filter_scale(RenderTexture* dst, texture* src, const vec4& scale = 1.0f); - -extern void draw_pass_set_camera(); +extern void image_filter_scale(render_data_context& rend_data_ctx, + RenderTexture* dst, texture* src, const vec4& scale = 1.0f); extern void reflect_full_init(); extern void reflect_full_free(); diff --git a/src/DivaGL/render_texture.cpp b/src/DivaGL/render_texture.cpp index 7134f18..ba9bc13 100644 --- a/src/DivaGL/render_texture.cpp +++ b/src/DivaGL/render_texture.cpp @@ -5,6 +5,7 @@ #include "render_texture.hpp" #include "gl_rend_state.hpp" +#include "gl_state.hpp" #include static uint32_t& render_texture_counter = *(uint32_t*)0x00000001411AD648; @@ -22,11 +23,11 @@ RenderTexture::~RenderTexture() { Free(); } -int32_t RenderTexture::Bind(int32_t index) { +int32_t RenderTexture::Bind(gl_state_struct& gl_st, int32_t index) { if (index < 0 || index > max_level) return -1; - gl_rend_state.bind_framebuffer(fbos[index]); + gl_st.bind_framebuffer(fbos[index]); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return -1; @@ -34,6 +35,19 @@ int32_t RenderTexture::Bind(int32_t index) { return 0; } +int32_t RenderTexture::Bind(p_gl_rend_state& p_gl_rend_st, int32_t index) { + if (index < 0 || index > max_level) + return -1; + + p_gl_rend_st.bind_framebuffer(fbos[index]); + if (p_gl_rend_st.check_framebuffer_status(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + return -1; + + gl_get_error_print(); + return 0; +} + + void RenderTexture::Free() { if (depth_texture) { texture_release(depth_texture); @@ -82,12 +96,12 @@ int32_t RenderTexture::Init(int32_t width, int32_t height, render_texture_counter++; color_texture = GetColorTex(); - gl_rend_state.bind_texture_2d(GetColorTex()); if (color_format == GL_RGBA32F) { + gl_state.bind_texture_2d(GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_state.bind_texture_2d(0); } - gl_rend_state.bind_texture_2d(0); } else { this->color_texture = 0; @@ -150,6 +164,10 @@ int32_t RenderTexture::SetColorDepthTextures(GLuint color_texture, return error; } +void RenderTexture::SetViewport(p_gl_rend_state& p_gl_rend_st) { + p_gl_rend_st.set_viewport(0, 0, GetWidth(), GetHeight()); +} + void render_texture_counter_reset() { render_texture_counter = 0; } @@ -169,7 +187,7 @@ static int32_t render_texture_set_framebuffer_texture(RenderTexture* rt, if (level < 0 || level > rt->max_level) return -1; - gl_rend_state.bind_framebuffer(rt->fbos[level]); + gl_state.bind_framebuffer(rt->fbos[level]); gl_get_error_print(); if (color_texture) { @@ -202,7 +220,7 @@ static int32_t render_texture_set_framebuffer_texture(RenderTexture* rt, int32_t ret = 0; if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) ret = -1; - gl_rend_state.bind_framebuffer(0); + gl_state.bind_framebuffer(0); gl_get_error_print(); return ret; } diff --git a/src/DivaGL/render_texture.hpp b/src/DivaGL/render_texture.hpp index 55b0d3e..3d39839 100644 --- a/src/DivaGL/render_texture.hpp +++ b/src/DivaGL/render_texture.hpp @@ -21,7 +21,8 @@ struct RenderTexture { RenderTexture(); virtual ~RenderTexture(); - int32_t Bind(int32_t index = 0); + int32_t Bind(struct gl_state_struct& gl_st, int32_t index = 0); + int32_t Bind(struct p_gl_rend_state& p_gl_rend_st, int32_t index = 0); void Free(); int32_t Init(int32_t width, int32_t height, int32_t max_level, GLenum color_format, GLenum depth_format); @@ -29,6 +30,7 @@ struct RenderTexture { int32_t InitStencilRenderbuffer(GLenum internal_format, int32_t width, int32_t height);*/ int32_t SetColorDepthTextures(GLuint color_texture, int32_t max_level = 0, GLuint depth_texture = 0, bool stencil = false); + void SetViewport(struct p_gl_rend_state& p_gl_rend_st); inline GLuint GetColorTex() { return color_texture->glid; @@ -45,10 +47,6 @@ struct RenderTexture { inline int32_t GetWidth() { return color_texture->width; }; - - inline void SetViewport() { - gl_rend_state.set_viewport(0, 0, GetWidth(), GetHeight()); - }; }; static_assert(sizeof(RenderTexture) == 0x30, "\"RenderTexture\" struct should have a size of 0x30"); diff --git a/src/DivaGL/renderer/dof.cpp b/src/DivaGL/renderer/dof.cpp index d2a07d3..c8472c7 100644 --- a/src/DivaGL/renderer/dof.cpp +++ b/src/DivaGL/renderer/dof.cpp @@ -7,6 +7,7 @@ #include "../rob/rob.hpp" #include "../camera.hpp" #include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../render_context.hpp" #include "../shader_ft.hpp" #include @@ -37,7 +38,7 @@ namespace renderer { } - void DOF3::apply(RenderTexture* rt, RenderTexture* buf_rt) { + void DOF3::apply(render_data_context& rend_data_ctx, RenderTexture* rt, RenderTexture* buf_rt) { if (dof_debug_data->flags & DOF_DEBUG_USE_UI_PARAMS) { if (dof_debug_data->flags & DOF_DEBUG_ENABLE_DOF) { if (dof_debug_data->flags & DOF_DEBUG_ENABLE_PHYS_DOF) { @@ -65,7 +66,7 @@ namespace renderer { } focus = max_def(focus, camera_data.min_distance); - apply_physical(rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), + apply_physical(rend_data_ctx, rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), camera_data.min_distance, camera_data.max_distance, focus, dof_debug_data->focal_length, camera_data.fov * DEG_TO_RAD_FLOAT, @@ -73,7 +74,7 @@ namespace renderer { } else { float_t fuzzing_range = max_def(dof_debug_data->f2.fuzzing_range, 0.01f); - apply_f2(rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), + apply_f2(rend_data_ctx, rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), camera_data.min_distance, camera_data.max_distance, camera_data.fov * DEG_TO_RAD_FLOAT, dof_debug_data->f2.focus, dof_debug_data->f2.focus_range, @@ -83,7 +84,7 @@ namespace renderer { } else if (dof_pv_data->enable && dof_pv_data->f2.ratio > 0.0f) { float_t fuzzing_range = max_def(dof_pv_data->f2.fuzzing_range, 0.01f); - apply_f2(rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), + apply_f2(rend_data_ctx, rt, buf_rt, rt->GetColorTex(), rt->GetDepthTex(), camera_data.min_distance, camera_data.max_distance, camera_data.fov * DEG_TO_RAD_FLOAT, dof_pv_data->f2.focus, dof_pv_data->f2.focus_range, @@ -142,155 +143,158 @@ namespace renderer { glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - common_ubo.Create(sizeof(dof_common_shader_data)); + common_ubo.Create(gl_state, sizeof(dof_common_shader_data)); vec2 data[50] = {}; renderer::DOF3::calculate_texcoords(data, 3.0f); - texcoords_ubo.Create(sizeof(data), data); + texcoords_ubo.Create(gl_state, sizeof(data), data); glGenVertexArrays(1, &vao); } - void DOF3::apply_f2(RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, + void DOF3::apply_f2(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, float_t min_distance, float_t max_distance, float_t fov, float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio) { - gl_rend_state.begin_event("renderer::DOF3::apply_f2"); - gl_rend_state.disable_blend(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.set_depth_func(GL_ALWAYS); - update_data(min_distance, max_distance, + rend_data_ctx.state.begin_event("renderer::DOF3::apply_f2"); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_func(GL_ALWAYS); + update_data(rend_data_ctx, min_distance, max_distance, fov, focus, 0.0f, 1.0f, focus_range, fuzzing_range, ratio); - uniform->arr[U_DOF] = 1; + rend_data_ctx.shader_flags.arr[U_DOF] = 1; - gl_rend_state.bind_vertex_array(vao); - render_tiles(depth_texture, true); - downsample(color_texture, depth_texture, true); - apply_main_filter(true); - upsample(rt, buf_rt, color_texture, depth_texture, true); + rend_data_ctx.state.bind_vertex_array(vao); + render_tiles(rend_data_ctx, depth_texture, true); + downsample(rend_data_ctx, color_texture, depth_texture, true); + apply_main_filter(rend_data_ctx, true); + upsample(rend_data_ctx, rt, buf_rt, color_texture, depth_texture, true); - gl_rend_state.use_program(0); + rend_data_ctx.state.use_program(0); for (int32_t i = 0; i < 8; i++) { - gl_rend_state.bind_sampler(i, 0); - gl_rend_state.active_bind_texture_2d(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); + rend_data_ctx.state.active_bind_texture_2d(i, 0); } - gl_rend_state.bind_vertex_array(0); - gl_rend_state.end_event(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.end_event(); } - void DOF3::apply_physical(RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, + void DOF3::apply_physical(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, float_t min_distance, float_t max_distance, float_t focus, float_t focal_length, float_t fov, float_t f_number) { - gl_rend_state.begin_event("renderer::DOF3::apply_physical"); - gl_rend_state.disable_blend(); - gl_rend_state.set_depth_mask(GL_FALSE); - gl_rend_state.set_depth_func(GL_ALWAYS); - update_data(min_distance, max_distance, + rend_data_ctx.state.begin_event("renderer::DOF3::apply_physical"); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.set_depth_mask(GL_FALSE); + rend_data_ctx.state.set_depth_func(GL_ALWAYS); + update_data(rend_data_ctx, min_distance, max_distance, fov, focus, focal_length, f_number, 0.0f, 0.1f, 0.0f); - uniform->arr[U_DOF] = 0; + rend_data_ctx.shader_flags.arr[U_DOF] = 0; - gl_rend_state.bind_vertex_array(vao); - render_tiles(depth_texture, false); - downsample(color_texture, depth_texture, false); - apply_main_filter(false); - upsample(rt, buf_rt, color_texture, depth_texture, false); + rend_data_ctx.state.bind_vertex_array(vao); + render_tiles(rend_data_ctx, depth_texture, false); + downsample(rend_data_ctx, color_texture, depth_texture, false); + apply_main_filter(rend_data_ctx, false); + upsample(rend_data_ctx, rt, buf_rt, color_texture, depth_texture, false); - shader::unbind(); + shader::unbind(rend_data_ctx.state); for (int32_t i = 0; i < 8; i++) { - gl_rend_state.bind_sampler(i, 0); - gl_rend_state.active_bind_texture_2d(i, 0); + rend_data_ctx.state.bind_sampler(i, 0); + rend_data_ctx.state.active_bind_texture_2d(i, 0); } - gl_rend_state.bind_vertex_array(0); - gl_rend_state.end_event(); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.end_event(); } - void DOF3::render_tiles(GLuint depth_texture, bool f2) { - gl_rend_state.begin_event("renderer::DOF3::render_tiles"); - fbo[0].bind_buffer(); - gl_rend_state.set_viewport(0, 0, fbo[0].width, fbo[0].height); - uniform->arr[U_DOF_STAGE] = 0; - shaders_ft.set(SHADER_FT_DOF); - common_ubo.Bind(0); - gl_rend_state.active_bind_texture_2d(0, depth_texture); - gl_rend_state.bind_sampler(0, samplers[1]); - glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + void DOF3::render_tiles(render_data_context& rend_data_ctx, GLuint depth_texture, bool f2) { + rend_data_ctx.state.begin_event("renderer::DOF3::render_tiles"); + rend_data_ctx.state.bind_framebuffer(fbo[0].buffer); + rend_data_ctx.state.set_viewport(0, 0, fbo[0].width, fbo[0].height); + rend_data_ctx.shader_flags.arr[U_DOF_STAGE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_DOF); + rend_data_ctx.state.bind_uniform_buffer_base(0, common_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, depth_texture); + rend_data_ctx.state.bind_sampler(0, samplers[1]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - fbo[1].bind_buffer(); - gl_rend_state.set_viewport(0, 0, fbo[1].width, fbo[1].height); - uniform->arr[U_DOF_STAGE] = 1; - shaders_ft.set(SHADER_FT_DOF); - gl_rend_state.active_bind_texture_2d(0, textures[0]); - gl_rend_state.bind_sampler(0, samplers[1]); - glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); + rend_data_ctx.state.bind_framebuffer(fbo[1].buffer); + rend_data_ctx.state.set_viewport(0, 0, fbo[1].width, fbo[1].height); + rend_data_ctx.shader_flags.arr[U_DOF_STAGE] = 1; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_DOF); + rend_data_ctx.state.active_bind_texture_2d(0, textures[0]); + rend_data_ctx.state.bind_sampler(0, samplers[1]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); } - void DOF3::downsample(GLuint color_texture, GLuint depth_texture, bool f2) { - gl_rend_state.begin_event("renderer::DOF3::downsample"); - fbo[2].bind_buffer(); - gl_rend_state.set_viewport(0, 0, fbo[2].width, fbo[2].height); - uniform->arr[U_DOF_STAGE] = 2; - shaders_ft.set(SHADER_FT_DOF); - common_ubo.Bind(0); - gl_rend_state.active_bind_texture_2d(0, depth_texture); - gl_rend_state.bind_sampler(0, samplers[1]); - gl_rend_state.active_bind_texture_2d(1, color_texture); - gl_rend_state.bind_sampler(1, samplers[0]); - gl_rend_state.active_bind_texture_2d(2, textures[1]); - gl_rend_state.bind_sampler(2, samplers[1]); - glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); + void DOF3::downsample(render_data_context& rend_data_ctx, GLuint color_texture, GLuint depth_texture, bool f2) { + rend_data_ctx.state.begin_event("renderer::DOF3::downsample"); + rend_data_ctx.state.bind_framebuffer(fbo[2].buffer); + rend_data_ctx.state.set_viewport(0, 0, fbo[2].width, fbo[2].height); + rend_data_ctx.shader_flags.arr[U_DOF_STAGE] = 2; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_DOF); + rend_data_ctx.state.bind_uniform_buffer_base(0, common_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, depth_texture); + rend_data_ctx.state.bind_sampler(0, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, color_texture); + rend_data_ctx.state.bind_sampler(1, samplers[0]); + rend_data_ctx.state.active_bind_texture_2d(2, textures[1]); + rend_data_ctx.state.bind_sampler(2, samplers[1]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); } - void DOF3::apply_main_filter(bool f2) { - gl_rend_state.begin_event("renderer::DOF3::apply_main_filter"); - fbo[3].bind_buffer(); - gl_rend_state.set_viewport(0, 0, fbo[3].width, fbo[3].height); - uniform->arr[U_DOF_STAGE] = 3; - shaders_ft.set(SHADER_FT_DOF); - common_ubo.Bind(0); - texcoords_ubo.Bind(1); - gl_rend_state.active_bind_texture_2d(0, textures[3]); - gl_rend_state.bind_sampler(0, samplers[1]); - gl_rend_state.active_bind_texture_2d(1, textures[2]); - gl_rend_state.bind_sampler(1, samplers[1]); - gl_rend_state.active_bind_texture_2d(2, textures[1]); - gl_rend_state.bind_sampler(2, samplers[1]); - glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.end_event(); + void DOF3::apply_main_filter(render_data_context& rend_data_ctx, bool f2) { + rend_data_ctx.state.begin_event("renderer::DOF3::apply_main_filter"); + rend_data_ctx.state.bind_framebuffer(fbo[3].buffer); + rend_data_ctx.state.set_viewport(0, 0, fbo[3].width, fbo[3].height); + rend_data_ctx.shader_flags.arr[U_DOF_STAGE] = 3; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_DOF); + rend_data_ctx.state.bind_uniform_buffer_base(0, common_ubo); + rend_data_ctx.state.bind_uniform_buffer_base(1, texcoords_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, textures[3]); + rend_data_ctx.state.bind_sampler(0, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, textures[2]); + rend_data_ctx.state.bind_sampler(1, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(2, textures[1]); + rend_data_ctx.state.bind_sampler(2, samplers[1]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.end_event(); } - void DOF3::upsample(RenderTexture* rt, RenderTexture* buf_rt, + void DOF3::upsample(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, bool f2) { - gl_rend_state.begin_event("renderer::DOF3::upsample"); - buf_rt->Bind(); - gl_rend_state.set_viewport(0, 0, width, height); - uniform->arr[U_DOF_STAGE] = 4; - shaders_ft.set(SHADER_FT_DOF); - common_ubo.Bind(0); - gl_rend_state.active_bind_texture_2d(0, textures[4]); - gl_rend_state.bind_sampler(0, samplers[1]); - gl_rend_state.active_bind_texture_2d(1, textures[5]); - gl_rend_state.bind_sampler(1, samplers[1]); - gl_rend_state.active_bind_texture_2d(2, textures[1]); - gl_rend_state.bind_sampler(2, samplers[1]); - gl_rend_state.active_bind_texture_2d(3, color_texture); - gl_rend_state.bind_sampler(3, samplers[1]); - gl_rend_state.active_bind_texture_2d(4, depth_texture); - gl_rend_state.bind_sampler(4, samplers[1]); - glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.begin_event("renderer::DOF3::upsample"); + buf_rt->Bind(rend_data_ctx.state); + rend_data_ctx.state.set_viewport(0, 0, width, height); + rend_data_ctx.shader_flags.arr[U_DOF_STAGE] = 4; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_DOF); + rend_data_ctx.state.bind_uniform_buffer_base(0, common_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, textures[4]); + rend_data_ctx.state.bind_sampler(0, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(1, textures[5]); + rend_data_ctx.state.bind_sampler(1, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(2, textures[1]); + rend_data_ctx.state.bind_sampler(2, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(3, color_texture); + rend_data_ctx.state.bind_sampler(3, samplers[1]); + rend_data_ctx.state.active_bind_texture_2d(4, depth_texture); + rend_data_ctx.state.bind_sampler(4, samplers[1]); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); if (DIVA_GL_VERSION_4_3) - glCopyImageSubData( + rend_data_ctx.state.copy_image_sub_data( buf_rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); else - fbo_blit(buf_rt->fbos[0], rt->fbos[0], + fbo_blit(rend_data_ctx.state, buf_rt->fbos[0], rt->fbos[0], 0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - gl_rend_state.end_event(); + rend_data_ctx.state.end_event(); } void DOF3::init_textures(int32_t width, int32_t height) { @@ -300,28 +304,29 @@ namespace renderer { int32_t h2 = max_def(height / 2, 1); glGenTextures(6, textures); - gl_rend_state.bind_texture_2d(textures[0]); + gl_state.bind_texture_2d(textures[0]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG16F, w20, h20, 0, GL_RG, GL_HALF_FLOAT, 0); fbo[0].init(w20, h20, &textures[0], 1, 0); - gl_rend_state.bind_texture_2d(textures[1]); + gl_state.bind_texture_2d(textures[1]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG16F, w20, h20, 0, GL_RG, GL_HALF_FLOAT, 0); fbo[1].init(w20, h20, &textures[1], 1, 0); - gl_rend_state.bind_texture_2d(textures[2]); + gl_state.bind_texture_2d(textures[2]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_R11F_G11F_B10F, w2, h2, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 0); - gl_rend_state.bind_texture_2d(textures[3]); + gl_state.bind_texture_2d(textures[3]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_R11F_G11F_B10F, w2, h2, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 0); fbo[2].init(w2, h2, &textures[2], 2, 0); - gl_rend_state.bind_texture_2d(textures[4]); + gl_state.bind_texture_2d(textures[4]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_R11F_G11F_B10F, w2, h2, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 0); - gl_rend_state.bind_texture_2d(textures[5]); + gl_state.bind_texture_2d(textures[5]); glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_R8, w2, h2, 0, GL_RED, GL_UNSIGNED_BYTE, 0); fbo[3].init(w2, h2, &textures[4], 2, 0); } - void DOF3::update_data(float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, + void DOF3::update_data(render_data_context& rend_data_ctx, + float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, float_t f_number, float_t focus_range, float_t fuzzing_range, float_t ratio) { float_t fl = focal_length; if (dist <= focal_length) @@ -341,7 +346,7 @@ namespace renderer { shader_data.g_depth_params2.y = focus_range; shader_data.g_depth_params2.z = -4.5f / (fuzzing_range * fuzzing_range); shader_data.g_depth_params2.w = ratio * 8.0f; - common_ubo.WriteMemory(shader_data); + common_ubo.WriteMemory(rend_data_ctx.state, shader_data); } void DOF3::calculate_texcoords(vec2* data, float_t size) { diff --git a/src/DivaGL/renderer/dof.hpp b/src/DivaGL/renderer/dof.hpp index 626889c..6deb8e4 100644 --- a/src/DivaGL/renderer/dof.hpp +++ b/src/DivaGL/renderer/dof.hpp @@ -43,6 +43,8 @@ struct dof_pv { static_assert(sizeof(dof_pv) == 0x14, "\"dof_pv\" struct should have a size of 0x14"); +struct render_data_context; + namespace renderer { struct DOF3 { int32_t width; @@ -58,28 +60,32 @@ namespace renderer { DOF3(int32_t width, int32_t height); ~DOF3(); - void apply(RenderTexture* rt, RenderTexture* buf_rt); + void apply(render_data_context& rend_data_ctx, RenderTexture* rt, RenderTexture* buf_rt); void resize(int32_t width, int32_t height); private: void free(); void init(int32_t width, int32_t height); - void apply_f2(RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, + void apply_f2(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, float_t min_distance, float_t max_distance, float_t fov, float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio); - void apply_physical(RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, + void apply_physical(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, float_t min_distance, float_t max_distance, float_t focus, float_t focal_length, float_t fov, float_t f_number); - void render_tiles(GLuint depth_texture, bool f2); - void downsample(GLuint color_texture, GLuint depth_texture, bool f2); - void apply_main_filter(bool f2); - void upsample(RenderTexture* rt, RenderTexture* buf_rt, + void render_tiles(render_data_context& rend_data_ctx, GLuint depth_texture, bool f2); + void downsample(render_data_context& rend_data_ctx, GLuint color_texture, GLuint depth_texture, bool f2); + void apply_main_filter(render_data_context& rend_data_ctx, bool f2); + void upsample(render_data_context& rend_data_ctx, + RenderTexture* rt, RenderTexture* buf_rt, GLuint color_texture, GLuint depth_texture, bool f2); void init_textures(int32_t width, int32_t height); - void update_data(float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, + void update_data(render_data_context& rend_data_ctx, + float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, float_t f_number, float_t focus_range, float_t fuzzing_range, float_t ratio); static void calculate_texcoords(vec2* data, float_t size); diff --git a/src/DivaGL/renderer/fbo.cpp b/src/DivaGL/renderer/fbo.cpp index 907c9f4..2079533 100644 --- a/src/DivaGL/renderer/fbo.cpp +++ b/src/DivaGL/renderer/fbo.cpp @@ -5,6 +5,7 @@ #include "fbo.hpp" #include "../../AFTModsShared/types.hpp" +#include "../gl_state.hpp" namespace renderer { FBO::FBO() : flags(), width(), height(), buffer(), count(), textures() { @@ -41,7 +42,7 @@ namespace renderer { textures[count] = depth_texture; glGenFramebuffers(1, &buffer); - gl_rend_state.bind_framebuffer(buffer, true); + gl_state.bind_framebuffer(buffer, true); for (int32_t i = 0; i < count; i++) glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); @@ -53,7 +54,7 @@ namespace renderer { color_attachments[i] = GL_COLOR_ATTACHMENT0 + i; glDrawBuffers(count, color_attachments); glCheckFramebufferStatus(GL_FRAMEBUFFER); - gl_rend_state.bind_framebuffer(0); + gl_state.bind_framebuffer(0); } #pragma warning(pop) diff --git a/src/DivaGL/renderer/fbo.hpp b/src/DivaGL/renderer/fbo.hpp index 62d60ad..14c6aa6 100644 --- a/src/DivaGL/renderer/fbo.hpp +++ b/src/DivaGL/renderer/fbo.hpp @@ -27,10 +27,6 @@ namespace renderer { void init(int32_t width, int32_t height, GLuint* color_textures, int32_t count, GLuint depth_texture); void free(); - - inline void bind_buffer() { - gl_rend_state.bind_framebuffer(buffer); - } }; static_assert(sizeof(renderer::FBO) == 0x20, "\"renderer::FBO\" struct should have a size of 0x20"); diff --git a/src/DivaGL/renderer/transparency.cpp b/src/DivaGL/renderer/transparency.cpp index 60a3e09..0587980 100644 --- a/src/DivaGL/renderer/transparency.cpp +++ b/src/DivaGL/renderer/transparency.cpp @@ -5,8 +5,8 @@ #include "transparency.hpp" #include "../../KKdLib/str_utils.hpp" -#include "../render_context.hpp" #include "../gl_rend_state.hpp" +#include "../render_context.hpp" #include "../shader_ft.hpp" extern render_context* rctx; @@ -39,48 +39,49 @@ namespace renderer { } } - void Transparency::combine(RenderTexture* rt, float_t alpha) { + void Transparency::combine(render_data_context& rend_data_ctx, RenderTexture* rt, float_t alpha) { transparency_batch_shader_data shader_data = {}; shader_data.g_opacity = { alpha, 0.0f, 0.0f, 0.0f }; - rctx->transparency_batch_ubo.WriteMemory(shader_data); + rctx->transparency_batch_ubo.WriteMemory(rend_data_ctx.state, shader_data); - gl_rend_state.disable_blend(); - gl_rend_state.disable_depth_test(); - rctx->render_buffer.Bind(); - shaders_ft.set(SHADER_FT_TRANSPARENCY); - rctx->transparency_batch_ubo.Bind(0); - gl_rend_state.active_bind_texture_2d(0, fbo.textures[0]); - gl_rend_state.active_bind_texture_2d(1, rt->GetColorTex()); - gl_rend_state.bind_vertex_array(vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.disable_depth_test(); + rctx->render_buffer.Bind(rend_data_ctx.state); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_TRANSPARENCY); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->transparency_batch_ubo); + rend_data_ctx.state.active_bind_texture_2d(0, fbo.textures[0]); + rend_data_ctx.state.active_bind_texture_2d(1, rt->GetColorTex()); + rend_data_ctx.state.bind_vertex_array(vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.enable_depth_test(); if (DIVA_GL_VERSION_4_3) - glCopyImageSubData(rctx->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, + rend_data_ctx.state.copy_image_sub_data( + rctx->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); else - fbo_blit(rctx->render_buffer.fbos[0], rt->fbos[0], + fbo_blit(rend_data_ctx.state, rctx->render_buffer.fbos[0], rt->fbos[0], 0, 0, fbo.width, fbo.height, 0, 0, fbo.width, fbo.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } - void Transparency::copy(GLuint texture) { + void Transparency::copy(render_data_context& rend_data_ctx, GLuint texture) { if (DIVA_GL_VERSION_4_3) - glCopyImageSubData(texture, GL_TEXTURE_2D, 0, 0, 0, 0, + rend_data_ctx.state.copy_image_sub_data(texture, GL_TEXTURE_2D, 0, 0, 0, 0, fbo.textures[0], GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); - fbo.bind_buffer(); - gl_rend_state.set_viewport(0, 0, fbo.width, fbo.height); + rend_data_ctx.state.bind_framebuffer(fbo.buffer); + rend_data_ctx.state.set_viewport(0, 0, fbo.width, fbo.height); if (!DIVA_GL_VERSION_4_3) { - gl_rend_state.disable_depth_test(); - uniform->arr[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - gl_rend_state.active_bind_texture_2d(0, texture); - gl_rend_state.bind_sampler(0, rctx->render_samplers[1]); - render_get()->draw_quad(fbo.width, fbo.height, 1.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + rend_data_ctx.state.active_bind_texture_2d(0, texture); + rend_data_ctx.state.bind_sampler(0, rctx->render_samplers[1]); + render_get()->draw_quad(rend_data_ctx, fbo.width, fbo.height, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + rend_data_ctx.state.enable_depth_test(); } } diff --git a/src/DivaGL/renderer/transparency.hpp b/src/DivaGL/renderer/transparency.hpp index 41956b2..9b8d4ec 100644 --- a/src/DivaGL/renderer/transparency.hpp +++ b/src/DivaGL/renderer/transparency.hpp @@ -10,6 +10,8 @@ #include "../render_texture.hpp" #include "fbo.hpp" +struct render_data_context; + namespace renderer { struct Transparency { private: @@ -22,8 +24,8 @@ namespace renderer { Transparency(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height); ~Transparency(); - void combine(RenderTexture* rt, float_t alpha); - void copy(GLuint texture); + void combine(render_data_context& rend_data_ctx, RenderTexture* rt, float_t alpha); + void copy(render_data_context& rend_data_ctx, GLuint texture); void resize(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height); }; diff --git a/src/DivaGL/rob/rob.cpp b/src/DivaGL/rob/rob.cpp index 898aab6..70b7cac 100644 --- a/src/DivaGL/rob/rob.cpp +++ b/src/DivaGL/rob/rob.cpp @@ -6,7 +6,7 @@ #include "rob.hpp" #include "../../KKdLib/str_utils.hpp" #include "../mdl/disp_manager.hpp" -#include "../gl_rend_state.hpp" +#include "../gl_state.hpp" #include "../object.hpp" #include "../render_manager.hpp" #include @@ -146,7 +146,7 @@ HOOK(void, FASTCALL, RobCloth__UpdateVertexBuffer, 0x000000014021CF00, obj_mesh* vertex_buffer->cycle_index(); GL::ArrayBuffer buffer = vertex_buffer->get_buffer(); - size_t data = (size_t)buffer.MapMemory(); + size_t data = (size_t)buffer.MapMemory(gl_state); if (!data) return; @@ -284,7 +284,7 @@ HOOK(void, FASTCALL, RobCloth__UpdateVertexBuffer, 0x000000014021CF00, obj_mesh* break; } - buffer.UnmapMemory(); + buffer.UnmapMemory(gl_state); } HOOK(void, FASTCALL, sub_1405044B0, 0x00000001405044B0, rob_chara* rob_chr) { @@ -754,7 +754,7 @@ void rob_chara_age_age_object::disp(size_t chara_index, obj_vert_buf.cycle_index(); GL::ArrayBuffer buffer = obj_vert_buf.get_buffer(); - size_t vtx_data = (size_t)buffer.MapMemory(); + size_t vtx_data = (size_t)buffer.MapMemory(gl_state); if (!vtx_data) return; @@ -763,7 +763,7 @@ void rob_chara_age_age_object::disp(size_t chara_index, memmove((void*)(vtx_data + vertex_array_size * i), (void*)((size_t)vertex_data + vertex_array_size * v44[i].second), vertex_array_size); - buffer.UnmapMemory(); + buffer.UnmapMemory(gl_state); mesh.num_vertex = disp_count * num_vertex; sub_mesh.num_index = disp_count * num_index; diff --git a/src/DivaGL/screen_shot.cpp b/src/DivaGL/screen_shot.cpp index 5d62088..86df129 100644 --- a/src/DivaGL/screen_shot.cpp +++ b/src/DivaGL/screen_shot.cpp @@ -5,6 +5,7 @@ #include "screen_shot.hpp" #include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "render_context.hpp" #include "shader_ft.hpp" #include "texture.hpp" @@ -62,9 +63,9 @@ HOOK(bool, FASTCALL, sub_1401898E0, 0x00000001401898E0, __int64 a1, texture* tex struc_21 v9 = {}; sub_140188010(&v9, tex->width, tex->height, 1); - gl_rend_state.bind_texture_2d(tex->glid); + gl_state.bind_texture_2d(tex->glid); glGetTexImageDLL(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, sub_140188410(&v9)); - gl_rend_state.bind_texture_2d(0); + gl_state.bind_texture_2d(0); struc_21 v10 = {}; sub_140188100(&v9, sub_140189B10(&v9, &v10, false, true)); @@ -74,20 +75,21 @@ HOOK(bool, FASTCALL, sub_1401898E0, 0x00000001401898E0, __int64 a1, texture* tex return true; } -HOOK(void, FASTCALL, ScreenShotImpl__get_data, 0x0000000140557F50, ScreenShotImpl* impl) { - gl_rend_state.active_bind_texture_2d(0, impl->tex->glid); - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, impl->width, impl->height); +HOOK(void, FASTCALL, ScreenShotImpl__copy, 0x0000000140557F50, ScreenShotImpl* impl) { + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + rend_data_ctx.state.active_bind_texture_2d(0, impl->tex->glid); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, 0, 0, 0, 0, 0, impl->width, impl->height); float_t ratio = (float_t)(impl->curr_height * impl->curr_width) / (float_t)(impl->width * impl->height); float_t scale = 1.0f; if (ratio < 0.1f) - uniform->arr[U_REDUCE] = 1; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 1; else if (ratio < 0.6f) { scale = 0.75f; - uniform->arr[U_REDUCE] = 1; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 1; } else - uniform->arr[U_REDUCE] = 0; + rend_data_ctx.shader_flags.arr[U_REDUCE] = 0; quad_shader_data quad = {}; quad.g_texcoord_modifier = { 0.5f, 0.5f, 0.5f, 0.5f }; @@ -95,23 +97,23 @@ HOOK(void, FASTCALL, ScreenShotImpl__get_data, 0x0000000140557F50, ScreenShotImp quad.g_color = 0.0f; quad.g_texture_lod = 0.0f; - rctx->quad_ubo.WriteMemory(quad); - rctx->quad_ubo.Bind(0); + rctx->quad_ubo.WriteMemory(rend_data_ctx.state, quad); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->quad_ubo); - gl_rend_state.disable_depth_test(); - gl_rend_state.disable_blend(); - gl_rend_state.disable_cull_face(); - gl_rend_state.set_viewport(0, 0, impl->curr_width, impl->curr_height); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.disable_cull_face(); + rend_data_ctx.state.set_viewport(0, 0, impl->curr_width, impl->curr_height); - shaders_ft.set(SHADER_FT_REDUCE); - gl_rend_state.bind_vertex_array(rctx->common_vao); - shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); - gl_rend_state.bind_vertex_array(0); - shader::unbind(); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, SHADER_FT_REDUCE); + rend_data_ctx.state.bind_vertex_array(rctx->common_vao); + rend_data_ctx.state.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + rend_data_ctx.state.bind_vertex_array(0); + shader::unbind(rend_data_ctx.state); - gl_rend_state.enable_cull_face(); - gl_rend_state.enable_blend(); - gl_rend_state.enable_depth_test(); + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.enable_depth_test(); } HOOK(void, FASTCALL, ScreenShotData__get_data, 0x0000000140557BE0, ScreenShotData* data) { @@ -126,6 +128,6 @@ HOOK(void, FASTCALL, ScreenShotData__get_data, 0x0000000140557BE0, ScreenShotDat void screen_shot_patch() { INSTALL_HOOK(sub_1401898E0); - INSTALL_HOOK(ScreenShotImpl__get_data); + INSTALL_HOOK(ScreenShotImpl__copy); INSTALL_HOOK(ScreenShotData__get_data); } diff --git a/src/DivaGL/shader.cpp b/src/DivaGL/shader.cpp index c1d6dda..21a0610 100644 --- a/src/DivaGL/shader.cpp +++ b/src/DivaGL/shader.cpp @@ -27,11 +27,9 @@ 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 bool shader_update_data(shader_set_data* set); - -int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { - set->curr_program = 0; +int32_t shader::bind(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, uint32_t sub_index) { if (num_sub < 1) return -1; @@ -50,7 +48,7 @@ int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { int32_t i = 0; for (i = 0; i < num_uniform; i++) { - const int32_t unival = uniform->arr[use_uniform[i]]; + const int32_t unival = shader_flags.arr[use_uniform[i]]; const int32_t unival_max = max_def(vp_unival_max[i], fp_unival_max[i]); unival_shad += unival_shad_curr * min_def(unival, unival_max); unival_shad_curr *= unival_max + 1; @@ -58,9 +56,7 @@ int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { } GLuint program = sub_shader->programs[unival_shad]; - set->curr_program = program; - - gl_rend_state.use_program(program); + p_gl_rend_st.use_program(program); return 0; } @@ -452,104 +448,14 @@ char* shader::parse_include(char* data, farc* f) { return temp_data; } -void shader::unbind() { - gl_rend_state.use_program(0); +void shader::unbind(p_gl_rend_state& p_gl_rend_st) { + p_gl_rend_st.use_program(0); } -shader_set_data::shader_set_data() : size(), shaders(), curr_program(), -primitive_restart(), primitive_restart_index(), get_index_by_name_func() { +shader_set_data::shader_set_data() : size(), shaders(), get_index_by_name_func() { } -void shader_set_data::disable_primitive_restart() { - primitive_restart = false; -} - -void shader_set_data::draw_arrays(GLenum mode, GLint first, GLsizei count) { - if (!shader_update_data(this)) - return; - - glDrawArraysDLL(mode, first, count); -} - -void shader_set_data::draw_elements(GLenum mode, - GLsizei count, GLenum type, const void* indices) { - switch (mode) { - case GL_TRIANGLE_STRIP: - uint32_t index; - switch (type) { - case GL_UNSIGNED_BYTE: - index = 0xFF; - break; - case GL_UNSIGNED_SHORT: - index = 0xFFFF; - break; - case GL_UNSIGNED_INT: - default: - index = 0xFFFFFFFF; - break; - } - - enable_primitive_restart(); - - if (primitive_restart_index != index) - primitive_restart_index = index; - break; - } - - if (!shader_update_data(this)) - return; - - glDrawElementsDLL(mode, count, type, indices); - - switch (mode) { - case GL_TRIANGLE_STRIP: - disable_primitive_restart(); - break; - } -} - -void shader_set_data::draw_range_elements(GLenum mode, - GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { - switch (mode) { - case GL_TRIANGLE_STRIP: - uint32_t index; - switch (type) { - case GL_UNSIGNED_BYTE: - index = 0xFF; - break; - case GL_UNSIGNED_SHORT: - index = 0xFFFF; - break; - case GL_UNSIGNED_INT: - default: - index = 0xFFFFFFFF; - break; - } - - enable_primitive_restart(); - - if (primitive_restart_index != index) - primitive_restart_index = index; - break; - } - - if (!shader_update_data(this)) - return; - - glDrawRangeElements(mode, start, end, count, type, indices); - - switch (mode) { - case GL_TRIANGLE_STRIP: - disable_primitive_restart(); - break; - } -} - -void shader_set_data::enable_primitive_restart() { - primitive_restart = true; -} - int32_t shader_set_data::get_index_by_name(const char* name) { if (get_index_by_name_func) { int32_t index = get_index_by_name_func(name); @@ -814,13 +720,13 @@ void shader_set_data::load(farc* f, bool ignore_cache, if (programs[k] && samplers.size()) { GLuint program = programs[k]; - gl_rend_state.use_program(program); + glUseProgram(program); for (auto& i : samplers) { GLint loc = glGetUniformLocation(program, i.second.c_str()); if (loc != -1) glUniform1i(loc, i.first); } - gl_rend_state.use_program(0); + glUseProgram(0); } if (programs[k] && uniforms.size()) { @@ -879,13 +785,13 @@ void shader_set_data::load(farc* f, bool ignore_cache, if (programs[0] && samplers.size()) { GLuint program = programs[0]; - gl_rend_state.use_program(program); + glUseProgram(program); for (auto& i : samplers) { GLint loc = glGetUniformLocation(program, i.second.c_str()); if (loc != -1) glUniform1i(loc, i.first); } - gl_rend_state.use_program(0); + glUseProgram(0); } if (programs[0] && uniforms.size()) { @@ -962,16 +868,16 @@ void shader_set_data::load(farc* f, bool ignore_cache, this->get_index_by_name_func = get_index_by_name; } -void shader_set_data::set(uint32_t index) { +void shader_set_data::set(p_gl_rend_state& p_gl_rend_st, uniform_value& shader_flags, uint32_t index) { if (this && index && index != -1) { shader* shader = &shaders[index]; if (shader->bind_func) - shader->bind_func(this, shader); + shader->bind_func(p_gl_rend_st, shader_flags, this, shader); else - shader->bind(this, shader->sub[0].sub_index); + shader->bind(p_gl_rend_st, shader_flags, this, shader->sub[0].sub_index); } else - shader::unbind(); + shader::unbind(p_gl_rend_st); } void shader_set_data::unload() { @@ -1252,17 +1158,3 @@ static bool shader_load_binary_shader(program_binary* bin, GLuint* program, cons } return true; } - -static bool shader_update_data(shader_set_data* set) { - if (!set || !set->curr_program) - return false; - - if (set->primitive_restart) { - gl_rend_state.enable_primitive_restart(); - gl_rend_state.set_primitive_restart_index(set->primitive_restart_index); - } - else - gl_rend_state.disable_primitive_restart(); - - return true; -} diff --git a/src/DivaGL/shader.hpp b/src/DivaGL/shader.hpp index d5d4e95..8d2ad85 100644 --- a/src/DivaGL/shader.hpp +++ b/src/DivaGL/shader.hpp @@ -36,7 +36,8 @@ struct shader_set_data; typedef int32_t (*PFNSHADERGETINDEXFUNCPROC)(const char* name); -typedef void (*PFNSHADERBINDFUNCPROC)(shader_set_data* set, shader* shad); +typedef void (*PFNSHADERBINDFUNCPROC)(struct p_gl_rend_state& p_gl_rend_st, + struct uniform_value& shader_flags, shader_set_data* set, shader* shad); struct shader_bind_func { uint32_t name_index; @@ -59,38 +60,29 @@ struct shader { const uniform_name* use_uniform; PFNSHADERBINDFUNCPROC bind_func; - int32_t bind(shader_set_data* set, uint32_t sub_index); + int32_t bind(struct p_gl_rend_state& p_gl_rend_st, + struct uniform_value& shader_flags, shader_set_data* set, uint32_t sub_index); 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, std::string& temp); static char* parse_include(char* data, farc* f); - static void unbind(); + static void unbind(struct p_gl_rend_state& p_gl_rend_st); }; struct shader_set_data { size_t size; shader* shaders; - GLuint curr_program; - GLboolean primitive_restart; - GLuint primitive_restart_index; PFNSHADERGETINDEXFUNCPROC get_index_by_name_func; shader_set_data(); - void disable_primitive_restart(); - void draw_arrays(GLenum mode, GLint first, GLsizei count); - void draw_elements(GLenum mode, - GLsizei count, GLenum type, const void* indices); - void draw_range_elements(GLenum mode, - GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); - void enable_primitive_restart(); int32_t get_index_by_name(const char* name); void load(farc* f, bool ignore_cache, const char* name, const shader_table* shaders_table, const size_t size, const shader_bind_func* bind_func_table, const size_t bind_func_table_size, PFNSHADERGETINDEXFUNCPROC get_index_by_name); - void set(uint32_t index); + void set(struct p_gl_rend_state& p_gl_rend_st, struct uniform_value& shader_flags, uint32_t index); void unload(); }; diff --git a/src/DivaGL/shader_ft.cpp b/src/DivaGL/shader_ft.cpp index c67674d..7275c3e 100644 --- a/src/DivaGL/shader_ft.cpp +++ b/src/DivaGL/shader_ft.cpp @@ -1261,23 +1261,39 @@ const size_t shader_ft_table_size = sizeof(shader_ft_table) / sizeof(shader_table); static void glass_eye_calc(glass_eye_struct* glass_eye); -static void glass_eye_set(glass_eye_struct* glass_eye); -static void shader_bind_blinn(shader_set_data* set, shader* shad); -static void shader_bind_cloth(shader_set_data* set, shader* shad); -static void shader_bind_hair(shader_set_data* set, shader* shad); -static void shader_bind_glass_eye(shader_set_data* set, shader* shad); -static void shader_bind_tone_map(shader_set_data* set, shader* shad); -static void shader_bind_sss_filter(shader_set_data* set, shader* shad); -static void shader_bind_esm_filter(shader_set_data* set, shader* shad); -static void shader_bind_reduce_tex(shader_set_data* set, shader* shad); -static void shader_bind_magnify(shader_set_data* set, shader* shad); -static void shader_bind_mlaa(shader_set_data* set, shader* shad); -static void shader_bind_exposure(shader_set_data* set, shader* shad); -static void shader_bind_gauss(shader_set_data* set, shader* shad); -static void shader_bind_snow_particle(shader_set_data* set, shader* shad); -static void shader_bind_star(shader_set_data* set, shader* shad); -static void shader_bind_imgfilter(shader_set_data* set, shader* shad); -static void shader_bind_dof(shader_set_data* set, shader* shad); +static void glass_eye_set(p_gl_rend_state& p_gl_rend_st, glass_eye_struct* glass_eye); +static void shader_bind_blinn(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_cloth(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_hair(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_glass_eye(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_tone_map(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_sss_filter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_esm_filter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_reduce_tex(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_magnify(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_mlaa(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_exposure(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_gauss(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_snow_particle(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_star(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_imgfilter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); +static void shader_bind_dof(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad); const shader_bind_func shader_ft_bind_func_table[] = { { @@ -1483,7 +1499,7 @@ static void glass_eye_calc(glass_eye_struct* glass_eye) { glass_eye->tex_offset.w = 0.0f; } -static void glass_eye_set(glass_eye_struct* glass_eye) { +static void glass_eye_set(p_gl_rend_state& p_gl_rend_st, glass_eye_struct* glass_eye) { glass_eye_batch_shader_data glass_eye_batch = {}; vec3 ellipsoid_radius = glass_eye->cornea_radius * glass_eye->cornea_radius; @@ -1530,228 +1546,244 @@ static void glass_eye_set(glass_eye_struct* glass_eye) { glass_eye_batch.g_tex_scale.w = glass_eye->lens_depth; extern render_context* rctx; - rctx->glass_eye_batch_ubo.WriteMemory(glass_eye_batch); - rctx->glass_eye_batch_ubo.Bind(3); + rctx->glass_eye_batch_ubo.WriteMemory(p_gl_rend_st, glass_eye_batch); + p_gl_rend_st.bind_uniform_buffer_base(3, rctx->glass_eye_batch_ubo); } -static void shader_bind_blinn(shader_set_data* set, shader* shad) { - shad->bind(set, uniform->arr[U_NORMAL] +static void shader_bind_blinn(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + shad->bind(p_gl_rend_st, shader_flags, set, shader_flags.arr[U_NORMAL] ? SHADER_FT_SUB_BLINN_FRAG : SHADER_FT_SUB_BLINN_VERT); } -static void shader_bind_cloth(shader_set_data* set, shader* shad) { - shad->bind(set, uniform->arr[U_NPR] ? SHADER_FT_SUB_CLOTH_NPR1 - : (uniform->arr[U_ANISO] ? SHADER_FT_SUB_CLOTH_ANISO : SHADER_FT_SUB_CLOTH_DEFAULT)); +static void shader_bind_cloth(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + shad->bind(p_gl_rend_st, shader_flags, set, shader_flags.arr[U_NPR] ? SHADER_FT_SUB_CLOTH_NPR1 + : (shader_flags.arr[U_ANISO] ? SHADER_FT_SUB_CLOTH_ANISO : SHADER_FT_SUB_CLOTH_DEFAULT)); } -static void shader_bind_hair(shader_set_data* set, shader* shad) { - shad->bind(set, uniform->arr[U_NPR] ? SHADER_FT_SUB_HAIR_NPR1 : SHADER_FT_SUB_HAIR_DEFAULT); +static void shader_bind_hair(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + shad->bind(p_gl_rend_st, shader_flags, set, shader_flags.arr[U_NPR] ? SHADER_FT_SUB_HAIR_NPR1 : SHADER_FT_SUB_HAIR_DEFAULT); } -static void shader_bind_glass_eye(shader_set_data* set, shader* shad) { - uniform->arr[U_EYE_LENS] = 0; - if (set->shaders[SHADER_FT_GLASEYE].bind(set, SHADER_FT_SUB_GLASS_EYE) >= 0) { +static void shader_bind_glass_eye(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + shader_flags.arr[U_EYE_LENS] = 0; + if (set->shaders[SHADER_FT_GLASEYE].bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_GLASS_EYE) >= 0) { glass_eye_calc(&glass_eye); - glass_eye_set(&glass_eye); + glass_eye_set(p_gl_rend_st, &glass_eye); } } -static void shader_bind_tone_map(shader_set_data* set, shader* shad) { - shad->bind(set, uniform->arr[U_NPR] == 1 +static void shader_bind_tone_map(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + shad->bind(p_gl_rend_st, shader_flags, set, shader_flags.arr[U_NPR] == 1 ? SHADER_FT_SUB_TONEMAP_NPR1 : SHADER_FT_SUB_TONEMAP); } -static void shader_bind_sss_filter(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_SSS_FILTER]) { +static void shader_bind_sss_filter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_SSS_FILTER]) { case 0: - shad->bind(set, uniform->arr[U_NPR] + shad->bind(p_gl_rend_st, shader_flags, set, shader_flags.arr[U_NPR] ? SHADER_FT_SUB_SSS_FILTER_MIN_NPR : SHADER_FT_SUB_SSS_FILTER_MIN); break; case 3: - shad->bind(set, SHADER_FT_SUB_SSS_FILTER_GAUSS_2D); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_SSS_FILTER_GAUSS_2D); break; } } -static void shader_bind_esm_filter(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_ESM_FILTER]) { +static void shader_bind_esm_filter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_ESM_FILTER]) { case 0: - shad->bind(set, SHADER_FT_SUB_ESM_FILTER_MIN); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_ESM_FILTER_MIN); break; case 1: - shad->bind(set, SHADER_FT_SUB_ESM_FILTER_EROSION); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_ESM_FILTER_EROSION); break; } } -static void shader_bind_reduce_tex(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_REDUCE]) { +static void shader_bind_reduce_tex(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_REDUCE]) { case 0: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2); break; default: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2_ALPHAMASK); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2_ALPHAMASK); break; } break; case 1: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4); break; } break; case 3: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4_EXTRACT); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4_EXTRACT); break; } break; case 4: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_GHOST); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_GHOST); break; } break; case 5: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_2); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_2); break; } break; case 6: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_BLUR); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_BLUR); break; } break; case 7: - switch (uniform->arr[U_ALPHA_MASK]) { + switch (shader_flags.arr[U_ALPHA_MASK]) { case 0: - shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_4); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_4); break; } break; } } -static void shader_bind_magnify(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_MAGNIFY]) { +static void shader_bind_magnify(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_MAGNIFY]) { case 0: - shad->bind(set, SHADER_FT_SUB_MAGNIFY_LINEAR); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MAGNIFY_LINEAR); break; case 2: - shad->bind(set, SHADER_FT_SUB_MAGNIFY_DIFF); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MAGNIFY_DIFF); break; case 3: - shad->bind(set, SHADER_FT_SUB_MAGNIFY_DIFF2); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MAGNIFY_DIFF2); break; case 4: - shad->bind(set, SHADER_FT_SUB_MAGNIFY_CONE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MAGNIFY_CONE); break; case 5: - shad->bind(set, SHADER_FT_SUB_MAGNIFY_CONE2); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MAGNIFY_CONE2); break; } } -static void shader_bind_mlaa(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_MLAA]) { +static void shader_bind_mlaa(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_MLAA]) { case 0: - shad->bind(set, SHADER_FT_SUB_MLAA_EDGE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MLAA_EDGE); break; case 1: - shad->bind(set, SHADER_FT_SUB_MLAA_AREA); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MLAA_AREA); break; case 2: - shad->bind(set, SHADER_FT_SUB_MLAA_BLEND); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_MLAA_BLEND); break; } } -static void shader_bind_exposure(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_EXPOSURE]) { +static void shader_bind_exposure(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_EXPOSURE]) { case 0: - shad->bind(set, SHADER_FT_SUB_EXPOSURE_MINIFY); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_EXPOSURE_MINIFY); break; case 1: - shad->bind(set, SHADER_FT_SUB_EXPOSURE_MEASURE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_EXPOSURE_MEASURE); break; case 2: - shad->bind(set, SHADER_FT_SUB_EXPOSURE_AVERAGE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_EXPOSURE_AVERAGE); break; } } -static void shader_bind_gauss(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_GAUSS]) { +static void shader_bind_gauss(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_GAUSS]) { case 0: - shad->bind(set, SHADER_FT_SUB_PP_GAUSS_USUAL); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_PP_GAUSS_USUAL); break; case 1: - shad->bind(set, SHADER_FT_SUB_PP_GAUSS_CONE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_PP_GAUSS_CONE); break; } } -static void shader_bind_snow_particle(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_SNOW_PARTICLE]) { +static void shader_bind_snow_particle(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_SNOW_PARTICLE]) { case 0: - shad->bind(set, SHADER_FT_SUB_SNOW_PARTICLE_CPU); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_SNOW_PARTICLE_CPU); break; case 1: - shad->bind(set, SHADER_FT_SUB_SNOW_PARTICLE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_SNOW_PARTICLE); break; } } -static void shader_bind_star(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_STAR]) { +static void shader_bind_star(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_STAR]) { case 0: - shad->bind(set, SHADER_FT_SUB_STAR); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_STAR); break; case 1: - shad->bind(set, SHADER_FT_SUB_STAR_MILKY_WAY); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_STAR_MILKY_WAY); break; } } -static void shader_bind_imgfilter(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_IMAGE_FILTER]) { +static void shader_bind_imgfilter(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_IMAGE_FILTER]) { case 0: - shad->bind(set, SHADER_FT_SUB_BOX4); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_BOX4); break; case 1: - shad->bind(set, SHADER_FT_SUB_BOX8); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_BOX8); break; case 5: - shad->bind(set, SHADER_FT_SUB_COPY); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_COPY); break; } } -static void shader_bind_dof(shader_set_data* set, shader* shad) { - switch (uniform->arr[U_DOF_STAGE]) { +static void shader_bind_dof(p_gl_rend_state& p_gl_rend_st, + uniform_value& shader_flags, shader_set_data* set, shader* shad) { + switch (shader_flags.arr[U_DOF_STAGE]) { case 0: - shad->bind(set, SHADER_FT_SUB_DOF_RENDER_TILE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_DOF_RENDER_TILE); break; case 1: - shad->bind(set, SHADER_FT_SUB_DOF_GATHER_TILE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_DOF_GATHER_TILE); break; case 2: - shad->bind(set, SHADER_FT_SUB_DOF_DOWNSAMPLE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_DOF_DOWNSAMPLE); break; case 3: - shad->bind(set, SHADER_FT_SUB_DOF_MAIN_FILTER); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_DOF_MAIN_FILTER); break; case 4: - shad->bind(set, SHADER_FT_SUB_DOF_UPSAMPLE); + shad->bind(p_gl_rend_st, shader_flags, set, SHADER_FT_SUB_DOF_UPSAMPLE); break; } } diff --git a/src/DivaGL/shadow.cpp b/src/DivaGL/shadow.cpp index bba5b69..140e9b3 100644 --- a/src/DivaGL/shadow.cpp +++ b/src/DivaGL/shadow.cpp @@ -5,8 +5,8 @@ #include "shadow.hpp" #include "../AFTModsShared/light_param/light.hpp" +#include "gl_state.hpp" #include "render_context.hpp" -#include "render_manager.hpp" #include #define MIN_SHADOW_RANGE (1.2f) @@ -25,6 +25,40 @@ static void sub_1405E6840(Shadow* shad); static void sub_1405E6910(Shadow* shad); static void sub_1405E6B70(Shadow* shad); +void Shadow::calc_proj_view_mat(cam_data& cam, const vec3& view_point, + const vec3& interest, float_t range, float_t offset, float_t scale) { + cam.set_view_point(view_point); + cam.set_interest(interest); + + vec3 up = { 0.0f, 1.0f, 0.0f }; + const vec3 dir = interest - view_point; + if (vec3::length_squared(dir) <= 0.000001f) { + up.x = 0.0f; + up.y = 0.0f; + if (dir.z < 0.0f) + up.z = 1.0f; + else + up.z = -1.0f; + } + cam.set_up(up); + + cam.calc_view_mat(); + cam.set_min_distance(z_near); + cam.set_max_distance(z_far); + cam.calc_ortho_proj_mat(-range, range, -range, range, scale, { offset, 0.0f }); + cam.calc_view_proj_mat(); +} + +void Shadow::clear_textures(p_gl_rend_state& p_gl_rend_st) { + for (int32_t i = 1; i < 3; i++) + for (int32_t j = 0; j < 4; j++) { + curr_render_textures[i]->Bind(p_gl_rend_st, j); + p_gl_rend_st.clear_color(1.0f, 1.0f, 1.0f, 1.0f); + p_gl_rend_st.clear(GL_COLOR_BUFFER_BIT); + } + p_gl_rend_st.bind_framebuffer(0); +} + void Shadow::ctrl() { for (int32_t i = 0; i < 2; i++) shadow_enable[i] = false; @@ -79,13 +113,17 @@ int32_t Shadow::init() { return -1; for (int32_t i = 0; i < 3; i++) { - gl_rend_state.bind_texture_2d(render_textures[i].GetColorTex()); + gl_state.bind_texture_2d(render_textures[i].GetColorTex()); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); static const vec4 border_color = 1.0f; glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); } - gl_rend_state.bind_texture_2d(0); + + gl_state.bind_texture_2d(render_textures[0].GetDepthTex()); + GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + gl_state.bind_texture_2d(0); gl_get_error_print(); return 0; } diff --git a/src/DivaGL/shadow.hpp b/src/DivaGL/shadow.hpp index a5df87d..1bedb64 100644 --- a/src/DivaGL/shadow.hpp +++ b/src/DivaGL/shadow.hpp @@ -53,6 +53,9 @@ struct Shadow { bool blur_filter_enable[2]; bool separate; + void calc_proj_view_mat(struct cam_data& cam, const vec3& view_point, + const vec3& interest, float_t range, float_t offset, float_t scale); + void clear_textures(struct p_gl_rend_state& p_gl_rend_st); void ctrl(); void free(); float_t get_shadow_range(); diff --git a/src/DivaGL/shared.cpp b/src/DivaGL/shared.cpp index d651f1d..a435717 100644 --- a/src/DivaGL/shared.cpp +++ b/src/DivaGL/shared.cpp @@ -6,12 +6,12 @@ #include "shared.hpp" #include "gl_rend_state.hpp" -void fbo_blit(GLuint src_fbo, GLuint dst_fbo, +void fbo_blit(p_gl_rend_state& p_gl_rend_st, GLuint src_fbo, GLuint dst_fbo, GLint src_x, GLint src_y, GLint src_width, GLint src_height, GLint dst_x, GLint dst_y, GLint dst_width, GLint dst_height, GLbitfield mask, GLenum filter) { - gl_rend_state.bind_read_framebuffer(src_fbo); - gl_rend_state.bind_draw_framebuffer(dst_fbo); - glBlitFramebuffer(src_x, src_y, src_x + src_width, src_y + src_height, + p_gl_rend_st.bind_read_framebuffer(src_fbo); + p_gl_rend_st.bind_draw_framebuffer(dst_fbo); + p_gl_rend_st.blit_framebuffer(src_x, src_y, src_x + src_width, src_y + src_height, dst_x, dst_y, dst_x + dst_width, dst_y + dst_height, mask, filter); } diff --git a/src/DivaGL/shared.hpp b/src/DivaGL/shared.hpp index e1e1219..6e95e32 100644 --- a/src/DivaGL/shared.hpp +++ b/src/DivaGL/shared.hpp @@ -8,7 +8,7 @@ #include "../AFTModsShared/shared.hpp" #include "wrap.hpp" -extern void fbo_blit(GLuint src_fbo, GLuint dst_fbo, +extern void fbo_blit(struct p_gl_rend_state& p_gl_rend_st, GLuint src_fbo, GLuint dst_fbo, GLint src_x, GLint src_y, GLint src_width, GLint src_height, GLint dst_x, GLint dst_y, GLint dst_width, GLint dst_height, GLbitfield mask, GLenum filter); diff --git a/src/DivaGL/sprite.cpp b/src/DivaGL/sprite.cpp index c0bb9d3..72d39db 100644 --- a/src/DivaGL/sprite.cpp +++ b/src/DivaGL/sprite.cpp @@ -4,6 +4,7 @@ */ #include "sprite.hpp" +#include "gl_state.hpp" #include "render_context.hpp" #include "shader_ft.hpp" #include @@ -93,7 +94,8 @@ namespace spr { mat4 mat; resolution_mode resolution_mode; - void Draw(int32_t index, bool font, texture* overlay_tex); + void Draw(render_data_context& rend_data_ctx, + int32_t index, bool font, texture* overlay_tex); void PostDraw(); void PreDraw(); }; @@ -111,12 +113,13 @@ namespace spr { static void add_draw_sprite(spr::SprArgs** args_array, int32_t count, bool font, spr::SprArgsInner& args_inner, std::vector& draw_param_buffer, std::vector& vertex_buffer, std::vector& index_buffer); - static void draw_sprite(const SprArgs& args, const mat4& mat, + static void draw_sprite(render_data_context& rend_data_ctx, const SprArgs& args, const mat4& mat, int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, texture* overlay_tex); - static void draw_sprite_begin(); - static void draw_sprite_copy_overlay_texture(const SprArgs& args, const mat4& mat, - const vec3* vtx, int32_t overlay_x_min, int32_t overlay_y_min, int32_t overlay_x_max, int32_t overlay_y_max); - static void draw_sprite_end(); + static void draw_sprite_begin(render_data_context& rend_data_ctx); + static void draw_sprite_copy_overlay_texture( + render_data_context& rend_data_ctx, const SprArgs& args, const mat4& mat, const vec3* vtx, + int32_t overlay_x_min, int32_t overlay_y_min, int32_t overlay_x_max, int32_t overlay_y_max); + static void draw_sprite_end(render_data_context& rend_data_ctx); static void draw_sprite_scale(spr::SprArgs* args); } @@ -138,16 +141,16 @@ static const GLenum spr_blend_param[6][4] = { }; namespace spr { - SpriteManager::RenderData::RenderData() { + SpriteManager::RenderData::RenderData() : vao() { glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + gl_state.bind_vertex_array(vao); vbo_vertex_count = 4096; static const GLsizei buffer_size = sizeof(sprite_draw_vertex); - vbo.Create(buffer_size * vbo_vertex_count); - glBindBuffer(GL_ARRAY_BUFFER, vbo); + vbo.Create(gl_state, buffer_size * vbo_vertex_count); + gl_state.bind_array_buffer(vbo, true); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, @@ -161,12 +164,12 @@ namespace spr { ebo_index_count = 4096; - ebo.Create(sizeof(uint32_t) * ebo_index_count); - ebo.Bind(); + ebo.Create(gl_state, sizeof(uint32_t) * ebo_index_count); + gl_state.bind_element_array_buffer(ebo, true); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); + gl_state.bind_element_array_buffer(0); } SpriteManager::RenderData::~RenderData() { @@ -194,10 +197,10 @@ namespace spr { vbo.Destroy(); - glBindVertexArray(vao); + gl_state.bind_vertex_array(vao); - vbo.Create(buffer_size * vbo_vertex_count); - glBindBuffer(GL_ARRAY_BUFFER, vbo); + vbo.Create(gl_state, buffer_size * vbo_vertex_count); + gl_state.bind_array_buffer(vbo, true); glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(buffer_size * vertex_buffer.size()), vertex_buffer.data()); @@ -212,11 +215,11 @@ namespace spr { glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(sprite_draw_vertex, uv)); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + gl_state.bind_array_buffer(0); + gl_state.bind_vertex_array(0); } else - vbo.WriteMemory(0, buffer_size * vertex_buffer.size(), vertex_buffer.data()); + vbo.WriteMemory(gl_state, 0, buffer_size * vertex_buffer.size(), vertex_buffer.data()); if (ebo_index_count < index_buffer.size()) { while (ebo_index_count < index_buffer.size()) @@ -224,23 +227,24 @@ namespace spr { ebo.Destroy(); - glBindVertexArray(vao); + gl_state.bind_vertex_array(vao); - ebo.Create(sizeof(uint32_t) * ebo_index_count); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + ebo.Create(gl_state, sizeof(uint32_t) * ebo_index_count); + gl_state.bind_element_array_buffer(ebo, true); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, (GLsizeiptr)(sizeof(uint32_t) * index_buffer.size()), index_buffer.data()); - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + gl_state.bind_vertex_array(0); + gl_state.bind_element_array_buffer(0); } else - ebo.WriteMemory(0, sizeof(uint32_t) * index_buffer.size(), index_buffer.data()); + ebo.WriteMemory(gl_state, 0, sizeof(uint32_t) * index_buffer.size(), index_buffer.data()); } - void SpriteManager::Draw(int32_t index, bool font, texture* overlay_tex) { - draw_sprite_begin(); + void SpriteManager::Draw(render_data_context& rend_data_ctx, + int32_t index, bool font, texture* overlay_tex) { + draw_sprite_begin(rend_data_ctx); size_t count = 0; for (auto& i : reqlist[index]) @@ -251,7 +255,7 @@ namespace spr { if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) res_window_get()->resolution_mode = resolution_mode; - gl_rend_state_rect viewport_rect = gl_rend_state.get_viewport(); + gl_rend_state_rect viewport_rect = rend_data_ctx.state.get_viewport(); for (int32_t i = 0; i < 2; i++) { auto reqlist = this->reqlist[index][i]; @@ -298,7 +302,7 @@ namespace spr { y_min = (int32_t)min.y; x_max = (int32_t)(max.x - min.x); y_max = (int32_t)(max.y - min.y); - gl_rend_state.set_viewport(x_min, y_min, x_max, y_max); + rend_data_ctx.state.set_viewport(x_min, y_min, x_max, y_max); } else { view_projection = view_projection_aet; @@ -333,23 +337,23 @@ namespace spr { 1.0f / (float_t)overlay_tex->height, 0.0f, 0.0f }; shader_data.g_transform = view_projection; - rctx->sprite_scene_ubo.WriteMemory(shader_data); - rctx->sprite_scene_ubo.Bind(0); + rctx->sprite_scene_ubo.WriteMemory(rend_data_ctx.state, shader_data); + rend_data_ctx.state.bind_uniform_buffer_base(0, rctx->sprite_scene_ubo); RenderData& render_data = *sprite_manager_render_data; - gl_rend_state.bind_vertex_array(render_data.vao); + rend_data_ctx.state.bind_vertex_array(render_data.vao); for (uint32_t j = SPR_PRIO_MAX; j; j--, reqlist++) for (auto& k : *reqlist) if (k.sprite_draw_param_index >= 0) - draw_sprite(k, mat, x_min, y_min, x_max, y_max, overlay_tex); - gl_rend_state.bind_vertex_array(0); + draw_sprite(rend_data_ctx, k, mat, x_min, y_min, x_max, y_max, overlay_tex); + rend_data_ctx.state.bind_vertex_array(0); } if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) res_window_get()->resolution_mode = mode; - draw_sprite_end(); + draw_sprite_end(rend_data_ctx); } void SpriteManager::PostDraw() { @@ -1067,7 +1071,7 @@ namespace spr { args_array[i]->sprite_draw_param_index = -1; } - static void draw_sprite(const SprArgs& args, const mat4& mat, + static void draw_sprite(render_data_context& rend_data_ctx, const SprArgs& args, const mat4& mat, int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, texture* overlay_tex) { sprite_draw_param& draw_param = sprite_manager_render_data->draw_param_buffer.data()[args.sprite_draw_param_index]; @@ -1075,8 +1079,9 @@ namespace spr { int32_t combiner = 0; if (draw_param.attrib.m.enable_blend) { if (draw_param.attrib.m.blend == 5) { - gl_rend_state.active_bind_texture_2d(7, overlay_tex->glid); - draw_sprite_copy_overlay_texture(args, mat, draw_param.vtx, x_min, y_min, x_max, y_max); + rend_data_ctx.state.active_bind_texture_2d(7, overlay_tex->glid); + draw_sprite_copy_overlay_texture(rend_data_ctx, + args, mat, draw_param.vtx, x_min, y_min, x_max, y_max); combiner = 2; } else @@ -1084,11 +1089,11 @@ namespace spr { const GLenum* blend = spr_blend_param[draw_param.attrib.m.blend]; - gl_rend_state.enable_blend(); - gl_rend_state.set_blend_func_separate(blend[0], blend[1], blend[2], blend[3]); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.set_blend_func_separate(blend[0], blend[1], blend[2], blend[3]); } else - gl_rend_state.disable_blend(); + rend_data_ctx.state.disable_blend(); if (draw_param.shader == SHADER_FT_SPRITE) { int32_t tex_0_type = 0; @@ -1111,51 +1116,50 @@ namespace spr { } } - uniform->arr[U_TEX_0_TYPE] = tex_0_type; - uniform->arr[U_TEX_1_TYPE] = tex_1_type; - uniform->arr[U_COMBINER] = combiner; + rend_data_ctx.shader_flags.arr[U_TEX_0_TYPE] = tex_0_type; + rend_data_ctx.shader_flags.arr[U_TEX_1_TYPE] = tex_1_type; + rend_data_ctx.shader_flags.arr[U_COMBINER] = combiner; } if (draw_param.textures[0]) { - gl_rend_state.active_bind_texture_2d(0, draw_param.textures[0]->glid); - gl_rend_state.bind_sampler(0, rctx->sprite_samplers[draw_param.attrib.m.sampler]); + rend_data_ctx.state.active_bind_texture_2d(0, draw_param.textures[0]->glid); + rend_data_ctx.state.bind_sampler(0, rctx->sprite_samplers[draw_param.attrib.m.sampler]); if (draw_param.textures[1]) { - gl_rend_state.active_bind_texture_2d(1, draw_param.textures[1]->glid); - gl_rend_state.bind_sampler(1, rctx->sprite_samplers[draw_param.attrib.m.sampler]); + rend_data_ctx.state.active_bind_texture_2d(1, draw_param.textures[1]->glid); + rend_data_ctx.state.bind_sampler(1, rctx->sprite_samplers[draw_param.attrib.m.sampler]); } - else if (!gl_rend_state.texture_binding_2d[1]) - gl_rend_state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid); + else + rend_data_ctx.state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid); } else { - if (!gl_rend_state.texture_binding_2d[0]) - gl_rend_state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid); - if (!gl_rend_state.texture_binding_2d[1]) - gl_rend_state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid); + rend_data_ctx.state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid); } - shaders_ft.set(draw_param.shader); + shaders_ft.set(rend_data_ctx.state, rend_data_ctx.shader_flags, draw_param.shader); if (draw_param.attrib.m.primitive != GL_TRIANGLES) - shaders_ft.draw_arrays(draw_param.attrib.m.primitive, draw_param.first, draw_param.count); + rend_data_ctx.state.draw_arrays(draw_param.attrib.m.primitive, draw_param.first, draw_param.count); else - shaders_ft.draw_range_elements(draw_param.attrib.m.primitive, draw_param.start, draw_param.end, + rend_data_ctx.state.draw_range_elements(draw_param.attrib.m.primitive, draw_param.start, draw_param.end, draw_param.count, GL_UNSIGNED_INT, (void*)draw_param.offset); } - static void draw_sprite_begin() { - gl_rend_state.disable_blend(true); - gl_rend_state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid, true); - gl_rend_state.bind_sampler(0, 0, true); - gl_rend_state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid, true); - gl_rend_state.bind_sampler(1, 0, true); - gl_rend_state.bind_sampler(7, 0, true); - gl_rend_state.set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO, true); - gl_rend_state.bind_vertex_array(0, true); - gl_rend_state.bind_uniform_buffer_base(0, 0, true); + static void draw_sprite_begin(render_data_context& rend_data_ctx) { + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.active_bind_texture_2d(0, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(0, 0); + rend_data_ctx.state.active_bind_texture_2d(1, rctx->empty_texture_2d->glid); + rend_data_ctx.state.bind_sampler(1, 0); + rend_data_ctx.state.bind_sampler(7, 0); + rend_data_ctx.state.set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + rend_data_ctx.state.bind_vertex_array(0); + rend_data_ctx.state.bind_uniform_buffer_base(0, 0); } - static void draw_sprite_copy_overlay_texture(const SprArgs& args, const mat4& mat, - const vec3* vtx, int32_t overlay_x_min, int32_t overlay_y_min, int32_t overlay_x_max, int32_t overlay_y_max) { + static void draw_sprite_copy_overlay_texture( + render_data_context& rend_data_ctx, const SprArgs& args, const mat4& mat, const vec3* vtx, + int32_t overlay_x_min, int32_t overlay_y_min, int32_t overlay_x_max, int32_t overlay_y_max) { if (args.num_vertex || args.kind != SPR_KIND_NORMAL) return; @@ -1210,21 +1214,21 @@ namespace spr { const int32_t width = x_max - x_min + 1; const int32_t height = y_max - y_min + 1; if (width * height > 0) { - gl_rend_state.active_texture(7); - glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, x_min, y_min, x_min, y_min, width, height); + rend_data_ctx.state.active_texture(7); + rend_data_ctx.state.copy_tex_sub_image_2d(GL_TEXTURE_2D, 0, x_min, y_min, x_min, y_min, width, height); } } - static void draw_sprite_end() { - gl_rend_state.disable_blend(); - gl_rend_state.active_bind_texture_2d(0, 0); - gl_rend_state.bind_sampler(0, 0); - gl_rend_state.active_bind_texture_2d(1, 0); - gl_rend_state.bind_sampler(1, 0); - gl_rend_state.active_bind_texture_2d(7, 0); - gl_rend_state.bind_sampler(7, 0); - gl_rend_state.set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); - shaders_ft.set(-1); + static void draw_sprite_end(render_data_context& rend_data_ctx) { + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.active_bind_texture_2d(0, 0); + rend_data_ctx.state.bind_sampler(0, 0); + rend_data_ctx.state.active_bind_texture_2d(1, 0); + rend_data_ctx.state.bind_sampler(1, 0); + rend_data_ctx.state.active_bind_texture_2d(7, 0); + rend_data_ctx.state.bind_sampler(7, 0); + rend_data_ctx.state.set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + shader::unbind(rend_data_ctx.state); } static void draw_sprite_scale(spr::SprArgs* args) { @@ -1266,8 +1270,9 @@ void sprite_manager_init() { sprite_manager_render_data = new spr::SpriteManager::RenderData; } -void sprite_manager_draw(int32_t index, bool font, texture* overlay_tex) { - sprite_manager->Draw(index, font, overlay_tex); +void sprite_manager_draw(render_data_context& rend_data_ctx, + int32_t index, bool font, texture* overlay_tex) { + sprite_manager->Draw(rend_data_ctx, index, font, overlay_tex); } void sprite_manager_post_draw() { @@ -1308,7 +1313,8 @@ HOOK(void, FASTCALL, spr__SprArgs__Reset, 0x000000014063CA10, spr::SprArgs* This } HOOK(void, FASTCALL, sprite_manager_draw, 0x000000014063F870, int32_t index, bool font, texture* tex) { - sprite_manager_draw(index, font, tex); + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + sprite_manager_draw(rend_data_ctx, index, font, tex); } void sprite_patch() { diff --git a/src/DivaGL/sprite.hpp b/src/DivaGL/sprite.hpp index c1a832d..d33868e 100644 --- a/src/DivaGL/sprite.hpp +++ b/src/DivaGL/sprite.hpp @@ -14,7 +14,8 @@ #include "texture.hpp" extern void sprite_manager_init(); -extern void sprite_manager_draw(int32_t index, bool font, texture* overlay_tex); +extern void sprite_manager_draw(struct render_data_context& rend_data_ctx, + int32_t index, bool font, texture* overlay_tex); extern void sprite_manager_post_draw(); extern void sprite_manager_pre_draw(); extern void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height); diff --git a/src/DivaGL/texture.cpp b/src/DivaGL/texture.cpp index 57e6d58..b2982cc 100644 --- a/src/DivaGL/texture.cpp +++ b/src/DivaGL/texture.cpp @@ -5,7 +5,7 @@ #include "texture.hpp" #include "../AFTModsShared/types.hpp" -#include "gl_rend_state.hpp" +#include "gl_state.hpp" #include "shared.hpp" #include @@ -281,7 +281,7 @@ HOOK(texture*, FASTCALL, texture_load_tex_cube_map, 0x000000014069B860, width, height, max_mipmap_level, data_ptr, false); } -HOOK(texture*, FASTCALL, texture_load_tex_2d, 0x000000014069B8E0, +HOOK(texture*, FASTCALL, texture_load_tex_2d, 0x000000014069B8E0, texture_id id, GLenum internal_format, int32_t width, int32_t height, int32_t max_mipmap_level, const void** data_ptr, bool use_high_anisotropy) { return texture_load_tex(id, GL_TEXTURE_2D, internal_format, @@ -334,10 +334,10 @@ texture_handler::texture_handler() : field_2C(), field_30(), field_34() { inline static void texture_bind(GLenum target, GLuint texture) { switch (target) { case GL_TEXTURE_2D: - gl_rend_state.bind_texture_2d(texture); + gl_state.bind_texture_2d(texture); break; case GL_TEXTURE_CUBE_MAP: - gl_rend_state.bind_texture_cube_map(texture); + gl_state.bind_texture_cube_map(texture); break; } } diff --git a/src/DivaGL/wrap.cpp b/src/DivaGL/wrap.cpp index 6ab99b7..d847e34 100644 --- a/src/DivaGL/wrap.cpp +++ b/src/DivaGL/wrap.cpp @@ -2613,6 +2613,9 @@ PFNWGLGETPROCADDRESSGLUTPROC* divagl_wglGetProcAddressGLUT = 0; PFNWGLMAKECURRENTGLUTPROC* divagl_wglMakeCurrentGLUT = 0; PFNGLTEXPARAMETERIVPROC divagl_glTexParameteriv = 0; +PFNGLSTENCILMASKPROC diva_glStencilMask = 0; +PFNGLSTENCILFUNCPROC diva_glStencilFunc = 0; +PFNGLSTENCILOPPROC diva_glStencilOp = 0; PFNGLDRAWARRAYSINSTANCEDPROC divagl_glDrawArraysInstanced = 0; PFNGLPRIMITIVERESTARTINDEXPROC divagl_glPrimitiveRestartIndex = 0; PFNGLGETUNIFORMBLOCKINDEXPROC divagl_glGetUniformBlockIndex = 0; @@ -2632,6 +2635,8 @@ PFNGLMAPNAMEDBUFFERPROC divagl_glMapNamedBuffer = 0; PFNGLMAPNAMEDBUFFERRANGEPROC divagl_glMapNamedBufferRange = 0; PFNGLUNMAPNAMEDBUFFERPROC divagl_glUnmapNamedBuffer = 0; PFNGLTEXTURESUBIMAGE2DPROC divagl_glTextureSubImage2D = 0; +PFNGLGENERATETEXTUREMIPMAPPROC divagl_glGenerateTextureMipmap = 0; +PFNGLBINDTEXTUREUNITPROC divagl_glBindTextureUnit = 0; PFNGLGETBOOLEANVDLLPROC divagl_glGetBooleanvDLL_orig = 0; PFNGLTEXIMAGE1DDLLPROC divagl_glTexImage1DDLL_orig = 0; @@ -2767,6 +2772,9 @@ HOOK(void, FASTCALL, wglGetProcAddresses, 0x0000000140461B50) { REPLACE_FUNC(glTexImage2DDLL); glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)GetProcAddress((HMODULE)opengl32_handle, "glTexParameteriv"); + glStencilMask = (PFNGLSTENCILMASKPROC)GetProcAddress((HMODULE)opengl32_handle, "glStencilMask"); + glStencilFunc = (PFNGLSTENCILFUNCPROC)GetProcAddress((HMODULE)opengl32_handle, "glStencilFunc"); + glStencilOp = (PFNGLSTENCILOPPROC)GetProcAddress((HMODULE)opengl32_handle, "glStencilOp"); // 3.1 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)wglGetProcAddressDLL("glDrawArraysInstanced"); @@ -2809,6 +2817,8 @@ HOOK(void, FASTCALL, wglGetProcAddresses, 0x0000000140461B50) { glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)wglGetProcAddressDLL("glMapNamedBufferRange"); glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)wglGetProcAddressDLL("glUnmapNamedBuffer"); glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)wglGetProcAddressDLL("glTextureSubImage2D"); + glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)wglGetProcAddressDLL("glGenerateTextureMipmap"); + glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)wglGetProcAddressDLL("glBindTextureUnit"); } #undef REPLACE_FUNC @@ -2827,11 +2837,7 @@ void wrap_patch() { } void GLAPIENTRY glAlphaFuncDLL(GLenum func, GLfloat ref) { - if (func == GL_GREATER && ref >= 0.5f) - uniform->arr[U_ALPHA_TEST] = 1; - else - uniform->arr[U_ALPHA_TEST] = 0; - //((PFNGLALPHAFUNCDLLPROC)wrap_addr_dll[GLALPHAFUNCDLL].orig_func)(func, ref); + ((PFNGLALPHAFUNCDLLPROC)wrap_addr_dll[GLALPHAFUNCDLL].orig_func)(func, ref); } void GLAPIENTRY glBeginDLL(GLenum mode) { diff --git a/src/DivaGL/wrap.hpp b/src/DivaGL/wrap.hpp index fe4fab3..8f6d8cf 100644 --- a/src/DivaGL/wrap.hpp +++ b/src/DivaGL/wrap.hpp @@ -1130,6 +1130,9 @@ typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSGLUTPROC) (LPCSTR lpszProc); typedef BOOL (GLAPIENTRY * PFNWGLMAKECURRENTGLUTPROC) (HDC hDc, HGLRC newContext); typedef void (GLAPIENTRY* PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY* PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAPIENTRY* PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAPIENTRY* PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); typedef void (GLAPIENTRY* PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); typedef void (GLAPIENTRY* PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); typedef GLuint (GLAPIENTRY* PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar* uniformBlockName); @@ -1149,6 +1152,8 @@ typedef void* (GLAPIENTRY* PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access typedef void* (GLAPIENTRY* PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef GLboolean (GLAPIENTRY* PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); typedef void (GLAPIENTRY* PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY* PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture); +typedef void (GLAPIENTRY* PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture); extern PFNGLBINDTEXTUREDLLPROC* divagl_glBindTextureDLL; extern PFNGLBLENDFUNCDLLPROC* divagl_glBlendFuncDLL; @@ -2272,6 +2277,9 @@ extern PFNWGLGETPROCADDRESSGLUTPROC* divagl_wglGetProcAddressGLUT; extern PFNWGLMAKECURRENTGLUTPROC* divagl_wglMakeCurrentGLUT; extern PFNGLTEXPARAMETERIVPROC divagl_glTexParameteriv; +extern PFNGLSTENCILMASKPROC diva_glStencilMask; +extern PFNGLSTENCILFUNCPROC diva_glStencilFunc; +extern PFNGLSTENCILOPPROC diva_glStencilOp; extern PFNGLDRAWARRAYSINSTANCEDPROC divagl_glDrawArraysInstanced; extern PFNGLPRIMITIVERESTARTINDEXPROC divagl_glPrimitiveRestartIndex; extern PFNGLGETUNIFORMBLOCKINDEXPROC divagl_glGetUniformBlockIndex; @@ -2291,6 +2299,8 @@ extern PFNGLMAPNAMEDBUFFERPROC divagl_glMapNamedBuffer; extern PFNGLMAPNAMEDBUFFERRANGEPROC divagl_glMapNamedBufferRange; extern PFNGLUNMAPNAMEDBUFFERPROC divagl_glUnmapNamedBuffer; extern PFNGLTEXTURESUBIMAGE2DPROC divagl_glTextureSubImage2D; +extern PFNGLGENERATETEXTUREMIPMAPPROC divagl_glGenerateTextureMipmap; +extern PFNGLBINDTEXTUREUNITPROC divagl_glBindTextureUnit; #define glBindTextureDLL (*divagl_glBindTextureDLL) #define glBlendFuncDLL (*divagl_glBlendFuncDLL) @@ -3414,6 +3424,9 @@ extern PFNGLTEXTURESUBIMAGE2DPROC divagl_glTextureSubImage2D; #define wglMakeCurrentGLUT (*divagl_wglMakeCurrentGLUT) #define glTexParameteriv divagl_glTexParameteriv +#define glStencilMask diva_glStencilMask +#define glStencilFunc diva_glStencilFunc +#define glStencilOp diva_glStencilOp #define glDrawArraysInstanced divagl_glDrawArraysInstanced #define glPrimitiveRestartIndex divagl_glPrimitiveRestartIndex #define glGetUniformBlockIndex divagl_glGetUniformBlockIndex @@ -3433,6 +3446,8 @@ extern PFNGLTEXTURESUBIMAGE2DPROC divagl_glTextureSubImage2D; #define glMapNamedBufferRange divagl_glMapNamedBufferRange #define glUnmapNamedBuffer divagl_glUnmapNamedBuffer #define glTextureSubImage2D divagl_glTextureSubImage2D +#define glGenerateTextureMipmap divagl_glGenerateTextureMipmap +#define glBindTextureUnit divagl_glBindTextureUnit extern bool DIVA_GL_VERSION_4_1; extern bool DIVA_GL_VERSION_4_2; diff --git a/src/KKdLib b/src/KKdLib index 6b42f33..5be3d43 160000 --- a/src/KKdLib +++ b/src/KKdLib @@ -1 +1 @@ -Subproject commit 6b42f33ae928d5b8b73a535029d33f0f714f0483 +Subproject commit 5be3d4380627f3c3c6fe208de5ce89e1f23504b3