diff --git a/src/CRE/GL/array_buffer.hpp b/src/CRE/GL/array_buffer.hpp index 6cc72f42..672b7286 100644 --- a/src/CRE/GL/array_buffer.hpp +++ b/src/CRE/GL/array_buffer.hpp @@ -4,6 +4,7 @@ */ #pragma once + #include #include "../gl_state.hpp" @@ -92,8 +93,12 @@ namespace GL { if (data) return data; - if (!GLAD_GL_VERSION_4_5) + if (GLAD_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); gl_state_bind_array_buffer(0); + } return 0; } diff --git a/src/CRE/GL/element_array_buffer.hpp b/src/CRE/GL/element_array_buffer.hpp index 9751b8d3..3a654e7a 100644 --- a/src/CRE/GL/element_array_buffer.hpp +++ b/src/CRE/GL/element_array_buffer.hpp @@ -4,6 +4,7 @@ */ #pragma once + #include #include "../gl_state.hpp" @@ -92,8 +93,12 @@ namespace GL { if (data) return data; - if (!GLAD_GL_VERSION_4_5) + if (GLAD_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); gl_state_bind_element_array_buffer(0); + } return 0; } diff --git a/src/CRE/GL/shader_storage_buffer.hpp b/src/CRE/GL/shader_storage_buffer.hpp index a22482b4..414a6575 100644 --- a/src/CRE/GL/shader_storage_buffer.hpp +++ b/src/CRE/GL/shader_storage_buffer.hpp @@ -4,6 +4,7 @@ */ #pragma once + #include #include "../gl_state.hpp" @@ -85,15 +86,19 @@ namespace GL { if (GLAD_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_state_bind_array_buffer(buffer); + gl_state_bind_shader_storage_buffer(buffer); data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); } if (data) return data; - if (!GLAD_GL_VERSION_4_5) - gl_state_bind_array_buffer(0); + if (GLAD_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + gl_state_bind_shader_storage_buffer(0); + } return 0; } @@ -109,7 +114,7 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - gl_state_bind_array_buffer(0); + gl_state_bind_shader_storage_buffer(0); } } diff --git a/src/CRE/GL/uniform_buffer.hpp b/src/CRE/GL/uniform_buffer.hpp index e196dcd7..aed5baa6 100644 --- a/src/CRE/GL/uniform_buffer.hpp +++ b/src/CRE/GL/uniform_buffer.hpp @@ -4,6 +4,7 @@ */ #pragma once + #include #include "../gl_state.hpp" @@ -85,15 +86,19 @@ namespace GL { if (GLAD_GL_VERSION_4_5) data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); else { - gl_state_bind_array_buffer(buffer); + gl_state_bind_uniform_buffer(buffer); data = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); } if (data) return data; - if (!GLAD_GL_VERSION_4_5) - gl_state_bind_array_buffer(0); + if (GLAD_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_UNIFORM_BUFFER); + gl_state_bind_uniform_buffer(0); + } return 0; } @@ -109,7 +114,7 @@ namespace GL { glUnmapNamedBuffer(buffer); else { glUnmapBuffer(GL_UNIFORM_BUFFER); - gl_state_bind_array_buffer(0); + gl_state_bind_uniform_buffer(0); } } diff --git a/src/CRE/Glitter/glitter.hpp b/src/CRE/Glitter/glitter.hpp index 7decf0f9..32efed9d 100644 --- a/src/CRE/Glitter/glitter.hpp +++ b/src/CRE/Glitter/glitter.hpp @@ -427,7 +427,6 @@ namespace Glitter { class F2RenderScene; class XRenderScene; - struct BatchShaderData; class Scene; class GltParticleManager; @@ -1504,13 +1503,6 @@ namespace Glitter { operator uint32_t() const { return (counter << 8) || index; } }; - struct BatchShaderData { - vec4 g_mvp[4]; - vec4 g_glitter_blend_color; - vec4 g_state_material_diffuse; - vec4 g_state_material_emission; - }; - class Scene { public: #if defined(CRE_DEV) @@ -1583,7 +1575,6 @@ namespace Glitter { bool draw_all; bool draw_all_mesh; bool draw_selected; - GL::UniformBuffer batch_ubo; GltParticleManager(); virtual ~GltParticleManager() override; diff --git a/src/CRE/Glitter/particle_manager.cpp b/src/CRE/Glitter/particle_manager.cpp index dd5ad18a..a92c70b0 100644 --- a/src/CRE/Glitter/particle_manager.cpp +++ b/src/CRE/Glitter/particle_manager.cpp @@ -27,12 +27,10 @@ namespace Glitter { draw_all_mesh = true; scenes.reserve(0x100); file_readers.reserve(0x100); - batch_ubo.Create(sizeof(BatchShaderData)); } GltParticleManager::~GltParticleManager() { FreeEffects(); - batch_ubo.Destroy(); } bool GltParticleManager::Init() { diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index d2fe09be..edd34ddd 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -964,7 +964,7 @@ namespace Glitter { if (rend_group->flags & PARTICLE_EMISSION || rend_group->blend_mode == PARTICLE_BLEND_TYPICAL) emission = rend_group->emission; - BatchShaderData shader_data = {}; + glitter_batch_shader_data shader_data = {}; mat4_transpose(&mat, &mat); shader_data.g_mvp[0] = mat.row0; shader_data.g_mvp[1] = mat.row1; @@ -973,7 +973,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 }; - GPM_VAL->batch_ubo.WriteMemory(shader_data); + rctx_ptr->glitter_batch_ubo.WriteMemory(shader_data); GLenum blend_src = GL_SRC_ALPHA; GLenum blend_dst = GL_ONE_MINUS_SRC_ALPHA; @@ -1077,7 +1077,7 @@ namespace Glitter { } shaders_ft.set(SHADER_FT_GLITTER_PT); - GPM_VAL->batch_ubo.Bind(2); + rctx_ptr->glitter_batch_ubo.Bind(2); switch (rend_group->type) { case PARTICLE_QUAD: gl_state_bind_vertex_array(rend_group->vao); @@ -1537,7 +1537,7 @@ namespace Glitter { emit_scale += ext_anim_scale; } - mdl::DispManager& disp_manager = rctx_ptr->disp_manager; + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; disp_manager.set_texture_pattern(0, 0); RenderElement* elem = rend_group->elements; @@ -2098,7 +2098,7 @@ namespace Glitter { if (rend_group->flags & PARTICLE_EMISSION || rend_group->blend_mode == PARTICLE_BLEND_TYPICAL) emission = rend_group->emission; - BatchShaderData shader_data = {}; + glitter_batch_shader_data shader_data = {}; mat4_transpose(&mat, &mat); shader_data.g_mvp[0] = mat.row0; shader_data.g_mvp[1] = mat.row1; @@ -2107,7 +2107,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 }; - GPM_VAL->batch_ubo.WriteMemory(shader_data); + rctx_ptr->glitter_batch_ubo.WriteMemory(shader_data); GLenum blend_src = GL_SRC_ALPHA; GLenum blend_dst = GL_ONE_MINUS_SRC_ALPHA; @@ -2194,7 +2194,7 @@ namespace Glitter { gl_state_disable_cull_face(); shaders_ft.set(SHADER_FT_GLITTER_PT); - GPM_VAL->batch_ubo.Bind(2); + rctx_ptr->glitter_batch_ubo.Bind(2); switch (rend_group->type) { case PARTICLE_QUAD: gl_state_bind_vertex_array(rend_group->vao); diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index 58a429a6..0062e2c7 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -473,7 +473,7 @@ void auth_3d::disp(render_context* rctx) { if (i->active) i->Disp(this, &mat, rctx); - rctx->disp_manager.set_material_list(0, 0); + rctx->disp_manager->set_material_list(0, 0); } void auth_3d::load(a3da* auth_file, @@ -1147,7 +1147,7 @@ namespace auth_3d_detail { return; } - rctx->post_process.tone_map->reset_scene_fade(0); + rctx->render.reset_scene_fade(0); } void EventFilterFade::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { @@ -1168,7 +1168,7 @@ namespace auth_3d_detail { else value.w = 1.0f - t; - rctx->post_process.tone_map->set_scene_fade(value, 0); + rctx->render.set_scene_fade(value, 0); } EventFilterTimeStop::EventFilterTimeStop(a3da_event* e) : Event(e) { @@ -3536,7 +3536,7 @@ static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_fil remove_parent_name.erase(remove_parent_name.begin(), remove_parent_name.begin() + remove_parent_name_size); - + size_t remove_parent_node_size = remove_parent_node.size(); for (size_t i = remove_parent_node_size, i1 = 0; i; i--, i1++) { uint32_t remove_parent_node_hash = hash_string_murmurhash(remove_parent_node[i1]); @@ -3964,7 +3964,7 @@ static void auth_3d_read_file_modern(auth_3d* auth) { } static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx) { - mdl::DispManager& disp_manager = rctx->disp_manager; + mdl::DispManager& disp_manager = *rctx->disp_manager; int32_t mat_list_count = 0; material_list_struct mat_list[TEXTURE_PATTERN_COUNT]; @@ -4076,33 +4076,29 @@ static void auth_3d_camera_auxiliary_load(auth_3d* auth, auth_3d_camera_auxiliar } static void auth_3d_camera_auxiliary_restore_prev_value(auth_3d_camera_auxiliary* ca, render_context* rctx) { - post_process_tone_map* tm = rctx->post_process.tone_map; - if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) - tm->set_auto_exposure(true); + rctx->render.set_auto_exposure(true); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) - tm->set_exposure(2.0); + rctx->render.set_exposure(2.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) - tm->set_gamma(1.0); + rctx->render.set_gamma(1.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) - tm->set_gamma_rate(1.0); + rctx->render.set_gamma_rate(1.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) - tm->set_saturate_coeff(1.0, 0, false); + rctx->render.set_saturate_coeff(1.0, 0, false); } static void auth_3d_camera_auxiliary_set(auth_3d_camera_auxiliary* ca, render_context* rctx) { - post_process_tone_map* tm = rctx->post_process.tone_map; - if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) - tm->set_auto_exposure(ca->auto_exposure_value > 0.0f); + rctx->render.set_auto_exposure(ca->auto_exposure_value > 0.0f); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) - tm->set_exposure(ca->exposure_value); + rctx->render.set_exposure(ca->exposure_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) - tm->set_gamma(ca->gamma_value); + rctx->render.set_gamma(ca->gamma_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) - tm->set_gamma_rate(ca->gamma_rate_value); + rctx->render.set_gamma_rate(ca->gamma_rate_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) - tm->set_saturate_coeff(ca->saturate_value, 0, false); + rctx->render.set_saturate_coeff(ca->saturate_value, 0, false); } static void auth_3d_camera_auxiliary_store(auth_3d* auth, auth_3d_camera_auxiliary_file* caf) { @@ -4698,7 +4694,7 @@ static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, if (!auth->visible || !moh->model_transform.visible) return; - mdl::DispManager& disp_manager = rctx->disp_manager; + mdl::DispManager& disp_manager = *rctx->disp_manager; for (auth_3d_object_instance& i : moh->instance) { if (!i.model_transform.visible) @@ -4716,7 +4712,7 @@ static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, disp_manager.set_obj_flags(flags); disp_manager.set_shadow_type(shadow_type); - Shadow* shad = rctx->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad && flags & mdl::OBJ_SHADOW) { disp_manager.set_shadow_type(SHADOW_STAGE); @@ -6328,7 +6324,7 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context mat4 mat = o->model_transform.mat; - mdl::DispManager& disp_manager = rctx->disp_manager; + mdl::DispManager& disp_manager = *rctx->disp_manager; object_database* obj_db = auth->obj_db; texture_database* tex_db = auth->tex_db; @@ -6379,7 +6375,8 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context texture_transform_struct tex_trans[TEXTURE_TRANSFORM_COUNT]; for (auth_3d_object_texture_transform& i : o->texture_transform) { - if (tex_trans_count >= TEXTURE_TRANSFORM_COUNT) + if (tex_trans_count >= TEXTURE_TRANSFORM_COUNT || i.texture_id == -1 + || !texture_storage_get_texture(i.texture_id)) break; tex_trans[tex_trans_count].id = i.texture_id; @@ -6408,7 +6405,10 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int); object_info obj_info = obj_db->get_object_info(buf); - disp_manager.entry_obj_by_object_info(&mat, obj_info); + if (auth->alpha < 0.999f) + disp_manager.entry_obj_by_object_info(&mat, obj_info, auth->alpha); + else + disp_manager.entry_obj_by_object_info(&mat, obj_info); disp_manager.set_morph({}, 0.0f); } else { @@ -6526,7 +6526,7 @@ static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, rende if (!auth->visible || !oh->node.front().model_transform.visible) return; - mdl::DispManager& disp_manager = rctx->disp_manager; + mdl::DispManager& disp_manager = *rctx->disp_manager; object_database* obj_db = auth->obj_db; texture_database* tex_db = auth->tex_db; @@ -6565,7 +6565,7 @@ static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, rende break; } - Shadow* shad = rctx->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) { vec3 pos = *(vec3*)&m->row3; pos.y -= 0.2f; @@ -7013,47 +7013,41 @@ static void auth_3d_post_process_load(auth_3d* auth, auth_3d_post_process* pp, a } static void auth_3d_post_process_restore_prev_value(auth_3d_post_process* pp, render_context* rctx) { - post_process_blur* blur = rctx->post_process.blur; - post_process_tone_map* tm = rctx->post_process.tone_map; - if (pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY) - blur->set_intensity(pp->intensity_init); + rctx->render.set_intensity(pp->intensity_init); if (pp->flags_init & (AUTH_3D_POST_PROCESS_LENS_FLARE | AUTH_3D_POST_PROCESS_LENS_GHOST | AUTH_3D_POST_PROCESS_LENS_SHAFT)) { - vec3 value = tm->get_lens(); + vec3 value = rctx->render.get_lens(); if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE) value.x = pp->lens_init.x; if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_SHAFT) value.y = pp->lens_init.y; if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_GHOST) value.z = pp->lens_init.z; - tm->set_lens(value); + rctx->render.set_lens(value); } if (pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS) - blur->set_radius(pp->radius_init); + rctx->render.set_radius(pp->radius_init); if (pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE) - tm->set_scene_fade(pp->scene_fade_init, 0); + rctx->render.set_scene_fade(pp->scene_fade_init, 0); } static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* rctx) { - post_process_blur* blur = rctx->post_process.blur; - post_process_tone_map* tm = rctx->post_process.tone_map; - if (pp->flags & AUTH_3D_POST_PROCESS_INTENSITY) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY)) { - pp->intensity_init = blur->get_intensity(); + pp->intensity_init = rctx->render.get_intensity(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_INTENSITY); } - blur->set_intensity(*(vec3*)&pp->intensity.value); + rctx->render.set_intensity(*(vec3*)&pp->intensity.value); } if (pp->flags & (AUTH_3D_POST_PROCESS_LENS_GHOST | AUTH_3D_POST_PROCESS_LENS_SHAFT | AUTH_3D_POST_PROCESS_LENS_FLARE)) { - vec3 value = tm->get_lens(); + vec3 value = rctx->render.get_lens(); if (pp->flags & AUTH_3D_POST_PROCESS_LENS_FLARE) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE)) pp->lens_init.x = value.x; @@ -7071,25 +7065,25 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r pp->lens_init.z = value.z; value.z = pp->lens_value.z; } - tm->set_lens(value); + rctx->render.set_lens(value); } if (pp->flags & AUTH_3D_POST_PROCESS_RADIUS) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS)) { - pp->radius_init = blur->get_radius(); + pp->radius_init = rctx->render.get_radius(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_RADIUS); } - blur->set_radius(*(vec3*)&pp->radius.value); + rctx->render.set_intensity(*(vec3*)&pp->radius.value); } if (pp->flags & AUTH_3D_POST_PROCESS_SCENE_FADE) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE)) { - pp->scene_fade_init = tm->get_scene_fade(); + pp->scene_fade_init = rctx->render.get_scene_fade(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_SCENE_FADE); } - tm->set_scene_fade(pp->scene_fade.value, 0); + rctx->render.set_scene_fade(pp->scene_fade.value, 0); } } diff --git a/src/CRE/clear_color.cpp b/src/CRE/clear_color.cpp index 7f5b8145..d487ab0f 100644 --- a/src/CRE/clear_color.cpp +++ b/src/CRE/clear_color.cpp @@ -4,14 +4,15 @@ */ #include "clear_color.hpp" +#include "gl_state.hpp" color4u8 clear_color; bool set_clear_color; -vec4 get_clear_color() { - if (!set_clear_color) - return 0.0f; - - return clear_color; +void clear_color_set_gl() { + vec4 color = 0.0f; + if (set_clear_color) + color = clear_color; + glClearColor(color.x, color.y, color.z, color.w); } diff --git a/src/CRE/clear_color.hpp b/src/CRE/clear_color.hpp index a2de72c9..b0cc0351 100644 --- a/src/CRE/clear_color.hpp +++ b/src/CRE/clear_color.hpp @@ -12,4 +12,4 @@ extern color4u8 clear_color; extern bool set_clear_color; -extern vec4 get_clear_color(); +extern void clear_color_set_gl(); diff --git a/src/CRE/color.hpp b/src/CRE/color.hpp index b1b7fa25..ff13f1fe 100644 --- a/src/CRE/color.hpp +++ b/src/CRE/color.hpp @@ -18,7 +18,7 @@ struct color4u8 { } - inline color4u8(uint8_t x, uint8_t y, uint8_t z, uint8_t w) : r(x), g(y), b(z), a(w) { + inline color4u8(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) { } diff --git a/src/CRE/fbo.cpp b/src/CRE/fbo.cpp deleted file mode 100644 index 7b142958..00000000 --- a/src/CRE/fbo.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "fbo.hpp" -#include "gl_state.hpp" - -fbo::fbo() : flags(), width(), height(), buffer(), count(), textures() { - -} - -fbo::~fbo() { - free_data(); -} - -#pragma warning(push) -#pragma warning(disable: 6385) -#pragma warning(disable: 6386) -void fbo::init_data(int32_t width, int32_t height, - GLuint* color_textures, int32_t count, GLuint depth_texture) { - if (buffer) { - glDeleteFramebuffers(1, &buffer); - buffer = 0; - } - - if (textures) { - delete[] textures; - textures = 0; - } - - count = min_def(count, 8); - - this->width = width; - this->height = height; - this->count = count; - flags = (fbo_flags)0; - if (depth_texture) { - this->flags = FBO_DEPTH_ATTACHMENT; - this->count++; - } - - textures = new GLuint[this->count]; - for (int32_t i = 0; i < count; i++) - textures[i] = color_textures[i]; - - if (flags & FBO_DEPTH_ATTACHMENT) - textures[count] = depth_texture; - - glGenFramebuffers(1, &buffer); - glBindFramebuffer(GL_FRAMEBUFFER, buffer); - for (int32_t i = 0; i < count; i++) - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); - - if (flags & FBO_DEPTH_ATTACHMENT) - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textures[count], 0); - - GLenum color_attachments[8]; - for (int32_t i = 0; i < count; i++) - color_attachments[i] = GL_COLOR_ATTACHMENT0 + i; - glDrawBuffers(count, color_attachments); - glCheckFramebufferStatus(GL_FRAMEBUFFER); -} -#pragma warning(pop) - -void fbo::free_data() { - if (buffer) { - glDeleteFramebuffers(1, &buffer); - buffer = 0; - } - - if (textures) { - delete[] textures; - textures = 0; - } -} - -void fbo::blit(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_state_bind_read_framebuffer(src_fbo); - gl_state_bind_draw_framebuffer(dst_fbo); - glBlitFramebuffer(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/CRE/fbo.hpp b/src/CRE/fbo.hpp deleted file mode 100644 index 5114b91f..00000000 --- a/src/CRE/fbo.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "shared.hpp" - -enum fbo_flags { - FBO_DEPTH_ATTACHMENT = 0x01, -}; - -struct fbo { - fbo_flags flags; - int32_t width; - int32_t height; - GLuint buffer; - int32_t count; - GLuint* textures; - - fbo(); - ~fbo(); - - void init_data(int32_t width, int32_t height, - GLuint* color_textures, int32_t count, GLuint depth_texture); - void free_data(); - - static void blit(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/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp new file mode 100644 index 00000000..31dbb52b --- /dev/null +++ b/src/CRE/mdl/disp_manager.cpp @@ -0,0 +1,3201 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "disp_manager.hpp" +#include "../../KKdLib/sort.hpp" +#include "../Glitter/glitter.hpp" +#include "../render_context.hpp" +#include "../shader_ft.hpp" +#include "draw_object.hpp" + +extern render_context* rctx_ptr; + +static const GLuint POSITION_INDEX = 0; +static const GLuint BONE_WEIGHT_INDEX = 1; +static const GLuint NORMAL_INDEX = 2; +static const GLuint COLOR0_INDEX = 3; +static const GLuint COLOR1_INDEX = 4; +static const GLuint MORPH_COLOR_INDEX = 5; +static const GLuint TANGENT_INDEX = 6; +static const GLuint UNKNOWN_INDEX = 7; +static const GLuint TEXCOORD0_INDEX = 8; +static const GLuint TEXCOORD1_INDEX = 9; +static const GLuint MORPH_POSITION_INDEX = 10; +static const GLuint MORPH_NORMAL_INDEX = 11; +static const GLuint MORPH_TANGENT_INDEX = 12; +static const GLuint MORPH_TEXCOORD0_INDEX = 13; +static const GLuint MORPH_TEXCOORD1_INDEX = 14; +static const GLuint BONE_INDEX_INDEX = 15; + +static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, + int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]); + +material_list_struct::material_list_struct() : blend_color(), +has_blend_color(), emission(), has_emission() { + hash = (uint32_t)-1; +} + +material_list_struct::material_list_struct(uint32_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission) : hash(hash), blend_color(blend_color), + has_blend_color(has_blend_color), emission(emission), has_emission(has_emission) { + +} + +texture_pattern_struct::texture_pattern_struct() : src(), dst() { + +} + +texture_pattern_struct::texture_pattern_struct(texture_id src, texture_id dst) : src(src), dst(dst) { + +} + +texture_transform_struct::texture_transform_struct() { + id = (uint32_t)-1; + mat = mat4_identity; +} + +texture_transform_struct::texture_transform_struct(uint32_t id, mat4& mat) : id(id), mat(mat) { + +} + +morph_struct::morph_struct() : weight() { + +} + +texture_data_struct::texture_data_struct() : field_0() { + +} + +namespace mdl { + EtcObjTeapot::EtcObjTeapot() { + size = 1.0f; + } + + EtcObjGrid::EtcObjGrid() { + w = 10; + h = 10; + ws = 20; + hs = 20; + } + + EtcObjCube::EtcObjCube() : wire() { + + } + + EtcObjSphere::EtcObjSphere() : wire() { + radius = 1.0f; + slices = 8; + stacks = 8; + } + + EtcObjPlane::EtcObjPlane() { + w = 10; + h = 10; + } + + EtcObjCone::EtcObjCone() : wire() { + base = 1.0f; + height = 1.0f; + slices = 8; + stacks = 8; + } + + EtcObjLine::EtcObjLine() { + pos[0] = { 0.0f, 0.0f, 0.0f }; + pos[1] = { 0.0f, 0.0f, 1.0f }; + } + + EtcObjCross::EtcObjCross() { + size = 0.1f; + } + + EtcObjCapsule::EtcObjCapsule() : wire() { + radius = 1.0f; + slices = 8; + stacks = 8; + pos[0] = { 0.0f, 0.0f, 0.0f }; + pos[1] = { 0.0f, 0.0f, 1.0f }; + } + + EtcObjEllipse::EtcObjEllipse() : wire() { + radius = 1.0f; + slices = 8; + stacks = 8; + pos[0] = { 0.0f, 0.0f, 0.0f }; + pos[1] = { 0.0f, 0.0f, 1.0f }; + } + + EtcObjCylinder::EtcObjCylinder() : wire() { + base = 1.0f; + top = 1.0f; + height = 1.0f; + slices = 8; + stacks = 8; + } + + EtcObj::Data::Data() : capsule() { + + } + + EtcObj::EtcObj() : type(), constant(), count(), offset() { + + } + + void EtcObj::init(EtcObjType type) { + this->type = type; + color = 0xFFFFFFFF; + //fog = false; + constant = false; + switch (type) { + case ETC_OBJ_TEAPOT: + data.teapot = {}; + break; + case ETC_OBJ_GRID: + data.grid = {}; + break; + case ETC_OBJ_CUBE: + data.cube = {}; + break; + case ETC_OBJ_SPHERE: + data.sphere = {}; + break; + case ETC_OBJ_PLANE: + data.plane = {}; + break; + case ETC_OBJ_CONE: + data.cone = {}; + break; + case ETC_OBJ_LINE: + data.line = {}; + break; + case ETC_OBJ_CROSS: + data.cross = {}; + break; + case ETC_OBJ_CAPSULE: // Added + data.capsule = {}; + break; + case ETC_OBJ_ELLIPSE: // Added + data.ellipse = {}; + break; + case ETC_OBJ_CYLINDER: // Added + data.cylinder = {}; + break; + } + } + + void ObjData::init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc) { + kind = mdl::OBJ_KIND_ETC; + this->mat = *mat; + args.etc = *etc; + + disp_manager->add_vertex_array(&args.etc, this->mat); + } + + void ObjData::init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, + obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, + int32_t mat_count, mat4* mats, /*GLuint vertex_buffer, GLuint index_buffer,*/ + obj_mesh_vertex_buffer* vertex_buffer, obj_mesh_index_buffer* index_buffer, vec4* blend_color, + vec4* emission, /*GLuint morph_vertex_buffer,*/ obj_mesh_vertex_buffer* morph_vertex_buffer, + int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)) { + kind = mdl::OBJ_KIND_NORMAL; + this->mat = *mat; + this->radius = radius; + + mdl::ObjSubMeshArgs* args = &this->args.sub_mesh; + args->mesh = mesh; + args->morph_weight = disp_manager->morph.weight; + args->material = material; + args->sub_mesh = sub_mesh; + args->textures = textures; + args->mat_count = mat_count; + args->mats = mats; + args->vertex_buffer = vertex_buffer; + args->index_buffer = index_buffer; + args->morph_vertex_buffer = morph_vertex_buffer; + + args->texture_pattern_count = disp_manager->texture_pattern_count; + for (int32_t i = 0; i < disp_manager->texture_pattern_count && i < TEXTURE_PATTERN_COUNT; i++) + args->texture_pattern_array[i] = disp_manager->texture_pattern_array[i]; + + args->texture_transform_count = disp_manager->texture_transform_count; + for (int32_t i = 0; i < disp_manager->texture_transform_count && i < TEXTURE_TRANSFORM_COUNT; i++) + args->texture_transform_array[i] = disp_manager->texture_transform_array[i]; + + if (blend_color && *blend_color != 1.0f) { + args->set_blend_color = true; + args->blend_color = *blend_color; + } + else { + args->set_blend_color = false; + args->blend_color = 1.0f; + } + + args->emission = *emission; + + args->chara_color = disp_manager->chara_color; + args->self_shadow = disp_manager->obj_flags & (mdl::OBJ_8 | mdl::OBJ_4) ? 1 : 0; + args->shadow = disp_manager->shadow_type; + args->texture_color_coefficients = disp_manager->texture_color_coefficients; + args->texture_color_coefficients.w = disp_manager->wet_param; + args->texture_color_offset = disp_manager->texture_color_offset; + args->texture_specular_coefficients = disp_manager->texture_specular_coefficients; + args->texture_specular_offset = disp_manager->texture_specular_offset; + args->instances_count = instances_count; + args->instances_mat = instances_mat; + args->func = func; + + disp_manager->add_vertex_array(args); + } + + void ObjData::init_translucent(const mat4* mat, ObjTranslucentArgs* translucent) { + kind = mdl::OBJ_KIND_TRANSLUCENT; + this->mat = *mat; + args.translucent = *translucent; + } + + void ObjData::init_user(const mat4* mat, UserArgsFunc func, void* data) { + kind = OBJ_KIND_USER; + this->mat = *mat; + args.user.func = func; + args.user.data = data; + } + + DispManager::DispManager() : obj_flags(), shadow_type(), field_8(), field_C(), + culling(), show_alpha_center(), show_mat_center(), texture_pattern_count(), + texture_pattern_array(), wet_param(), texture_transform_count(), + texture_transform_array(), material_list_count(), material_list_array() { + put_index = -1; + object_culling = true; + object_sort = true; + chara_color = true; + buff_offset = 0; + buff_max = 0; + buff_size = 0x300000; + buff = force_malloc(0x300000); + texture_color_coefficients = 1.0f; + texture_color_offset = 0.0f; + texture_specular_coefficients = 1.0f; + texture_specular_offset = 0.0f; + } + + DispManager::~DispManager() { + for (DispManager::vertex_array& i : vertex_array_cache) + glDeleteVertexArrays(1, &i.vertex_array); + vertex_array_cache.clear(); + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + glDeleteVertexArrays(1, &i.vertex_array); + + i.vertex_buffer.Destroy(); + i.index_buffer.Destroy(); + } + etc_vertex_array_cache.clear(); + + free_def(buff); + } + + void DispManager::add_vertex_array(ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + const obj_material_data* material = args->material; + + //GLuint vertex_buffer = args->vertex_buffer; + obj_mesh_vertex_buffer* vertex_buffer = args->vertex_buffer; + //GLuint morph_vertex_buffer = args->morph_vertex_buffer; + obj_mesh_vertex_buffer* morph_vertex_buffer = args->morph_vertex_buffer; + //GLuint index_buffer = args->index_buffer; + obj_mesh_index_buffer* index_buffer = args->index_buffer; + + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (const obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + + GLuint vertex_attrib_buffer_binding[16] = {}; + object_data_get_vertex_attrib_buffer_bindings(args, + texcoord_array, vertex_attrib_buffer_binding); + + bool compressed = mesh->attrib.m.compressed; + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + DispManager::vertex_array* vertex_array = 0; + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time >= 0 && i.vertex_buffer == vertex_buffer + && i.morph_vertex_buffer == morph_vertex_buffer + && i.index_buffer == index_buffer && i.vertex_format == vertex_format + && i.size_vertex == size_vertex && i.compressed == compressed + && !memcmp(i.vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) + if (i.vertex_array) { + i.alive_time = 60; + return; + } + else { + vertex_array = &i; + break; + } + + if (!vertex_array) + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time <= 0) { + vertex_array = &i; + break; + } + + if (!vertex_array) { + vertex_array_cache.push_back({}); + vertex_array = &vertex_array_cache.back(); + } + + if (!vertex_array->vertex_array) { + glGenVertexArrays(1, &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); + glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + 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); + } + + vertex_array->vertex_buffer = vertex_buffer; + vertex_array->morph_vertex_buffer = morph_vertex_buffer; + vertex_array->index_buffer = index_buffer; + vertex_array->alive_time = 60; + vertex_array->vertex_format = vertex_format; + vertex_array->size_vertex = size_vertex; + vertex_array->compressed = compressed; + memcpy(&vertex_array->texcoord_array, texcoord_array, sizeof(texcoord_array)); + memcpy(&vertex_array->vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)); + + gl_state_bind_vertex_array(vertex_array->vertex_array); + //gl_state_bind_array_buffer(vertex_buffer); + gl_state_bind_array_buffer(vertex_buffer->get_buffer()); + if (index_buffer) + //gl_state_bind_element_array_buffer(index_buffer, true); + gl_state_bind_element_array_buffer(index_buffer->buffer, true); + +#if SHARED_OBJECT_BUFFER + //size_t offset = vertex_buffer_offset; + size_t offset = vertex_buffer->get_offset(); +#else + size_t offset = 0; +#endif + if (vertex_format & OBJ_VERTEX_POSITION) { + if (!vertex_array->vertex_attrib_array[POSITION_INDEX]) { + glEnableVertexAttribArray(POSITION_INDEX); + vertex_array->vertex_attrib_array[POSITION_INDEX] = true; + } + + 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; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + if (!vertex_array->vertex_attrib_array[NORMAL_INDEX]) { + glEnableVertexAttribArray(NORMAL_INDEX); + vertex_array->vertex_attrib_array[NORMAL_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else { + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[NORMAL_INDEX]) { + glDisableVertexAttribArray(NORMAL_INDEX); + vertex_array->vertex_attrib_array[NORMAL_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + if (!vertex_array->vertex_attrib_array[TANGENT_INDEX]) { + glEnableVertexAttribArray(TANGENT_INDEX); + vertex_array->vertex_attrib_array[TANGENT_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else { + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[TANGENT_INDEX]) { + glDisableVertexAttribArray(TANGENT_INDEX); + vertex_array->vertex_attrib_array[TANGENT_INDEX] = false; + } + + if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) + offset += 12; + + for (int32_t i = 0; i < 2; i++) { + int32_t texcoord_index = texcoord_array[i]; + if (texcoord_index < 0) { + if (vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { + glDisableVertexAttribArray(TEXCOORD0_INDEX + i); + vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = false; + } + continue; + } + + if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) { + if (!vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { + glEnableVertexAttribArray(TEXCOORD0_INDEX + i); + vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = true; + } + + if (!compressed) + glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 8ULL * texcoord_index)); + else + glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_HALF_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 4ULL * texcoord_index)); + } + } + + if (!compressed) { + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + } + else { + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 4; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + if (!vertex_array->vertex_attrib_array[COLOR0_INDEX]) { + glEnableVertexAttribArray(COLOR0_INDEX); + vertex_array->vertex_attrib_array[COLOR0_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(COLOR0_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else { + glVertexAttribPointer(COLOR0_INDEX, + 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[COLOR0_INDEX]) { + glDisableVertexAttribArray(COLOR0_INDEX); + vertex_array->vertex_attrib_array[COLOR0_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) + offset += 16; + + if (vertex_format & OBJ_VERTEX_BONE_DATA) { + if (!vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { + glEnableVertexAttribArray(BONE_WEIGHT_INDEX); + vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else { + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_UNSIGNED_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + } + + if (!vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { + glEnableVertexAttribArray(BONE_INDEX_INDEX); + vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = true; + } + + glVertexAttribIPointer(BONE_INDEX_INDEX, + 4, GL_SHORT, size_vertex, (void*)offset); + offset += 8; + } + else { + if (vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { + glDisableVertexAttribArray(BONE_WEIGHT_INDEX); + vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { + glDisableVertexAttribArray(BONE_INDEX_INDEX); + vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = false; + } + } + + if (!compressed && vertex_format & OBJ_VERTEX_UNKNOWN) { + if (!vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { + glEnableVertexAttribArray(UNKNOWN_INDEX); + vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = true; + } + + glVertexAttribPointer(UNKNOWN_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { + glDisableVertexAttribArray(UNKNOWN_INDEX); + vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = false; + } + + if (morph_vertex_buffer) { + //gl_state_bind_array_buffer(morph_vertex_buffer); + gl_state_bind_array_buffer(morph_vertex_buffer->get_buffer()); + +#if SHARED_OBJECT_BUFFER + //size_t offset = morph_vertex_buffer_offset; + size_t offset = morph_vertex_buffer->get_offset(); +#else + size_t offset = 0; +#endif + if (vertex_format & OBJ_VERTEX_POSITION) { + if (!vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glEnableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = true; + } + + glVertexAttribPointer(MORPH_POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glDisableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + if (!vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glEnableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else { + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glDisableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + if (!vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glEnableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else { + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glDisableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; + } + + if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) + offset += 12; + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glEnableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + else { + glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, + 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 4; + } + } + else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glEnableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = true; + } + + if (!compressed) { + glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + else { + glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, + 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 4; + } + } + else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; + } + + if (!compressed) { + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + } + else { + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 4; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + uniform_value[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; + } + + if (!compressed) { + glVertexAttribPointer(MORPH_COLOR_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else { + glVertexAttribPointer(MORPH_COLOR_INDEX, + 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + } + else if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { + glDisableVertexAttribArray(MORPH_COLOR_INDEX); + vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; + } + + if (!compressed) { + if (vertex_format & OBJ_VERTEX_COLOR1) + offset += 16; + + if (vertex_format & OBJ_VERTEX_BONE_DATA) + offset += 32; + + if (vertex_format & OBJ_VERTEX_UNKNOWN) + offset += 16; + } + else { + if (vertex_format & OBJ_VERTEX_BONE_DATA) + offset += 16; + } + } + else { + if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glDisableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glDisableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glDisableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { + glDisableVertexAttribArray(MORPH_COLOR_INDEX); + vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; + } + } + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (index_buffer) + gl_state_bind_element_array_buffer(0); + } + + static void gen_cube_vertices(std::vector& data) { + data.resize(sizeof(vec3) * 2 * 4 * 6); + + vec3* vtx = (vec3*)data.data(); + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + } + + static size_t gen_cube_indices(std::vector& indices) { + const uint32_t sides_indices[] = { + 0, 1, 2, 0, 3, 1, + 4, 5, 6, 6, 7, 4, + 8, 9, 10, 10, 11, 8, + 12, 13, 14, 15, 14, 13, + 16, 17, 18, 18, 19, 16, + 20, 21, 22, 20, 23, 21, + }; + + const uint32_t edges_indices[] = { + 0, 2, 1, 2, 0, 3, 1, 3, + 4, 5, 6, 5, 4, 7, 6, 7, + 0, 4, 1, 6, 2, 5, 3, 7, + }; + + indices.insert(indices.end(), sides_indices, + sides_indices + sizeof(sides_indices) / sizeof(uint32_t)); + + size_t wire_offset = indices.size(); + + indices.insert(indices.end(), edges_indices, + edges_indices + sizeof(edges_indices) / sizeof(uint32_t)); + + return wire_offset; + } + + static void gen_sphere_vertices(std::vector& data, + int32_t slices, int32_t stacks, float_t radius) { + if (slices < 2 || stacks < 2) + return; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(radius); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t slice_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 1; i < stacks; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = xz * cosf(slice_angle); + float_t z = xz * sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y * radius); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-radius); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_sphere_indices(std::vector& indices, + int32_t slices, int32_t stacks) { + if (slices < 2 || stacks < 2) + return 0; + + // Top stack vertices + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Middle stacks vertices + for (int32_t i = 1; i < stacks - 1; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(6LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(j + m2); + + indices.push_back(k + m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Bottom stack vertices + { + int32_t m1 = (stacks - 2) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(m2); + + if (++k >= slices) + k = 0; + } + } + + size_t wire_offset = indices.size(); + + // Top stack wireframe + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(m1); + indices.push_back(j + m2); + } + } + + // Middle stacks wireframe + for (int32_t i = 1; i < stacks - 1; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(j + m2); + } + } + + // Bottom stack wireframe + { + int32_t m1 = (stacks - 2) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(m2); + } + } + + // Slices wireframe + for (int32_t i = 1; i < stacks; i++) { + int32_t m = (i - 1) * slices + 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m); + indices.push_back(k + m); + + if (k++ >= slices) + k = 0; + } + } + + return wire_offset; + } + + static void gen_capsule_vertices(std::vector& data, + int32_t slices, int32_t stacks, float_t length, float_t radius) { + if (slices < 2 || stacks < 2) + return; + + stacks = ((stacks + 1) >> 1) << 1; + + if (length < 0.00001f) { + gen_sphere_vertices(data, slices, stacks, radius); + return; + } + + length *= 0.5f; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(radius + length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t slice_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 1; i <= stacks / 2; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = xz * cosf(slice_angle); + float_t z = xz * sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y + length); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + } + } + + for (int32_t i = stacks / 2; i < stacks; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = xz * cosf(slice_angle); + float_t z = xz * sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y - length); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-radius - length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_capsule_indices(std::vector& indices, + int32_t slices, int32_t stacks, float_t length) { + if (slices < 2 || stacks < 2) + return 0; + + stacks = ((stacks + 1) >> 1) << 1; + + if (length < 0.00001f) + return gen_sphere_indices(indices, slices, stacks); + + // Top stack vertices + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Middle stacks vertices + for (int32_t i = 1; i < stacks; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(6LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(j + m2); + + indices.push_back(k + m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Bottom stack vertices + { + int32_t m1 = (stacks - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(m2); + + if (++k >= slices) + k = 0; + } + } + + size_t wire_offset = indices.size(); + + // Top stack wireframe + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(m1); + indices.push_back(j + m2); + } + } + + // Middle stacks wireframe + for (int32_t i = 1; i < stacks; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(j + m2); + } + } + + // Bottom stack wireframe + { + int32_t m1 = (stacks - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(m2); + } + } + + // Slices wireframe + for (int32_t i = 1; i <= stacks; i++) { + int32_t m = (i - 1) * slices + 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m); + indices.push_back(k + m); + + if (k++ >= slices) + k = 0; + } + } + + return wire_offset; + } + + static void gen_ellipse_vertices(std::vector& data, + int32_t slices, int32_t stacks, float_t length, float_t radius) { + if (slices < 2 || stacks < 2) + return; + + stacks = ((stacks + 1) >> 1) << 1; + + if (length < 0.00001f) { + gen_sphere_vertices(data, slices, stacks, radius); + return; + } + + length *= 0.5f; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(radius + length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t slice_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 1; i < stacks; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + float_t y_n = y; + y *= radius + length; + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = xz * cosf(slice_angle); + float_t z = xz * sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y_n); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-radius - length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_ellipse_indices(std::vector& indices, + int32_t slices, int32_t stacks, float_t length) { + stacks = ((stacks + 1) >> 1) << 1; + + return gen_sphere_indices(indices, slices, stacks); + } + + static void gen_cylinder_vertices(std::vector& data, + int32_t slices, int32_t stacks, float_t base, float_t top, float_t height) { + float_t half_height = height * 0.5f; + + if (slices < 2 || stacks < 0) + return; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(half_height); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t slice_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 0; i <= stacks; i++) { + float_t y = lerp_def(half_height, -half_height, (float_t)i / (float_t)stacks); + float_t radius = lerp_def(top, base, (float_t)i / (float_t)stacks); + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = cosf(slice_angle); + float_t z = sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(0.0f); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-half_height); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_cylinder_indices(std::vector& indices, + int32_t slices, int32_t stacks) { + if (slices < 2 || stacks < 0) + return 0; + + // Top cap vertices + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Stacks vertices + for (int32_t i = 0; i < stacks; i++) { + int32_t m1 = i * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(6LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(j + m2); + + indices.push_back(k + m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Bottom cap vertices + { + int32_t m1 = stacks * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(m2); + + if (++k >= slices) + k = 0; + } + } + + size_t wire_offset = indices.size(); + + // Stacks wireframe + for (int32_t i = 0; i < stacks; i++) { + int32_t m1 = i * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(j + m2); + } + } + + // Slices wireframe + for (int32_t i = 0; i <= stacks; i++) { + int32_t m = i * slices + 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m); + indices.push_back(k + m); + + if (k++ >= slices) + k = 0; + } + } + + return wire_offset; + } + + void DispManager::add_vertex_array(EtcObj* etc, mat4& mat) { + EtcObjType type = etc->type; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + case mdl::ETC_OBJ_CAPSULE: // Added + case mdl::ETC_OBJ_ELLIPSE: // Added + case mdl::ETC_OBJ_CYLINDER: // Added + break; + default: + return; + } + + bool indexed = false; + bool wire = false; + float_t length = 0.0f; + + switch (type) { + case mdl::ETC_OBJ_TEAPOT: { + EtcObjTeapot& teapot = etc->data.teapot; + + indexed = true; + } break; + case mdl::ETC_OBJ_GRID: { + EtcObjGrid& grid = etc->data.grid; + + } break; + case mdl::ETC_OBJ_CUBE: { + EtcObjCube& cube = etc->data.cube; + + vec3 size = cube.size * 0.5f; + mat4_scale_rot(&mat, &size, &mat); + + indexed = true; + wire = cube.wire; + } break; + case mdl::ETC_OBJ_SPHERE: { + EtcObjSphere& sphere = etc->data.sphere; + + indexed = true; + wire = sphere.wire; + } break; + case mdl::ETC_OBJ_PLANE: { + EtcObjPlane& plane = etc->data.plane; + + mat4_scale_rot(&mat, (float_t)plane.w * 0.5f, 1.0f, (float_t)plane.h * 0.5f, &mat); + } break; + case mdl::ETC_OBJ_CONE: { + EtcObjCone& cone = etc->data.cone; + + indexed = true; + wire = cone.wire; + } break; + case mdl::ETC_OBJ_LINE: { + EtcObjLine& line = etc->data.line; + + } break; + case mdl::ETC_OBJ_CROSS: { + EtcObjCross& cross = etc->data.cross; + + mat4_scale_rot(&mat, cross.size, &mat); + } break; + case mdl::ETC_OBJ_CAPSULE: { // Added + EtcObjCapsule& capsule = etc->data.capsule; + + vec3 origin = (capsule.pos[0] + capsule.pos[1]) * 0.5f; + mat4_add_translate(&mat, &origin, &mat); + + vec3 dir = vec3::normalize(capsule.pos[1] - capsule.pos[0]); + vec3 up = { 0.0f, 1.0f, 0.0f }; + vec3 axis; + float_t angle; + Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir); + + mat4 m = mat4_identity; + mat4_mul_rotation(&m, &axis, angle, &m); + mat4_mul(&m, &mat, &mat); + + indexed = true; + wire = capsule.wire; + length = vec3::distance(capsule.pos[0], capsule.pos[1]); + } break; + case mdl::ETC_OBJ_ELLIPSE: { // Added + EtcObjEllipse& ellipse = etc->data.ellipse; + + vec3 origin = (ellipse.pos[0] + ellipse.pos[1]) * 0.5f; + mat4_add_translate(&mat, &origin, &mat); + + vec3 dir = vec3::normalize(ellipse.pos[1] - ellipse.pos[0]); + vec3 up = { 0.0f, 1.0f, 0.0f }; + vec3 axis; + float_t angle; + Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir); + + mat4 m = mat4_identity; + mat4_mul_rotation(&m, &axis, angle, &m); + mat4_mul(&m, &mat, &mat); + + indexed = true; + wire = ellipse.wire; + length = vec3::distance(ellipse.pos[0], ellipse.pos[1]); + } break; + case mdl::ETC_OBJ_CYLINDER: { // Added + EtcObjCylinder& cylinder = etc->data.cylinder; + + indexed = true; + wire = cylinder.wire; + } break; + } + + DispManager::etc_vertex_array* etc_vertex_array = 0; + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type || i.vertex_buffer.IsNull()) + continue; + + if (type == mdl::ETC_OBJ_TEAPOT + || type == mdl::ETC_OBJ_GRID + && !memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid)) + || type == mdl::ETC_OBJ_CUBE + || type == mdl::ETC_OBJ_SPHERE + && i.data.sphere.slices == etc->data.sphere.slices + && i.data.sphere.stacks == etc->data.sphere.stacks + && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f + || type == mdl::ETC_OBJ_PLANE + || type == mdl::ETC_OBJ_CONE + && i.data.cone.slices == etc->data.cone.slices + && i.data.cone.stacks == etc->data.cone.stacks + && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f + && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f + || type == mdl::ETC_OBJ_LINE + || type == mdl::ETC_OBJ_CROSS + || type == mdl::ETC_OBJ_CAPSULE // Added + && i.data.capsule.slices == etc->data.capsule.slices + && ((i.data.capsule.stacks + 1)) >> 1 == ((etc->data.capsule.stacks + 1) >> 1) + && fabsf(i.data.capsule.radius - etc->data.capsule.radius) < 0.00001f + && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f + || type == mdl::ETC_OBJ_ELLIPSE // Added + && i.data.ellipse.slices == etc->data.ellipse.slices + && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) + && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f + && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f + || type == mdl::ETC_OBJ_CYLINDER // Added + && i.data.cylinder.slices == etc->data.cylinder.slices + && i.data.cylinder.stacks == etc->data.cylinder.stacks + && fabsf(i.data.cylinder.base - etc->data.cylinder.base) < 0.00001f + && fabsf(i.data.cylinder.top - etc->data.cylinder.top) < 0.00001f + && fabsf(i.data.cylinder.height - etc->data.cylinder.height) < 0.00001f) + if (i.vertex_array) { + i.alive_time = 2; + if (!wire) { + etc->count = i.count; + etc->offset = i.offset; + } + else { + etc->count = i.wire_count; + etc->offset = i.wire_offset; + } + return; + } + else { + etc_vertex_array = &i; + break; + } + } + + if (!etc_vertex_array) + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time <= 0) { + etc_vertex_array = &i; + break; + } + + if (!etc_vertex_array) { + etc_vertex_array_cache.push_back({}); + etc_vertex_array = &etc_vertex_array_cache.back(); + } + + if (!etc_vertex_array->vertex_array) { + glGenVertexArrays(1, &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); + glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + 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); + } + + etc_vertex_array->alive_time = 2; + etc_vertex_array->data = etc->data; + etc_vertex_array->type = type; + + std::vector vtx_data; + std::vector vtx_indices; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: { + EtcObjTeapot& teapot = etc->data.teapot; + + etc_vertex_array->count = (GLsizei)vtx_indices.size(); + } break; + case mdl::ETC_OBJ_GRID: { + EtcObjGrid& grid = etc->data.grid; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CUBE: { + EtcObjCube& cube = etc->data.cube; + + gen_cube_vertices(vtx_data); + size_t wire_offset = gen_cube_indices(vtx_indices); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_SPHERE: { + EtcObjSphere& sphere = etc->data.sphere; + + gen_sphere_vertices(vtx_data, sphere.slices, sphere.stacks, sphere.radius); + size_t wire_offset = gen_sphere_indices(vtx_indices, sphere.slices, sphere.stacks); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_PLANE: { + EtcObjPlane& plane = etc->data.plane; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CONE: { + EtcObjCone& cone = etc->data.cone; + + etc_vertex_array->count = (GLsizei)vtx_indices.size(); + } break; + case mdl::ETC_OBJ_LINE: { + EtcObjLine& line = etc->data.line; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CROSS: { + EtcObjCross& cross = etc->data.cross; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CAPSULE: { // Added + EtcObjCapsule& capsule = etc->data.capsule; + + gen_capsule_vertices(vtx_data, capsule.slices, capsule.stacks, length, capsule.radius); + size_t wire_offset = gen_capsule_indices(vtx_indices, capsule.slices, capsule.stacks, length); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_ELLIPSE: { // Added + EtcObjEllipse& ellipse = etc->data.ellipse; + + gen_ellipse_vertices(vtx_data, ellipse.slices, ellipse.stacks, length, ellipse.radius); + size_t wire_offset = gen_ellipse_indices(vtx_indices, ellipse.slices, ellipse.stacks, length); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_CYLINDER: { // Added + EtcObjCylinder& cylinder = etc->data.cylinder; + + gen_cylinder_vertices(vtx_data, cylinder.slices, cylinder.stacks, + cylinder.base, cylinder.top, cylinder.height); + size_t wire_offset = gen_cylinder_indices(vtx_indices, cylinder.slices, cylinder.stacks); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + } + + if (!wire) { + etc->count = etc_vertex_array->count; + etc->offset = etc_vertex_array->offset; + } + else { + etc->count = etc_vertex_array->wire_count; + etc->offset = etc_vertex_array->wire_offset; + } + + if (!etc_vertex_array->count) + return; + + if (etc_vertex_array->max_vtx < vtx_data.size()) { + etc_vertex_array->max_vtx = vtx_data.size(); + + etc_vertex_array->vertex_buffer.Destroy(); + } + + if (etc_vertex_array->max_idx < vtx_indices.size()) { + etc_vertex_array->max_idx = vtx_indices.size(); + + etc_vertex_array->index_buffer.Destroy(); + } + + GLsizei size_vertex = sizeof(vec3) * 2; + + gl_state_bind_vertex_array(etc_vertex_array->vertex_array); + + if (etc_vertex_array->vertex_buffer.IsNull()) + etc_vertex_array->vertex_buffer.Create(sizeof(float_t) * vtx_data.size()); + + etc_vertex_array->vertex_buffer.Bind(); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float_t) + * 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.Bind(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint32_t) + * vtx_indices.size(), vtx_indices.data()); + } + + glEnableVertexAttribArray(POSITION_INDEX); + glVertexAttribPointer(POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)0); + + glEnableVertexAttribArray(NORMAL_INDEX); + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)sizeof(vec3)); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (indexed) + gl_state_bind_element_array_buffer(0); + } + + void* DispManager::alloc_data(int32_t size) { + if (!buff || buff_offset + size > buff_size) + return 0; + + void* data = (void*)((size_t)buff + buff_offset); + buff_offset += size; + buff_max = max_def(buff_max, buff_offset); + return data; + } + + ObjData* DispManager::alloc_obj_data(ObjKind kind) { + int32_t size = (int32_t)align_val(sizeof(ObjKind) + sizeof(mat4) + sizeof(float_t) * 2, 0x08); + switch (kind) { + case OBJ_KIND_NORMAL: + return (ObjData*)alloc_data(size + sizeof(ObjSubMeshArgs)); + case OBJ_KIND_ETC: + return (ObjData*)alloc_data(size + sizeof(EtcObj)); + case OBJ_KIND_USER: + return (ObjData*)alloc_data(size + sizeof(UserArgs)); + case OBJ_KIND_TRANSLUCENT: + return (ObjData*)alloc_data(size + sizeof(ObjTranslucentArgs)); + default: + return 0; + } + } + + mat4* DispManager::alloc_mat4_array(int32_t count) { + return (mat4*)alloc_data(sizeof(mat4) * count); + } + + void DispManager::buffer_reset() { + buff_offset = 0; + } + + void DispManager::check_vertex_arrays() { + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 && --i.alive_time <= 0) { + i.vertex_buffer = 0; + i.morph_vertex_buffer = 0; + } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time > 0 && --i.alive_time <= 0) { + gl_state_bind_vertex_array(i.vertex_array); + glDisableVertexAttribArray(POSITION_INDEX); + glDisableVertexAttribArray( NORMAL_INDEX); + gl_state_bind_array_buffer(0, true); + gl_state_bind_element_array_buffer(0, true); + gl_state_bind_vertex_array(0); + } + } + + void DispManager::draw(ObjType type, int32_t depth_mask, bool a4) { + if (get_obj_count(type) < 1) + return; + + render_context* rctx = rctx_ptr; + + int32_t alpha_test = 0; + float_t min_alpha = 1.0f; + float_t alpha_threshold = 0.0f; + bool reflect = uniform_value[U_REFLECT] == 1; + void(*func)(render_context * rctx, const ObjSubMeshArgs * args) = draw_sub_mesh_default; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + rctx->obj_scene_ubo.Bind(0); + rctx->obj_batch_ubo.Bind(1); + rctx->obj_skinning_ubo.Bind(3); + + switch (type) { + case OBJ_TYPE_TRANSLUCENT: + case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: + case OBJ_TYPE_TRANSLUCENT_LOCAL: + if (depth_mask) + func = draw_sub_mesh_translucent; + else + gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_TRANSPARENT: + case OBJ_TYPE_TRANSPARENT_LOCAL: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + case OBJ_TYPE_SHADOW_CHARA: + case OBJ_TYPE_SHADOW_STAGE: + case OBJ_TYPE_SHADOW_OBJECT_CHARA: + case OBJ_TYPE_SHADOW_OBJECT_STAGE: + func = draw_sub_mesh_shadow; + break; + case OBJ_TYPE_TYPE_6: + func = draw_sub_mesh_translucent; + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rctx->draw_state->shader_index = SHADER_FT_SIL; + break; + case OBJ_TYPE_TYPE_7: + func = draw_sub_mesh_translucent; + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + rctx->draw_state->shader_index = SHADER_FT_SIL; + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.99999994f; + break; + case OBJ_TYPE_REFLECT_CHARA_OPAQUE: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + break; + case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + min_alpha = 0.0f; + break; + case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + case OBJ_TYPE_REFLECT_OPAQUE: + alpha_test = 1; + if (!a4) + func = draw_sub_mesh_reflect_reflect_map; + break; + case OBJ_TYPE_REFLECT_TRANSLUCENT: + case OBJ_TYPE_REFRACT_TRANSLUCENT: + gl_state_set_depth_mask(GL_FALSE); + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_REFLECT_TRANSPARENT: + case OBJ_TYPE_REFRACT_TRANSPARENT: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_SSS: + func = draw_sub_mesh_sss; + break; + case OBJ_TYPE_USER: + func = draw_sub_mesh_translucent; + break; + default: + break; + } + rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + uniform_value[U_ALPHA_TEST] = alpha_test; + + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh(rctx, &i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_ETC: { + draw_object_model_mat_load(rctx, i->mat); + draw_etc_obj(rctx, &i->args.etc); + } break; + case OBJ_KIND_USER: { + draw_object_model_mat_load(rctx, i->mat); + i->args.user.func(i->args.user.data); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh(rctx, i->args.translucent.sub_mesh[j], &i->mat, func); + } break; + } + } + + switch (type) { + case OBJ_TYPE_TRANSLUCENT: + case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: + case OBJ_TYPE_REFLECT_TRANSLUCENT: + case OBJ_TYPE_REFRACT_TRANSLUCENT: + if (!depth_mask) + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_TYPE_6: + case OBJ_TYPE_TYPE_7: + rctx_ptr->draw_state->shader_index = -1; + gl_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_state_set_cull_face_mode(GL_BACK); + break; + } + + uniform_value_reset(); + gl_state_bind_vertex_array(0); + shader::unbind(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + for (int32_t i = 0; i < 5; i++) + gl_state_bind_sampler(i, 0); + } + + void DispManager::draw_translucent(ObjType type, int32_t alpha) { + if (get_obj_count(type) < 1) + return; + + render_context* rctx = rctx_ptr; + + int32_t alpha_test = 0; + float_t min_alpha = 1.0f; + float_t alpha_threshold = 0.0f; + bool reflect = uniform_value[U_REFLECT] == 1; + void(*func)(render_context * rctx, const ObjSubMeshArgs * args) = draw_sub_mesh_default; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + rctx->obj_scene_ubo.Bind(0); + rctx->obj_batch_ubo.Bind(1); + rctx->obj_skinning_ubo.Bind(3); + + switch (type) { + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL: + gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + } + rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + uniform_value[U_ALPHA_TEST] = alpha_test; + + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + 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(rctx, &i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) { + ObjSubMeshArgs* args = i->args.translucent.sub_mesh[j]; + int32_t a = (int32_t)(args->blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(rctx, args, &i->mat, func); + } + } break; + } + } + + switch (type) { + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: + gl_state_set_cull_face_mode(GL_BACK); + break; + } + + uniform_value_reset(); + shader::unbind(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + } + + /*void DispManager::draw_show_vector(ObjType type, int32_t show_vector) { + if (get_obj_count(type) < 1) + return; + + render_context* rctx = rctx_ptr; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + for (ObjData*& i : obj[type]) { + switch (i->type) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh_show_vector(rctx, &i->args.sub_mesh, + &i->mat, show_vector); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh_show_vector(rctx, i->args.translucent.sub_mesh[j], + &i->mat, show_vector); + } break; + } + } + gl_state_set_blend_func(GL_ONE, GL_ZERO); + }*/ + + void DispManager::entry_list(ObjType type, ObjData* data) { + obj[type].push_back(data); + } + + static int32_t obj_axis_aligned_bounding_box_check_visibility( + obj_axis_aligned_bounding_box* aabb, camera* cam, const mat4* mat) { + vec3 points[8]; + points[0] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, 0.0f)); + points[1] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, -0.0f)); + points[2] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, 0.0f)); + points[3] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, -0.0f)); + points[4] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, 0.0f)); + points[5] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, -0.0f)); + points[6] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, -0.0f)); + points[7] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, 0.0f)); + + mat4 view_mat; + mat4_mul(mat, &cam->view, &view_mat); + for (int32_t i = 0; i < 8; i++) + mat4_transform_point(&view_mat, &points[i], &points[i]); + + vec4 v2[6]; + *(vec3*)&v2[0] = { 0.0f, 0.0f, -1.0f }; + v2[0].w = (float_t)-cam->min_distance; + *(vec3*)&v2[1] = cam->field_1E4; + v2[1].w = 0.0f; + *(vec3*)&v2[2] = cam->field_1F0; + v2[2].w = 0.0f; + *(vec3*)&v2[3] = cam->field_1FC; + v2[3].w = 0.0f; + *(vec3*)&v2[4] = cam->field_208; + v2[4].w = 0.0f; + *(vec3*)&v2[5] = { 0.0f, 0.0f, 1.0f }; + v2[5].w = (float_t)cam->max_distance; + + for (int32_t i = 0; i < 6; i++) + for (int32_t j = 0; j < 8; j++) { + float_t v34 = vec3::dot(*(vec3*)&v2[i], points[j]) + v2[i].w; + if (v34 > 0.0f) + break; + + if (j == 7) + return 0; + } + return 1; + } + + static int32_t obj_bounding_sphere_check_visibility(obj_bounding_sphere* sphere, + CullingCheck* culling, camera* cam, const mat4* mat) { + if (culling->func) + return culling->func(sphere, &cam->view); + + vec3 center; + mat4_transform_point(mat, &sphere->center, ¢er); + mat4_transform_point(&cam->view, ¢er, ¢er); + float_t radius = mat4_get_max_scale(mat) * sphere->radius; + + double_t min_depth = (double_t)center.z - (double_t)radius; + double_t max_depth = (double_t)center.z + (double_t)radius; + if (-cam->min_distance < min_depth || -cam->max_distance > max_depth) + return 0; + + float_t v5 = vec3::dot(cam->field_1E4, center); + if (v5 < -radius) + return 0; + + float_t v6 = vec3::dot(cam->field_1F0, center); + if (v6 < -radius) + return 0; + + float_t v7 = vec3::dot(cam->field_1FC, center); + if (v7 < -radius) + return 0; + + float_t v8 = vec3::dot(cam->field_208, center); + if (v8 < -radius) + return 0; + + if (-cam->min_distance >= max_depth && -cam->max_distance <= min_depth + && v5 >= radius && v6 >= radius && v7 >= radius && v8 >= radius) + return 1; + return 2; + } + + bool DispManager::entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, + obj_mesh_index_buffer* obj_index_buf, const mat4* mat, + std::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, + obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, + mat4* instances_mat, void(*func)(const ObjSubMeshArgs*), bool enable_bone_mat, bool local) { + if (!obj_vertex_buf || !obj_index_buf) { + printf_debug("mdl::DispManager::entry_obj: no vertex or index object buffer to draw;\n"); + printf_debug(" Object: %s\n", object->name); + return false; + } + + ::camera* cam = rctx_ptr->camera; + cam->update_data(); + + if (!local && object_culling && !instances_count && !bone_mat && (!object + || !obj_bounding_sphere_check_visibility( + &object->bounding_sphere, &culling, cam, mat))) { + culling.culled.objects++; + return false; + } + culling.passed.objects++; + + for (uint32_t i = 0; i < object->num_mesh; i++) { + obj_mesh* mesh = &object->mesh_array[i]; + obj_mesh* mesh_morph = 0; + if (obj_vertex_buf && obj_morph_vertex_buf) { + if (obj_vertex_buf[i].get_size() != obj_morph_vertex_buf[i].get_size()) + continue; + + if (object_morph && i < object_morph->num_mesh) + mesh_morph = &object_morph->mesh_array[i]; + } + + if (!local && object_culling && !instances_count && !bone_mat + && !obj_bounding_sphere_check_visibility( + &mesh->bounding_sphere, &culling, cam, mat) + && (!mesh_morph || !obj_bounding_sphere_check_visibility( + &mesh_morph->bounding_sphere, &culling, cam, mat))) { + culling.culled.meshes++; + continue; + } + culling.passed.meshes++; + + ObjSubMeshArgs* translucent_priority[40]; + int32_t translucent_priority_count = 0; + + for (uint32_t j = 0; j < mesh->num_submesh; j++) { + obj_sub_mesh* sub_mesh = &mesh->submesh_array[j]; + obj_sub_mesh* sub_mesh_morph = 0; + if (sub_mesh->attrib.m.cloth) + continue; + + if (!local && object_culling && !instances_count && !bone_mat) { + int32_t v32 = obj_bounding_sphere_check_visibility( + &sub_mesh->bounding_sphere, &culling, cam, mat); + if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis)) { + if (v32 == 2) { + if (culling.func) + v32 = 1; + else + v32 = obj_axis_aligned_bounding_box_check_visibility( + &sub_mesh->axis_aligned_bounding_box, cam, mat); + } + + if (!v32) { + if (!mesh_morph || j >= mesh_morph->num_submesh) { + culling.culled.submesh_array++; + continue; + } + + sub_mesh_morph = &mesh_morph->submesh_array[j]; + if (!sub_mesh_morph) { + culling.culled.submesh_array++; + continue; + } + + v32 = obj_bounding_sphere_check_visibility( + &sub_mesh_morph->bounding_sphere, &culling, cam, mat); + if (v32 == 2) { + if (culling.func) + v32 = 1; + else + v32 = obj_axis_aligned_bounding_box_check_visibility( + &sub_mesh_morph->axis_aligned_bounding_box, cam, mat); + } + + if (!v32) { + culling.culled.submesh_array++; + continue; + } + } + } + } + culling.passed.submesh_array++; + + int32_t num_bone_index = sub_mesh->num_bone_index; + uint16_t* bone_index = sub_mesh->bone_index_array; + + mat4* mats; + if (num_bone_index && enable_bone_mat) { + mats = alloc_mat4_array(num_bone_index); + if (bone_mat) + for (int32_t k = 0; k < num_bone_index; k++, bone_index++) + mats[k] = bone_mat[*bone_index]; + else + for (int32_t k = 0; k < num_bone_index; k++) + mats[k] = mat4_identity; + } + else { + mats = 0; + num_bone_index = 0; + } + + obj_material_data* material = &object->material_array[sub_mesh->material_index]; + ObjData* data = alloc_obj_data(OBJ_KIND_NORMAL); + if (!data) + continue; + + //GLuint morph_vertex_buffer = 0; + //if (obj_morph_vertex_buf) + // morph_vertex_buffer = obj_morph_vertex_buf[i].get_buffer(); + obj_mesh_vertex_buffer* morph_vertex_buffer + = obj_morph_vertex_buf ? &obj_morph_vertex_buf[i] : 0; + + //GLuint index_buffer = 0; + //if (obj_index_buf) + // index_buffer = obj_index_buf[i].buffer; + obj_mesh_index_buffer* index_buffer = &obj_index_buf[i]; + + //GLuint vertex_buffer = 0; + //if (obj_vertex_buf) + // vertex_buffer = obj_vertex_buf[i].get_buffer(); + obj_mesh_vertex_buffer* vertex_buffer = &obj_vertex_buf[i]; + + if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer) { + printf_debug("mdl::DispManager::entry_obj: no vertex or index mesh buffer to draw;\n"); + printf_debug(" Object: %s; Mesh: %s; Sub Mesh: %d\n", object->name, mesh->name, j); + continue; + } + + uint32_t material_hash = hash_utf8_murmurhash(material->material.name); + + material_list_struct* mat_list = 0; + for (int32_t k = 0; k < material_list_count; k++) + if (material_list_array[k].hash == material_hash) { + mat_list = &material_list_array[k]; + break; + } + + vec4 _blend_color = 1.0f; + vec4 _emission = 0.0f; + + if (mat_list) { + bool has_blend_color = false; + if (mat_list->has_blend_color.x) { + _blend_color.x = mat_list->blend_color.x; + has_blend_color = true; + } + + if (mat_list->has_blend_color.y) { + _blend_color.y = mat_list->blend_color.y; + has_blend_color = true; + } + + if (mat_list->has_blend_color.z) { + _blend_color.z = mat_list->blend_color.z; + has_blend_color = true; + } + + if (mat_list->has_blend_color.w) { + _blend_color.w = mat_list->blend_color.w; + has_blend_color = true; + } + + if (blend_color) { + if (!has_blend_color) + _blend_color = *blend_color; + else + _blend_color *= *blend_color; + } + + bool has_emission = false; + if (mat_list->has_emission.x) { + _emission.x = mat_list->emission.x; + has_emission = true; + } + + if (mat_list->has_emission.y) { + _emission.y = mat_list->emission.y; + has_emission = true; + } + + if (mat_list->has_emission.z) { + _emission.z = mat_list->emission.z; + has_emission = true; + } + + if (mat_list->has_emission.w) { + _emission.w = mat_list->emission.w; + has_emission = true; + } + + if (!has_emission) + _emission = material->material.color.emission; + } + else { + if (blend_color) + _blend_color = *blend_color; + _emission = material->material.color.emission; + } + + data->init_sub_mesh(this, mat, object->bounding_sphere.radius, sub_mesh, + mesh, material, textures, num_bone_index, mats, vertex_buffer, index_buffer, + &_blend_color, &_emission, morph_vertex_buffer, instances_count, instances_mat, func); + + if (obj_flags & mdl::OBJ_SHADOW_OBJECT) { + entry_list((ObjType)(OBJ_TYPE_SHADOW_OBJECT_CHARA + + shadow_type), data); + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + continue; + } + + obj_material_attrib_member attrib = material->material.attrib.m; + if (obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3) + && data->args.sub_mesh.blend_color.w < 1.0f) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + if (attrib.flag_28 || (attrib.punch_through + || !(attrib.alpha_texture | attrib.alpha_material)) + && !sub_mesh->attrib.m.transparent) { + if (!attrib.punch_through) { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(local ? OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL + : OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, data); + } + else { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(local ? OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL + : OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, data); + } + + if (obj_flags & mdl::OBJ_SSS) + entry_list(OBJ_TYPE_SSS, data); + } + + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL + : OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); + } + } + else { + if (attrib.flag_28 || data->args.sub_mesh.blend_color.w >= 1.0f + && (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material)) + && !sub_mesh->attrib.m.transparent) { + if (obj_flags & mdl::OBJ_SHADOW) + entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); + + if (obj_flags & mdl::OBJ_SSS) + entry_list(OBJ_TYPE_SSS, data); + + if (attrib.punch_through) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) + entry_list(local ? OBJ_TYPE_TRANSPARENT_LOCAL + : OBJ_TYPE_TRANSPARENT, data); + + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFLECT) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_TRANSPARENT, data); + } + else { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) + entry_list(local ? OBJ_TYPE_OPAQUE_LOCAL + : OBJ_TYPE_OPAQUE, data); + + if (obj_flags & mdl::OBJ_20) + entry_list(OBJ_TYPE_TYPE_6, data); + + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFLECT) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_OPAQUE, data); + } + + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + continue; + } + else if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + if (!attrib.translucent_priority) + if (local) + entry_list(OBJ_TYPE_TRANSLUCENT_LOCAL, data); + else if (mesh->attrib.m.translucent_no_shadow + || obj_flags & mdl::OBJ_TRANSLUCENT_NO_SHADOW) { + entry_list(OBJ_TYPE_TRANSLUCENT_NO_SHADOW, data); + } + else + entry_list(OBJ_TYPE_TRANSLUCENT, data); + else if (translucent_priority_count < 40) + translucent_priority[translucent_priority_count++] = &data->args.sub_mesh; + } + } + + if (obj_flags & mdl::OBJ_SHADOW) + entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + + shadow_type), data); + if (obj_flags & mdl::OBJ_40) + entry_list(OBJ_TYPE_TYPE_7, data); + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + if (obj_flags & mdl::OBJ_REFLECT) { + if (rctx_ptr->render_manager->reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + else + entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT, data); + } + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_TRANSLUCENT, data); + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + } + + if (!translucent_priority_count) + continue; + + ObjTranslucentArgs translucent_args; + translucent_args.count = 0; + for (int32_t j = 62; j; j--) + for (int32_t k = 0; k < translucent_priority_count; k++) { + ObjSubMeshArgs* sub_mesh = translucent_priority[k]; + if (sub_mesh->material->material.attrib.m.translucent_priority != j) + continue; + + translucent_args.sub_mesh[translucent_args.count] = sub_mesh; + translucent_args.count++; + } + + ObjData* data = alloc_obj_data(OBJ_KIND_TRANSLUCENT); + if (!data) + continue; + + data->init_translucent(mat, &translucent_args); + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL + : OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_3) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); + else + entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL + : OBJ_TYPE_TRANSLUCENT, data); + } + return true; + } + + void DispManager::entry_obj_by_obj(const mat4* mat, + ::obj* obj, std::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, + obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) { + if (!obj) + return; + + vec4 blend_color = { 1.0f, 1.0f, 1.0f, alpha }; + vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0; + + entry_obj(obj, obj_vert_buf, obj_index_buf, mat, textures, blend_color_ptr, + bone_mat, 0, 0, 0, 0, 0, !!bone_mat); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat) { + vec4 blend_color = 1.0f; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, int32_t instances_count, + mat4* instances_mat, void(*func)(const ObjSubMeshArgs*), bool enable_bone_mat, bool local) { + if (obj_info.id == -1 && obj_info.set_id == -1) + return false; + + ::obj* object = object_storage_get_obj(obj_info); + if (!object) + return false; + + std::vector* textures = object_storage_get_obj_set_textures(obj_info.set_id); + obj_mesh_vertex_buffer* obj_vertex_buffer = object_storage_get_obj_mesh_vertex_buffer(obj_info); + obj_mesh_index_buffer* obj_index_buffer = object_storage_get_obj_mesh_index_buffer(obj_info); + + ::obj* obj_morph = 0; + obj_mesh_vertex_buffer* obj_morph_vertex_buffer = 0; + if (morph.object.set_id != -1) { + obj_morph = object_storage_get_obj(morph.object); + obj_morph_vertex_buffer = object_storage_get_obj_mesh_vertex_buffer(morph.object); + } + + return entry_obj(object, obj_vertex_buffer, obj_index_buffer, + mat, textures, blend_color, bone_mat, obj_morph, obj_morph_vertex_buffer, + instances_count, instances_mat, func, enable_bone_mat, local); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, + object_info obj_info, float_t alpha, mat4* bone_mat) { + vec4 blend_color = 1.0f; + blend_color.w = alpha; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + float_t r, float_t g, float_t b, float_t a, mat4* bone_mat, bool local) { + vec4 blend_color = { r, g, b, a }; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true, local); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, bool local) { + return entry_obj_by_object_info(mat, obj_info, blend_color, 0, 0, 0, 0, false, local); + } + + void DispManager::entry_obj_by_object_info_object_skin(object_info obj_info, + std::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, + mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat) { + obj_skin* skin = object_storage_get_obj_skin(obj_info); + if (!skin) + return; + + obj_skin_set_matrix_buffer(skin, matrices, ex_data_matrices, rctx_ptr->matrix_buffer, mat, global_mat); + + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + if (texture_data && !texture_data->field_0) { + vec4 value; + get_texture_color_coeff(texture_color_coefficients); + *(vec3*)&value = texture_data->texture_color_coefficients * *(vec3*)&texture_color_coefficients; + value.w = 0.0f; + set_texture_color_coefficients(value); + + get_texture_color_offset(texture_color_offset); + *(vec3*)&value = texture_data->texture_color_offset; + value.w = 0.0f; + set_texture_color_offset(value); + + get_texture_specular_coeff(texture_specular_coefficients); + *(vec3*)&value = texture_data->texture_specular_coefficients * *(vec3*)&texture_specular_coefficients; + value.w = 0.0f; + set_texture_specular_coefficients(value); + + get_texture_specular_offset(texture_specular_offset); + *(vec3*)&value = texture_data->texture_specular_offset; + value.w = 0.0f; + set_texture_specular_offset(value); + } + + size_t texture_pattern_count = texture_pattern ? texture_pattern->size() : 0; + if (texture_pattern && texture_pattern_count) + set_texture_pattern((int32_t)texture_pattern_count, texture_pattern->data()); + + if (fabsf(alpha - 1.0f) > 0.000001f) + entry_obj_by_object_info(global_mat, obj_info, alpha, rctx_ptr->matrix_buffer); + else + entry_obj_by_object_info(global_mat, obj_info, rctx_ptr->matrix_buffer); + + if (texture_pattern && texture_pattern_count) + set_texture_pattern(); + + if (texture_data && !texture_data->field_0) { + set_texture_color_coefficients(texture_color_coefficients); + set_texture_color_offset(texture_color_offset); + set_texture_specular_coefficients(texture_specular_coefficients); + set_texture_specular_offset(texture_specular_offset); + } + } + + void DispManager::entry_obj_etc(const mat4* mat, EtcObj* etc, bool local) { + ObjData* data = alloc_obj_data(mdl::OBJ_KIND_ETC); + if (!data) + return; + + data->init_etc(this, mat, etc); + if (etc->color.a == 0xFF) { + if (!local && (obj_flags & OBJ_SHADOW)) + mdl::DispManager::entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); + mdl::DispManager::entry_list(local ? OBJ_TYPE_OPAQUE_LOCAL : OBJ_TYPE_OPAQUE, data); + } + else + mdl::DispManager::entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL : OBJ_TYPE_TRANSLUCENT, data); + } + + void DispManager::entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type) { + ObjData* _data = alloc_obj_data(OBJ_KIND_USER); + if (_data) { + _data->init_user(mat, func, data); + entry_list(type, _data); + } + } + + GLuint DispManager::get_vertex_array(const ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + const obj_material_data* material = args->material; + + //GLuint vertex_buffer = args->vertex_buffer; + obj_mesh_vertex_buffer* vertex_buffer = args->vertex_buffer; + //GLuint morph_vertex_buffer = args->morph_vertex_buffer; + obj_mesh_vertex_buffer* morph_vertex_buffer = args->morph_vertex_buffer; + //GLuint index_buffer = args->index_buffer; + obj_mesh_index_buffer* index_buffer = args->index_buffer; + + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (const obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + + GLuint vertex_attrib_buffer_binding[16] = {}; + object_data_get_vertex_attrib_buffer_bindings(args, + texcoord_array, vertex_attrib_buffer_binding); + + bool compressed = mesh->attrib.m.compressed; + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 && i.vertex_buffer == vertex_buffer + && i.morph_vertex_buffer == morph_vertex_buffer + && i.index_buffer == index_buffer && i.vertex_format == vertex_format + && i.size_vertex == size_vertex && i.compressed == compressed + && !memcmp(i.vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) + return i.vertex_array; + return 0; + } + + GLuint DispManager::get_vertex_array(const EtcObj* etc) { + EtcObjType type = etc->type; + float_t length = 0; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + break; + case mdl::ETC_OBJ_CAPSULE: // Added + length = vec3::distance(etc->data.capsule.pos[0], etc->data.capsule.pos[1]); + break; + case mdl::ETC_OBJ_ELLIPSE: // Added + length = vec3::distance(etc->data.ellipse.pos[0], etc->data.ellipse.pos[1]); + break; + case mdl::ETC_OBJ_CYLINDER: // Added + break; + default: + return 0; + } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type) + continue; + + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + return i.vertex_array; + case mdl::ETC_OBJ_GRID: + if (!memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CUBE: + return i.vertex_array; + case mdl::ETC_OBJ_SPHERE: + if (i.data.sphere.slices == etc->data.sphere.slices + && i.data.sphere.stacks == etc->data.sphere.stacks + && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_PLANE: + return i.vertex_array; + case mdl::ETC_OBJ_CONE: + if (i.data.cone.slices == etc->data.cone.slices + && i.data.cone.stacks == etc->data.cone.stacks + && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f + && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_LINE: + return i.vertex_array; + case mdl::ETC_OBJ_CROSS: + return i.vertex_array; + case mdl::ETC_OBJ_CAPSULE: // Added + if (i.data.capsule.slices == etc->data.capsule.slices + && ((i.data.capsule.stacks + 1)) >> 1 == ((etc->data.capsule.stacks + 1) >> 1) + && fabsf(i.data.capsule.radius - etc->data.capsule.radius) < 0.00001f + && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_ELLIPSE: // Added + if (i.data.ellipse.slices == etc->data.ellipse.slices + && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) + && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f + && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CYLINDER: // Added + if (i.data.cylinder.slices == etc->data.cylinder.slices + && i.data.cylinder.stacks == etc->data.cylinder.stacks + && fabsf(i.data.cylinder.base - etc->data.cylinder.base) < 0.00001f + && fabsf(i.data.cylinder.top - etc->data.cylinder.top) < 0.00001f + && fabsf(i.data.cylinder.height - etc->data.cylinder.height) < 0.00001f) + return i.vertex_array; + break; + } + } + return 0; + } + + bool DispManager::get_chara_color() { + return chara_color; + } + + ObjFlags DispManager::get_obj_flags() { + return obj_flags; + } + + void DispManager::get_material_list(int32_t& count, material_list_struct*& value) { + count = material_list_count; + + for (int32_t i = 0; i < count; i++) + value[i] = material_list_array[i]; + } + + void DispManager::get_morph(object_info& object, float_t& weight) { + weight = morph.weight; + object = morph.object; + } + + int32_t DispManager::get_obj_count(ObjType type) { + return (int32_t)obj[type].size(); + } + + shadow_type_enum DispManager::get_shadow_type() { + return shadow_type; + } + + void DispManager::get_texture_color_coeff(vec4& value) { + value = texture_color_coefficients; + } + + void DispManager::get_texture_color_offset(vec4& value) { + value = texture_color_offset; + } + + void DispManager::get_texture_pattern(int32_t& count, texture_pattern_struct*& value) { + count = texture_pattern_count; + + for (int32_t i = 0; i < count; i++) + value[i] = texture_pattern_array[i]; + } + + void DispManager::get_texture_specular_coeff(vec4& value) { + value = texture_specular_coefficients; + } + + void DispManager::get_texture_specular_offset(vec4& value) { + value = texture_specular_offset; + } + + void DispManager::get_texture_transform(int32_t& count, texture_transform_struct*& value) { + count = texture_transform_count; + + for (int32_t i = 0; i < count; i++) + value[i] = texture_transform_array[i]; + } + + float_t DispManager::get_wet_param() { + return wet_param; + } + + static int mdl_obj_data_sort_quicksort_compare0(void const* src1, void const* src2) { + float_t d1 = (*(ObjData**)src1)->view_z; + float_t d2 = (*(ObjData**)src2)->view_z; + return d1 > d2 ? -1 : (d1 < d2 ? 1 : 0); + } + + static int mdl_obj_data_sort_quicksort_compare1(void const* src1, void const* src2) { + float_t d1 = (*(ObjData**)src1)->view_z; + float_t d2 = (*(ObjData**)src2)->view_z; + return d1 < d2 ? -1 : (d1 > d2 ? 1 : 0); + } + + static int mdl_obj_data_sort_quicksort_compare2(void const* src1, void const* src2) { + float_t r1 = (*(ObjData**)src1)->radius; + float_t r2 = (*(ObjData**)src2)->radius; + return r1 > r2 ? -1 : (r1 < r2 ? 1 : 0); + } + + void DispManager::obj_sort(mat4* view, ObjType type, int32_t compare_func) { + std::vector& vec = obj[type]; + if (vec.size() < 1) + return; + + for (ObjData*& i : vec) { + vec3 center; + mat4_get_translation(&i->mat, ¢er); + if (i->kind == OBJ_KIND_NORMAL) { + mat4 mat = i->mat; + if (i->args.sub_mesh.mesh->attrib.m.billboard) + model_mat_face_camera_view(view, &mat, &mat); + else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) + model_mat_face_camera_position(view, &mat, &mat); + + const obj_sub_mesh* sub_mesh = i->args.sub_mesh.sub_mesh; + if (i->args.sub_mesh.mat_count < 1 || !sub_mesh->num_bone_index) + mat4_transform_point(&mat, &sub_mesh->bounding_sphere.center, ¢er); + else { + vec3 center_sum = 0.0f; + for (uint32_t j = 0; j < sub_mesh->num_bone_index; j++) { + center = sub_mesh->bounding_sphere.center; + mat4_transform_point(&i->args.sub_mesh.mats[j], ¢er, ¢er); + center_sum += center; + } + center_sum *= 1.0f / (float_t)sub_mesh->num_bone_index; + } + i->radius = i->args.sub_mesh.mesh->bounding_sphere.radius; + } + + mat4_transform_point(view, ¢er, ¢er); + i->view_z = center.z; + } + + switch (compare_func) { + case 0: + quicksort_custom(vec.data(), vec.size(), + sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare0); + break; + case 1: + quicksort_custom(vec.data(), vec.size(), + sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare1); + break; + case 2: + quicksort_custom(vec.data(), vec.size(), + sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare2); + break; + } + } + + void DispManager::refresh() { + culling.passed_prev = culling.passed; + culling.culled_prev = culling.culled; + culling.passed = {}; + culling.culled = {}; + + obj_flags = (::mdl::ObjFlags)0; + field_8 = 0; + field_C = 0; + + texture_pattern_count = 0; + memset(texture_pattern_array, 0, sizeof(texture_pattern_array)); + texture_transform_count = 0; + memset(texture_transform_array, 0, sizeof(texture_transform_array)); + texture_color_coefficients = 1.0f; + texture_color_offset = 0.0f; + texture_specular_coefficients = 1.0f; + texture_specular_offset = 0.0f; + + for (std::vector& i : obj) + i.clear(); + + buffer_reset(); + } + + void DispManager::set_chara_color(bool value) { + chara_color = value; + } + + void DispManager::set_culling_finc(bool(*func)(obj_bounding_sphere*, mat4*)) { + culling.func = func; + } + + void DispManager::set_obj_flags(ObjFlags flags) { + obj_flags = flags; + } + + void DispManager::set_material_list(int32_t count, material_list_struct* value) { + if (count > MATERIAL_LIST_COUNT) + return; + + material_list_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + material_list_array[i] = value[i]; + else + for (int32_t i = 0; i < MATERIAL_LIST_COUNT; i++) + material_list_array[i] = {}; + } + + void DispManager::set_morph(object_info object, float_t weight) { + morph.weight = weight; + morph.object = object; + } + + void DispManager::set_shadow_type(shadow_type_enum type) { + if (type == SHADOW_CHARA || type == SHADOW_STAGE) + shadow_type = type; + } + + void DispManager::set_texture_color_coefficients(vec4& value) { + texture_color_coefficients = value; + } + + void DispManager::set_texture_color_offset(vec4& value) { + texture_color_offset = value; + } + + void DispManager::set_texture_pattern(int32_t count, texture_pattern_struct* value) { + if (count > TEXTURE_PATTERN_COUNT) + return; + + texture_pattern_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + texture_pattern_array[i] = value[i]; + else + for (int32_t i = 0; i < TEXTURE_PATTERN_COUNT; i++) + texture_pattern_array[i] = {}; + } + + void DispManager::set_texture_specular_coefficients(vec4& value) { + texture_specular_coefficients = value; + } + + void DispManager::set_texture_specular_offset(vec4& value) { + texture_specular_offset = value; + } + + void DispManager::set_texture_transform(int32_t count, texture_transform_struct* value) { + if (count > TEXTURE_TRANSFORM_COUNT) + return; + + texture_transform_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + texture_transform_array[i] = value[i]; + else + for (int32_t i = count; i < TEXTURE_TRANSFORM_COUNT; i++) + texture_transform_array[i] = {}; + } + + void DispManager::set_wet_param(float_t value) { + wet_param = value; + } +} + +static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, + int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + + //GLuint vertex_buffer = args->vertex_buffer; + GLuint vertex_buffer = args->vertex_buffer + ? args->vertex_buffer->get_buffer() : 0; + //GLuint morph_vertex_buffer = args->morph_vertex_buffer; + GLuint morph_vertex_buffer = args->morph_vertex_buffer + ? args->morph_vertex_buffer->get_buffer() : 0; + + bool compressed = mesh->attrib.m.compressed; + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + if (vertex_format & OBJ_VERTEX_POSITION) + vertex_attrib_buffer_binding[POSITION_INDEX] = vertex_buffer; + if (vertex_format & OBJ_VERTEX_NORMAL) + vertex_attrib_buffer_binding[NORMAL_INDEX] = vertex_buffer; + if (vertex_format & OBJ_VERTEX_TANGENT) + vertex_attrib_buffer_binding[TANGENT_INDEX] = vertex_buffer; + + for (int32_t i = 0; i < 2; i++) { + int32_t texcoord_index = texcoord_array[i]; + if (texcoord_index >= 0) + if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) + vertex_attrib_buffer_binding[TEXCOORD0_INDEX + i] = vertex_buffer; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) + vertex_attrib_buffer_binding[COLOR0_INDEX] = vertex_buffer; + + if (vertex_format & OBJ_VERTEX_BONE_DATA) { + vertex_attrib_buffer_binding[BONE_WEIGHT_INDEX] = vertex_buffer; + vertex_attrib_buffer_binding[BONE_INDEX_INDEX] = vertex_buffer; + } + + if (!compressed && vertex_format & OBJ_VERTEX_UNKNOWN) + vertex_attrib_buffer_binding[UNKNOWN_INDEX] = vertex_buffer; + + if (args->morph_vertex_buffer) { + if (vertex_format & OBJ_VERTEX_POSITION) + vertex_attrib_buffer_binding[MORPH_POSITION_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_NORMAL) + vertex_attrib_buffer_binding[MORPH_NORMAL_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TANGENT) + vertex_attrib_buffer_binding[MORPH_TANGENT_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + vertex_attrib_buffer_binding[MORPH_TEXCOORD0_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + vertex_attrib_buffer_binding[MORPH_TEXCOORD1_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_COLOR0) + vertex_attrib_buffer_binding[MORPH_COLOR_INDEX] = morph_vertex_buffer; + } +} diff --git a/src/CRE/mdl/disp_manager.hpp b/src/CRE/mdl/disp_manager.hpp new file mode 100644 index 00000000..48571233 --- /dev/null +++ b/src/CRE/mdl/disp_manager.hpp @@ -0,0 +1,504 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/time.hpp" +#include "../../KKdLib/vec.hpp" +#include "../GL/array_buffer.hpp" +#include "../GL/element_array_buffer.hpp" +#include "../color.hpp" +#include "../object.hpp" +#include "../shadow.hpp" + +#define MATERIAL_LIST_COUNT 24 +#define TEXTURE_PATTERN_COUNT 24 +#define TEXTURE_TRANSFORM_COUNT 24 + +struct material_list_struct { + uint32_t hash; + vec4 blend_color; + vec4u8 has_blend_color; + vec4 emission; + vec4u8 has_emission; + + material_list_struct(); + material_list_struct(uint32_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission); +}; + +struct texture_pattern_struct { + texture_id src; + texture_id dst; + + texture_pattern_struct(); + texture_pattern_struct(texture_id src, texture_id dst); +}; + +struct texture_transform_struct { + uint32_t id; + mat4 mat; + + texture_transform_struct(); + texture_transform_struct(uint32_t id, mat4& mat); +}; + +struct morph_struct { + object_info object; + float_t weight; + + morph_struct(); +}; + +struct texture_data_struct { + int32_t field_0; + vec3 texture_color_coefficients; + vec3 texture_color_offset; + vec3 texture_specular_coefficients; + vec3 texture_specular_offset; + + texture_data_struct(); +}; + +namespace mdl { + enum EtcObjType { + ETC_OBJ_TEAPOT = 0, + ETC_OBJ_GRID, + ETC_OBJ_CUBE, + ETC_OBJ_SPHERE, + ETC_OBJ_PLANE, + ETC_OBJ_CONE, + ETC_OBJ_LINE, + ETC_OBJ_CROSS, + ETC_OBJ_CAPSULE, // Added + ETC_OBJ_ELLIPSE, // Added + ETC_OBJ_CYLINDER, // Added + ETC_OBJ_MAX, + }; + + enum ObjKind { + OBJ_KIND_NORMAL = 0, + OBJ_KIND_ETC, + OBJ_KIND_USER, + OBJ_KIND_TRANSLUCENT, + OBJ_KIND_MAX, + }; + + enum ObjFlags : uint32_t { + OBJ_SHADOW = 0x00000001, + OBJ_2 = 0x00000002, + OBJ_4 = 0x00000004, + OBJ_8 = 0x00000008, + OBJ_10 = 0x00000010, + OBJ_20 = 0x00000020, + OBJ_40 = 0x00000040, + OBJ_SHADOW_OBJECT = 0x00000080, + OBJ_CHARA_REFLECT = 0x00000100, + OBJ_REFLECT = 0x00000200, + OBJ_REFRACT = 0x00000400, + OBJ_800 = 0x00000800, + OBJ_TRANSLUCENT_NO_SHADOW = 0x00001000, + OBJ_SSS = 0x00002000, + OBJ_4000 = 0x00004000, + OBJ_8000 = 0x00008000, + OBJ_ALPHA_ORDER_1 = 0x00010000, + OBJ_ALPHA_ORDER_2 = 0x00020000, + OBJ_ALPHA_ORDER_3 = 0x00040000, + OBJ_80000 = 0x00080000, + OBJ_100000 = 0x00100000, + OBJ_200000 = 0x00200000, + OBJ_400000 = 0x00400000, + OBJ_800000 = 0x00800000, + OBJ_USER = 0x01000000, + OBJ_2000000 = 0x02000000, + OBJ_4000000 = 0x04000000, + OBJ_8000000 = 0x08000000, + OBJ_10000000 = 0x10000000, + OBJ_20000000 = 0x20000000, + OBJ_40000000 = 0x40000000, + OBJ_NO_TRANSLUCENCY = 0x80000000, + }; + + enum ObjType { + OBJ_TYPE_OPAQUE = 0, + OBJ_TYPE_TRANSLUCENT, + OBJ_TYPE_TRANSLUCENT_NO_SHADOW, + OBJ_TYPE_TRANSPARENT, + OBJ_TYPE_SHADOW_CHARA, + OBJ_TYPE_SHADOW_STAGE, + OBJ_TYPE_TYPE_6, + OBJ_TYPE_TYPE_7, + OBJ_TYPE_SHADOW_OBJECT_CHARA, + OBJ_TYPE_SHADOW_OBJECT_STAGE, + OBJ_TYPE_REFLECT_CHARA_OPAQUE, + OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT, + OBJ_TYPE_REFLECT_CHARA_TRANSPARENT, + OBJ_TYPE_REFLECT_OPAQUE, + OBJ_TYPE_REFLECT_TRANSLUCENT, + OBJ_TYPE_REFLECT_TRANSPARENT, + OBJ_TYPE_REFRACT_OPAQUE, + OBJ_TYPE_REFRACT_TRANSLUCENT, + OBJ_TYPE_REFRACT_TRANSPARENT, + OBJ_TYPE_SSS, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, + OBJ_TYPE_USER, + OBJ_TYPE_OPAQUE_LOCAL, // X + OBJ_TYPE_TRANSLUCENT_LOCAL, + OBJ_TYPE_TRANSPARENT_LOCAL, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, + OBJ_TYPE_MAX, + }; + + struct DispManager; + struct ObjSubMeshArgs; + + struct ObjSubMeshArgs { + const obj_sub_mesh* sub_mesh; + const obj_mesh* mesh; + const obj_material_data* material; + const std::vector* textures; + int32_t mat_count; + const mat4* mats; + //GLuint vertex_buffer; + obj_mesh_vertex_buffer* vertex_buffer; + //GLuint index_buffer; + obj_mesh_index_buffer* index_buffer; + bool set_blend_color; + bool chara_color; + vec4 blend_color; + vec4 emission; + bool self_shadow; + shadow_type_enum shadow; + //GLuint morph_vertex_buffer; + obj_mesh_vertex_buffer* morph_vertex_buffer; + float_t morph_weight; + int32_t texture_pattern_count; + texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + int32_t texture_transform_count; + texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; + int32_t instances_count; + const mat4* instances_mat; + void(*func)(const mdl::ObjSubMeshArgs*); + }; + + struct EtcObjTeapot { + float_t size; + + EtcObjTeapot(); + }; + + struct EtcObjGrid { + int32_t w; + int32_t h; + int32_t ws; + int32_t hs; + + EtcObjGrid(); + }; + + struct EtcObjCube { + vec3 size; + bool wire; + + EtcObjCube(); + }; + + struct EtcObjSphere { + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + + EtcObjSphere(); + }; + + struct EtcObjPlane { + int32_t w; + int32_t h; + + EtcObjPlane(); + }; + + struct EtcObjCone { + float_t base; + float_t height; + int32_t slices; + int32_t stacks; + bool wire; + + EtcObjCone(); + }; + + struct EtcObjLine { + vec3 pos[2]; + + EtcObjLine(); + }; + + struct EtcObjCross { + float_t size; + + EtcObjCross(); + }; + + struct EtcObjCapsule { // Added + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + vec3 pos[2]; + + EtcObjCapsule(); + }; + + struct EtcObjEllipse { // Added + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + vec3 pos[2]; + + EtcObjEllipse(); + }; + + struct EtcObjCylinder { // Added + float_t base; + float_t top; + float_t height; + int32_t slices; + int32_t stacks; + bool wire; + + EtcObjCylinder(); + }; + + struct EtcObj { + union Data { + EtcObjTeapot teapot; + EtcObjGrid grid; + EtcObjCube cube; + EtcObjSphere sphere; + EtcObjPlane plane; + EtcObjCone cone; + EtcObjLine line; + EtcObjCross cross; + EtcObjCapsule capsule; // Added + EtcObjEllipse ellipse; // Added + EtcObjCylinder cylinder; // Added + + Data(); + }; + + EtcObjType type; + color4u8 color; + //bool fog; + bool constant; // Added + Data data; + GLsizei count; // Added + size_t offset; // Added + + EtcObj(); + void init(EtcObjType type); + }; + + typedef void(*UserArgsFunc)(void* data); + + struct UserArgs { + UserArgsFunc func; + void* data; + }; + + struct ObjTranslucentArgs { + uint32_t count; + ObjSubMeshArgs* sub_mesh[40]; + }; + + struct ObjData { + union Args { + ObjSubMeshArgs sub_mesh; + EtcObj etc; + UserArgs user; + ObjTranslucentArgs translucent; + }; + + ObjKind kind; + mat4 mat; + float_t view_z; + float_t radius; + Args args; + + void init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc); + void init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, + obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, + int32_t mat_count, mat4* mats, /*GLuint vertex_buffer, GLuint index_buffer,*/ + obj_mesh_vertex_buffer* vertex_buffer, obj_mesh_index_buffer* index_buffer, vec4* blend_color, + vec4* emission, /*GLuint morph_vertex_buffer,*/ obj_mesh_vertex_buffer* morph_vertex_buffer, + int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)); + void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent); + void init_user(const mat4* mat, UserArgsFunc func, void* data); + }; + + struct CullingCheck { + struct Info { + int32_t objects; + int32_t meshes; + int32_t submesh_array; + }; + + Info passed; + Info culled; + Info passed_prev; + Info culled_prev; + + bool(*func)(obj_bounding_sphere*, mat4*); + }; + + struct DispManager { + struct vertex_array { + //GLuint vertex_buffer; + obj_mesh_vertex_buffer* vertex_buffer; + //GLuint morph_vertex_buffer; + obj_mesh_vertex_buffer* morph_vertex_buffer; + //GLuint index_buffer; + obj_mesh_index_buffer* index_buffer; + int32_t alive_time; + GLuint vertex_array; + bool vertex_attrib_array[16]; + obj_vertex_format vertex_format; + GLsizei size_vertex; + bool compressed; + GLuint vertex_attrib_buffer_binding[16]; + int32_t texcoord_array[2]; + }; + + struct etc_vertex_array { + GL::ArrayBuffer vertex_buffer; + GL::ElementArrayBuffer index_buffer; + int32_t alive_time; + GLuint vertex_array; + EtcObj::Data data; + EtcObjType type; + GLsizei count; + size_t offset; + GLsizei wire_count; + size_t wire_offset; + size_t max_vtx; + size_t max_idx; + }; + + mdl::ObjFlags obj_flags; + shadow_type_enum shadow_type; + int32_t field_8; + int32_t field_C; + std::vector obj[mdl::OBJ_TYPE_MAX]; + mdl::CullingCheck culling; + int32_t put_index; + bool show_alpha_center; + bool show_mat_center; + bool object_culling; + bool object_sort; + bool chara_color; + int32_t buff_offset; + int32_t buff_max; + int32_t buff_size; + void* buff; + morph_struct morph; + int32_t texture_pattern_count; + texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + float_t wet_param; + int32_t texture_transform_count; + texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; + int32_t material_list_count; + material_list_struct material_list_array[MATERIAL_LIST_COUNT]; + std::vector vertex_array_cache; + std::vector etc_vertex_array_cache; + + DispManager(); + ~DispManager(); + + void add_vertex_array(ObjSubMeshArgs* args); + void add_vertex_array(EtcObj* etc, mat4& mat); + void* alloc_data(int32_t size); + ObjData* alloc_obj_data(ObjKind kind); + mat4* alloc_mat4_array(int32_t count); + void buffer_reset(); + void check_vertex_arrays(); + void draw(mdl::ObjType type, int32_t depth_mask = 0, bool a4 = true); + void draw_translucent(mdl::ObjType type, int32_t alpha); + /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ + void entry_list(ObjType type, ObjData* data); + bool entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, + obj_mesh_index_buffer* obj_index_buf, const mat4* mat, + std::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, + obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, + mat4* instances_mat, void(*func)(const mdl::ObjSubMeshArgs*), bool enable_bone_mat, bool local = false); + void entry_obj_by_obj(const mat4* mat, + ::obj* obj, std::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, + obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat = 0); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, int32_t instances_count, + mat4* instances_mat, void(*func)(const mdl::ObjSubMeshArgs*), bool enable_bone_mat, bool local = false); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, float_t alpha, mat4* bone_mat = 0); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + float_t r, float_t g, float_t b, float_t a, mat4* bone_mat = 0, bool local = false); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat = 0, bool local = false); + void entry_obj_by_object_info_object_skin(object_info obj_info, + std::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, + mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat); + void entry_obj_etc(const mat4* mat, EtcObj* etc, bool local = false); + void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type); + GLuint get_vertex_array(const ObjSubMeshArgs* args); + GLuint get_vertex_array(const EtcObj* etc); + bool get_chara_color(); + ObjFlags get_obj_flags(); + void get_material_list(int32_t& count, material_list_struct*& value); + void get_morph(object_info& object, float_t& weight); + int32_t get_obj_count(ObjType type); + shadow_type_enum get_shadow_type(); + void get_texture_color_coeff(vec4& value); + void get_texture_color_offset(vec4& value); + void get_texture_pattern(int32_t& count, texture_pattern_struct*& value); + void get_texture_specular_coeff(vec4& value); + 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); + void refresh(); + void set_chara_color(bool value = false); + void set_culling_finc(bool(*func)(obj_bounding_sphere*, mat4*) = 0); + void set_obj_flags(ObjFlags flags = (ObjFlags)0); + void set_material_list(int32_t count = 0, material_list_struct* value = 0); + void set_morph(object_info object = {}, float_t weight = 0.0f); + void set_shadow_type(shadow_type_enum type = SHADOW_CHARA); + void set_texture_color_coefficients(vec4& value); + void set_texture_color_offset(vec4& value); + void set_texture_pattern(int32_t count = 0, texture_pattern_struct* value = 0); + void set_texture_specular_coefficients(vec4& value); + void set_texture_specular_offset(vec4& value); + void set_texture_transform(int32_t count = 0, texture_transform_struct* value = 0); + void set_wet_param(float_t value = 0.0f); + }; +} diff --git a/src/CRE/draw_object.cpp b/src/CRE/mdl/draw_object.cpp similarity index 94% rename from src/CRE/draw_object.cpp rename to src/CRE/mdl/draw_object.cpp index 576700d9..5e00123e 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/mdl/draw_object.cpp @@ -4,10 +4,10 @@ */ #include "draw_object.hpp" -#include "light_param/light.hpp" -#include "shader_ft.hpp" -#include "static_var.hpp" -#include "texture.hpp" +#include "../light_param/light.hpp" +#include "../shader_ft.hpp" +#include "../static_var.hpp" +#include "../texture.hpp" static bool draw_object_blend_set(render_context* rctx, const mdl::ObjSubMeshArgs* args, obj_material_shader_lighting_type lighting_type); @@ -57,11 +57,11 @@ namespace mdl { shaders_ft.draw_elements(mesh_draw_mode[primitive_type], count, mesh_indices_type[index_format], (void*)indices); - rctx->draw_state.stats.draw_count += count; + rctx->draw_state->stats.draw_count += count; if (primitive_type == OBJ_PRIMITIVE_TRIANGLES) - rctx->draw_state.stats.draw_triangle_count += count / 3; + rctx->draw_state->stats.draw_triangle_count += count / 3; else if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP) - rctx->draw_state.stats.draw_triangle_count += count - 2; + rctx->draw_state->stats.draw_triangle_count += count - 2; } void draw_etc_obj(render_context* rctx, mdl::EtcObj* etc) { @@ -85,7 +85,7 @@ namespace mdl { if (!etc->count) return; - GLuint vao = rctx->disp_manager.get_vertex_array(etc); + GLuint vao = rctx->disp_manager->get_vertex_array(etc); if (!vao) return; @@ -181,7 +181,7 @@ namespace mdl { void draw_sub_mesh(render_context* rctx, const ObjSubMeshArgs* args, const mat4* model, void(*func)(render_context* rctx, const ObjSubMeshArgs* args)) { - GLuint vao = rctx->disp_manager.get_vertex_array(args); + GLuint vao = rctx->disp_manager->get_vertex_array(args); if (!vao) return; @@ -243,7 +243,7 @@ namespace mdl { if (!args->func) draw_object_vertex_attrib_set_default(rctx, args); - draw_object_material_set_default(rctx, args, rctx->draw_state.shader); + draw_object_material_set_default(rctx, args, rctx->draw_state->shader); const obj_sub_mesh* sub_mesh = args->sub_mesh; draw(rctx, @@ -263,7 +263,7 @@ namespace mdl { rctx->obj_batch.g_offset_color = 0.0f; } - rctx->draw_state.stats.object_draw_count++; + rctx->draw_state->stats.object_draw_count++; } void draw_sub_mesh_default_instanced(render_context* rctx, @@ -276,7 +276,7 @@ namespace mdl { if (!args->func) draw_object_vertex_attrib_set_default(rctx, args); - draw_object_material_set_default(rctx, args, rctx->draw_state.shader); + draw_object_material_set_default(rctx, args, rctx->draw_state->shader); const obj_sub_mesh* sub_mesh = args->sub_mesh; const mat4* instances_mat = args->instances_mat; @@ -302,7 +302,7 @@ namespace mdl { rctx->obj_batch.g_offset_color = 0.0f; } - rctx->draw_state.stats.object_draw_count++; + rctx->draw_state->stats.object_draw_count++; } void draw_sub_mesh_sss(render_context* rctx, const ObjSubMeshArgs* args) { @@ -317,12 +317,12 @@ namespace mdl { const obj_material_data* material = args->material; switch (material->material.shader.index) { case SHADER_FT_CLOTH: - if (!rctx->render_manager.npr_param && material->material.color.ambient.w < 1.0f + if (!rctx->render_manager->npr_param && material->material.color.ambient.w < 1.0f && material->material.shader_info.m.aniso_direction == OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) aniso = true; break; case SHADER_FT_TIGHTS: - if (!rctx->render_manager.npr_param) + if (!rctx->render_manager->npr_param) aniso = true; break; //case SHADER_FT_EYEBALL: @@ -340,7 +340,7 @@ namespace mdl { uniform_value[U37] = 1; } else { - const vec4& sss_param = rctx->render_manager.sss_data.param; + const vec4& sss_param = rctx->sss_data->param; rctx->obj_batch.g_sss_param = { sss_param.x, sss_param.y, sss_param.z, 0.5f }; uniform_value[U37] = 0; } @@ -370,7 +370,7 @@ namespace mdl { draw_object_vertex_attrib_reset_reflect(args); uniform_value_reset(); - rctx->draw_state.stats.object_reflect_draw_count++; + rctx->draw_state->stats.object_reflect_draw_count++; } void draw_sub_mesh_reflect_reflect_map(render_context* rctx, const ObjSubMeshArgs* args) { @@ -390,7 +390,7 @@ namespace mdl { draw_object_material_reset_reflect(rctx); draw_object_vertex_attrib_reset_reflect(args); - rctx->draw_state.stats.object_reflect_draw_count++; + rctx->draw_state->stats.object_reflect_draw_count++; } void draw_sub_mesh_shadow(render_context* rctx, const ObjSubMeshArgs* args) { @@ -411,13 +411,13 @@ namespace mdl { void draw_sub_mesh_translucent(render_context* rctx, const ObjSubMeshArgs* args) { const obj_material_data* material = args->material; const std::vector* textures = args->textures; - if (rctx->draw_state.shader_index != -1) { + if (rctx->draw_state->shader_index != -1) { rctx->obj_batch.g_material_state_emission = args->emission; draw_object_material_set_uniform(material, false); if (material->material.attrib.m.alpha_texture) uniform_value[U_TEXTURE_COUNT] = 0; rctx->obj_batch.g_texture_blend = { (float_t)uniform_value[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f }; - shaders_ft.set(rctx->draw_state.shader_index); + shaders_ft.set(rctx->draw_state->shader_index); } draw_object_vertex_attrib_set_default(rctx, args); @@ -429,12 +429,10 @@ namespace mdl { if (material->material.attrib.m.alpha_texture) { const obj_material_texture_data* texdata = material->material.texdata; uint32_t texture_id = -1; - uint32_t texture_index = -1; if (!material->material.shader_compo.m.transparency) { for (int32_t i = 0; i < 8; i++, texdata++) if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) { texture_id = texdata->tex_index; - texture_index = texdata->texture_index; break; } tex_index = 0; @@ -444,7 +442,6 @@ namespace mdl { if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_TRANSPARENCY) { if (texdata->attrib.m.flag_29) { texture_id = texdata->tex_index; - texture_index = texdata->texture_index; } break; } @@ -506,10 +503,10 @@ namespace mdl { gl_state_enable_cull_face(); draw_object_vertex_attrib_reset_default(args); - if (rctx->draw_state.shader_index != -1) + if (rctx->draw_state->shader_index != -1) uniform_value_reset(); - rctx->draw_state.stats.object_translucent_draw_count++; + rctx->draw_state->stats.object_translucent_draw_count++; } } @@ -585,7 +582,7 @@ static bool draw_object_blend_set(render_context* rctx, 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 = rctx->draw_state.shader_index; + int32_t shader_index = rctx->draw_state->shader_index; if (shader_index == -1) { shader_index = material->material.shader.index; if (shader_index == SHADER_FT_BLINN) { @@ -638,7 +635,7 @@ static void draw_object_chara_color_fog_set(render_context* rctx, const mdl::Obj uniform_value[U_FOG_HEIGHT] = 2 + attrib.fog_height; else uniform_value[U_FOG_HEIGHT] = 1; - uniform_value[U_FOG] = rctx->draw_state.fog_height ? 2 : 1; + uniform_value[U_FOG] = rctx->draw_state->fog_height ? 2 : 1; } } @@ -665,14 +662,14 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob material->material.shader_info.get_lighting_type(); bool disable_fog = draw_object_blend_set(rctx, args, lighting_type); draw_object_material_set_uniform(material, false); - if (!rctx->draw_state.light) + if (!rctx->draw_state->light) uniform_value[U_LIGHT_0] = 0; else if (args->self_shadow) uniform_value[U_LIGHT_0] = 1; else uniform_value[U_LIGHT_0] = args->sub_mesh->attrib.m.recieve_shadow ? 1 : 0; uniform_value[U_SHADOW] = 0; - uniform_value[U_SELF_SHADOW] = rctx->draw_state.self_shadow ? 1 : 0; + uniform_value[U_SELF_SHADOW] = rctx->draw_state->self_shadow ? 1 : 0; const obj_material_texture_data* texdata = material->material.texdata; uniform_value[U_SHADOW] = args->shadow > SHADOW_CHARA; @@ -779,7 +776,7 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob draw_object_chara_color_fog_set(rctx, args, disable_fog); rctx->obj_batch.g_material_state_ambient = material->material.color.ambient; - if (!rctx->render_manager.sss_data.enable) + if (!rctx->sss_data->enable) rctx->obj_batch.g_material_state_ambient.w = 1.0f; rctx->obj_batch.g_material_state_diffuse = material->material.color.diffuse; rctx->obj_batch.g_material_state_emission = args->emission; @@ -805,8 +802,8 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob if (!use_shader) shaders_ft.set(SHADER_FT_SIMPLE); - else if (rctx->draw_state.shader_index != -1) - shaders_ft.set(rctx->draw_state.shader_index); + else if (rctx->draw_state->shader_index != -1) + shaders_ft.set(rctx->draw_state->shader_index); else if (material->material.shader.index != -1) { if (material->material.shader.index != SHADER_FT_BLINN) shaders_ft.set(material->material.shader.index); @@ -835,7 +832,7 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob if (fresnel > 9.0f) fresnel = 9.0f; else if (fresnel == 0.0f) - fresnel = rctx->draw_state.fresnel; + fresnel = rctx->draw_state->fresnel; fresnel = (fresnel - 1.0f) * 0.12f * 0.82f; rctx->obj_batch.g_fresnel_coefficients = { fresnel, 0.18f, line_light, 0.0f }; @@ -877,15 +874,15 @@ static void draw_object_material_set_parameter(render_context* rctx, const obj_m float_t reflect_uv_scale; float_t refract_uv_scale; float_t inv_bump_depth; - if (rctx->draw_state.use_global_material) { - bump_depth = rctx->draw_state.bump_depth; - intensity = rctx->draw_state.intensity; - reflect_uv_scale = rctx->draw_state.reflect_uv_scale; - refract_uv_scale = rctx->draw_state.refract_uv_scale; - inv_bump_depth = (1.0f - rctx->draw_state.bump_depth) * 64.0f + 1.0f; + if (rctx->draw_state->use_global_material) { + bump_depth = rctx->draw_state->bump_depth; + intensity = rctx->draw_state->intensity; + reflect_uv_scale = rctx->draw_state->reflect_uv_scale; + refract_uv_scale = rctx->draw_state->refract_uv_scale; + inv_bump_depth = (1.0f - rctx->draw_state->bump_depth) * 64.0f + 1.0f; vec4 specular = mat_data->material.color.specular; - specular.w = rctx->draw_state.reflectivity; + specular.w = rctx->draw_state->reflectivity; rctx->obj_batch.g_material_state_specular = specular; } else { @@ -971,7 +968,7 @@ static void draw_object_material_set_reflect(render_context* rctx, const mdl::Ob draw_object_material_set_uniform(material, true); rctx->obj_batch.g_texture_blend = { (float_t)uniform_value[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f }; - shaders_ft.set(rctx->draw_state.shader_index); + shaders_ft.set(rctx->draw_state->shader_index); rctx->obj_batch.g_material_state_ambient = ambient; rctx->obj_batch.g_material_state_diffuse = diffuse; rctx->obj_batch.g_material_state_emission = emission; @@ -1088,7 +1085,7 @@ static void draw_object_vertex_attrib_set_default(render_context* rctx, const md if (texcoord_mat_set[texcoord_index]) continue; - int32_t texture_id = material->material.texdata[i].tex_index; + uint32_t texture_id = material->material.texdata[i].tex_index; rctx->obj_batch.set_g_texcoord_transforms(texcoord_index, material->material.texdata[i].tex_coord_mat); @@ -1134,7 +1131,7 @@ static void draw_object_vertex_attrib_set_reflect(render_context* rctx, const md const obj_material_data* material = args->material; if (material->material.texdata[0].tex_index != -1) { - int32_t tex_index = material->material.texdata[0].tex_index; + uint32_t tex_index = material->material.texdata[0].tex_index; rctx->obj_batch.set_g_texcoord_transforms(0, material->material.texdata[0].tex_coord_mat); diff --git a/src/CRE/draw_object.hpp b/src/CRE/mdl/draw_object.hpp similarity index 90% rename from src/CRE/draw_object.hpp rename to src/CRE/mdl/draw_object.hpp index 5e5598a6..9e045b1c 100644 --- a/src/CRE/draw_object.hpp +++ b/src/CRE/mdl/draw_object.hpp @@ -5,11 +5,11 @@ #pragma once -#include "../KKdLib/default.hpp" -#include "../KKdLib/mat.hpp" -#include "../KKdLib/vec.hpp" -#include "object.hpp" -#include "render_context.hpp" +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" +#include "../object.hpp" +#include "../render_context.hpp" namespace mdl { extern void draw(render_context* rctx, obj_primitive_type primitive_type, uint32_t count, diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index aebd8604..db7f42e0 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -34,7 +34,7 @@ static uint32_t obj_vertex_format_get_vertex_size_comp(obj_vertex_format format) std::map object_storage_data; std::map object_storage_data_modern; -obj_mesh_index_buffer::obj_mesh_index_buffer() : buffer(), size() { +obj_mesh_index_buffer::obj_mesh_index_buffer() : buffer() { } @@ -60,7 +60,6 @@ bool obj_mesh_index_buffer::load_data(size_t size, const void* data) { if (!size) return false; - this->size = (GLsizeiptr)size; glGenBuffers(1, &buffer); gl_state_bind_element_array_buffer(buffer, true); if (GLAD_GL_VERSION_4_4) @@ -76,7 +75,6 @@ void obj_mesh_index_buffer::unload() { glDeleteBuffers(1, &buffer); buffer = 0; - size = 0; } void* obj_mesh_index_buffer::fill_data(void* data, obj_mesh& mesh) { @@ -368,8 +366,6 @@ bool obj_index_buffer::load(obj* obj) { if (index) { void* data = index; for (uint32_t i = 0; i < mesh_num; i++) { - mesh_data[i].size = (GLsizeiptr)buffer_size; - uint32_t offset = (uint32_t)((size_t)data - (size_t)index); data = obj_mesh_index_buffer::fill_data(data, obj->mesh_array[i]); diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index a5f30e11..876080de 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -21,7 +21,6 @@ struct obj_mesh_index_buffer { GLuint buffer; - GLsizeiptr size; obj_mesh_index_buffer(); @@ -112,6 +111,7 @@ extern int32_t obj_material_texture_type_get_texcoord_index( obj_material_texture_type type, int32_t index); extern int32_t obj_material_texture_type_get_texture_index( obj_material_texture_type type, int32_t base_index); + extern void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4* global_mat); diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp deleted file mode 100644 index 3d2c8d46..00000000 --- a/src/CRE/post_process.cpp +++ /dev/null @@ -1,1089 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "post_process.hpp" -#include "rob/rob.hpp" -#include "fbo.hpp" -#include "gl_state.hpp" -#include "render_texture.hpp" -#include "shader_ft.hpp" -#include "stage.hpp" -#include "stage_modern.hpp" -#include "static_var.hpp" -#include "texture.hpp" - -extern bool task_stage_is_modern; - -extern render_context* rctx_ptr; - -static void post_process_generate_area_texture(post_process* pp); -static void post_process_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2); -static void post_process_calculate_area_texture_data_area(float_t* val_left, - float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright); - -post_process_frame_texture_render_texture::post_process_frame_texture_render_texture() : texture() { - type = POST_PROCESS_FRAME_TEXTURE_MAX; -} - -post_process_frame_texture_render_texture::~post_process_frame_texture_render_texture() { - -} - -post_process_frame_texture::post_process_frame_texture() : capture() { - -} - -post_process_frame_texture::~post_process_frame_texture() { - -} - -post_process::post_process() : ssaa(), mlaa(), ss_alpha_mask(), aet_back_tex(), render_textures_data(), -movie_textures_data(), aet_back(), mlaa_area_texture(), sss_contour_texture(), texture_counter(), -lens_shaft_query(), lens_flare_query(), lens_shaft_query_data(), lens_flare_query_data(), -lens_flare_query_index(), lens_flare_texture(), lens_shaft_texture(), lens_ghost_texture(), -lens_ghost_count(), lens_flare_pos(), lens_shaft_scale(), lens_shaft_inv_scale(), lens_flare_power(), -field_A10(), lens_flare_appear_power(), render_width(), render_height(), view_point(), -interest(), view_point_prev(), interest_prev(), reset_exposure(), sprite_width(), sprite_height(), -screen_x_offset(), screen_y_offset(), screen_width(), screen_height(), mag_filter() { - blur = new post_process_blur(); - dof = new post_process_dof(); - exposure = new post_process_exposure(); - tone_map = new post_process_tone_map(); - transparency = new post_process_transparency(); - stage_index = -1; - stage_index_prev = -1; - - GLuint sampler; - glGenSamplers(3, samplers); - sampler = samplers[0]; - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - sampler = samplers[1]; - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - static const vec4 border_color = 0.0f; - - sampler = samplers[2]; - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); - - glGenVertexArrays(1, &query_vao); - - glGenVertexArrays(1, &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(); - - 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_state_bind_array_buffer(0); - gl_state_bind_vertex_array(0); - - post_process_generate_area_texture(this); - - if (!lens_shaft_query[0]) - glGenQueries(3, lens_shaft_query); - - if (!lens_flare_query[0]) - glGenQueries(3, lens_flare_query); - - sun_quad_ubo.Create(sizeof(sun_quad_shader_data)); - - for (GLuint& i : lens_shaft_query_data) - i = -1; - - for (GLuint& i : lens_flare_query_data) - i = -1; - - reset(); -} - -post_process::~post_process() { - if (aet_back_tex) - texture_free(aet_back_tex); - - if (blur) { - delete blur; - blur = 0; - } - - if (dof) { - delete dof; - dof = 0; - } - - if (exposure) { - delete exposure; - exposure = 0; - } - - if (tone_map) { - delete tone_map; - tone_map = 0; - } - - if (transparency) { - delete transparency; - transparency = 0; - } - - if (mlaa_area_texture) { - glDeleteTextures(1, &mlaa_area_texture); - mlaa_area_texture = 0; - } - - if (samplers[0]) { - glDeleteSamplers(3, samplers); - samplers[0] = 0; - } - - if (query_vao) { - glDeleteVertexArrays(1, &query_vao); - query_vao = 0; - } - - if (lens_ghost_vao) { - glDeleteVertexArrays(1, &lens_ghost_vao); - lens_ghost_vao = 0; - } - - lens_ghost_vbo.Destroy(); - - if (lens_shaft_query[0]) { - glDeleteQueries(3, lens_shaft_query); - lens_shaft_query[0] = 0; - } - - if (lens_flare_query[0]) { - glDeleteQueries(3, lens_flare_query); - lens_flare_query[0] = 0; - } - - sun_quad_ubo.Destroy(); -} - -void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param) { - for (int32_t i = 0; i < 8; i++) - gl_state_bind_sampler(i, 0); - - dof->apply(&rend_texture, &buf_texture, cam); - - draw_lens_ghost(&rend_texture); - - get_frame_texture(rend_texture.GetColorTex(), POST_PROCESS_FRAME_TEXTURE_PRE_PP); - - blur->downsample(&rend_texture); - blur->get_blur(); - exposure->get_exposure(cam, render_width, render_height, reset_exposure, - blur->reduce_texture[4].GetColorTex(), blur->reduce_texture[2].GetColorTex()); - tone_map->apply(&rend_texture, light_proj_tex, (texture*)(aet_back ? aet_back_tex : 0), - &rend_texture, &buf_texture, /* sss_contour_texture,*/ - blur->reduce_texture[0].GetColorTex(), exposure->exposure.GetColorTex(), npr_param, this); - if (mlaa) - apply_mlaa(samplers, ss_alpha_mask); - - for (int32_t i = 0; i < 16; i++) { - if (!render_textures_data[i]) - continue; - - render_textures[i].Bind(); - - texture* t = render_textures_data[i]; - if (render_width > t->width * 2ULL || render_height > t->height * 2ULL) - uniform_value[U_REDUCE] = 1; - else - uniform_value[U_REDUCE] = 0; - - glViewport(0, 0, t->width, t->height); - gl_state_active_bind_texture_2d(0, rend_texture.GetColorTex()); - gl_state_bind_sampler(0, samplers[0]); - shaders_ft.set(SHADER_FT_REDUCE); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - } - - get_frame_texture(rend_texture.GetColorTex(), POST_PROCESS_FRAME_TEXTURE_POST_PP); - - frame_texture_reset_capture(); - - screen_texture.Bind(); - glViewport(0, 0, sprite_width, sprite_height); - if (ssaa) { - gl_state_active_bind_texture_2d(0, rend_texture.GetColorTex()); - gl_state_bind_sampler(0, samplers[0]); - uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; - uniform_value[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform_value[U_ALPHA_MASK] = 0; - } - else { - gl_state_active_bind_texture_2d(0, rend_texture.GetColorTex()); - if (mag_filter == POST_PROCESS_MAG_FILTER_NEAREST) - gl_state_bind_sampler(0, samplers[1]); - else - gl_state_bind_sampler(0, samplers[0]); - - switch (mag_filter) { - case POST_PROCESS_MAG_FILTER_NEAREST: - case POST_PROCESS_MAG_FILTER_BILINEAR: - default: - uniform_value[U_MAGNIFY] = 0; - break; - case POST_PROCESS_MAG_FILTER_SHARPEN_5_TAP: - uniform_value[U_MAGNIFY] = 2; - break; - case POST_PROCESS_MAG_FILTER_SHARPEN_4_TAP: - uniform_value[U_MAGNIFY] = 3; - break; - case POST_PROCESS_MAG_FILTER_CONE_4_TAP: - uniform_value[U_MAGNIFY] = 4; - break; - case POST_PROCESS_MAG_FILTER_CONE_2_TAP: - uniform_value[U_MAGNIFY] = 5; - break; - } - - shaders_ft.set(SHADER_FT_MAGNIFY); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - } - shader::unbind(); - - for (int32_t i = 0; i < 8; i++) - gl_state_bind_sampler(i, 0); -} - -void post_process::apply_mlaa(GLuint* samplers, int32_t ss_alpha_mask) { - gl_state_begin_event("PostProcess::mlaa"); - mlaa_buffer.Bind(); - gl_state_active_bind_texture_2d(0, rend_texture.GetColorTex()); - gl_state_bind_sampler(0, samplers[1]); - uniform_value[U_MLAA] = 0; - shaders_ft.set(SHADER_FT_MLAA); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - - temp_buffer.Bind(); - gl_state_active_bind_texture_2d(0, mlaa_buffer.GetColorTex()); - gl_state_active_bind_texture_2d(1, mlaa_area_texture); - gl_state_bind_sampler(0, samplers[0]); - gl_state_bind_sampler(1, samplers[1]); - uniform_value[U_MLAA] = 1; - uniform_value[U_MLAA_SEARCH] = 2; - shaders_ft.set(SHADER_FT_MLAA); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - - buf_texture.Bind(); - gl_state_active_bind_texture_2d(0, rend_texture.GetColorTex()); - gl_state_active_bind_texture_2d(1, temp_buffer.GetColorTex()); - gl_state_bind_sampler(0, samplers[1]); - uniform_value[U_MLAA] = 2; - uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; - shaders_ft.set(SHADER_FT_MLAA); - RenderTexture::DrawQuad(&shaders_ft, render_width, render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform_value[U_ALPHA_MASK] = 0; - gl_state_active_bind_texture_2d(0, 0); - gl_state_active_bind_texture_2d(1, 0); - - fbo::blit(buf_texture.fbos[0], rend_texture.fbos[0], - 0, 0, buf_texture.GetWidth(), buf_texture.GetHeight(), - 0, 0, rend_texture.GetWidth(), rend_texture.GetHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR); - gl_state_end_event(); -} - -void post_process::ctrl(camera* cam) { - view_point_prev = view_point; - interest_prev = interest; - cam->get_view_point(view_point); - cam->get_interest(interest); - - stage_index_prev = stage_index; - if (task_stage_is_modern) - stage_index = (int32_t)task_stage_modern_get_current_stage_hash(); - else - stage_index = task_stage_get_current_stage_index(); - - reset_exposure = cam->fast_change_hist1 && !cam->fast_change_hist0; - if (reset_exposure) { - float_t view_point_dist = vec3::distance(view_point, view_point_prev); - - vec3 dir = vec3::normalize(interest - view_point); - vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); - - float_t dir_diff_angle = vec3::dot(dir, dir_prev); - if (dir_diff_angle < 0.5f) - dir_diff_angle = 0.0f; - if (view_point_dist < dir_diff_angle * 0.4f) - reset_exposure = false; - } - else if (stage_index != stage_index_prev) - reset_exposure = true; -} - -void post_process::draw_lens_flare(camera* cam) { - static float_t flt_1411ACB84 = sinf(0.01365909819f); - static float_t flt_1411ACB8C = tanf(0.01365909819f) * 2.0f * 0.94f; - - if (!lens_flare_texture) - return; - - GLuint tex = obj_database_get_obj_set_texture(5, 4549); - if (!tex) - return; - - float_t v5 = tanf((float_t)(cam->get_fov() * DEG_TO_RAD) * 0.5f); - light_set* set = &rctx_ptr->light_set[LIGHT_SET_MAIN]; - light_data* data = &set->lights[LIGHT_SUN]; - - vec3 position; - vec4 emission; - if (data->get_type() == LIGHT_PARALLEL) { - data->get_position(position); - data->get_diffuse(emission); - } - else { - set->lights[LIGHT_STAGE].get_position(position); - position = vec3::normalize(position) * 500.0f; - set->lights[LIGHT_STAGE].get_ibl_color0(emission); - data->set_type(LIGHT_PARALLEL); - data->set_position(position); - data->set_diffuse(emission); - } - - vec4 v44; - *(vec3*)&v44 = position; - v44.w = 1.0f; - - mat4_transform_vector(&cam->view_projection, &v44, &v44); - - float_t v13 = 1.0f / v44.w; - float_t v14 = v44.x * v13; - float_t v15 = v44.y * v13; - float_t v16 = (float_t)render_width * 0.01f / (float_t)render_height; - v14 = clamp_def(v14, -0.99f, 0.99f); - v15 = clamp_def(v15, v16 - 1.0f, 1.0f - v16); - v44.x = v14 * v44.w; - v44.y = v15 * v44.w; - - mat4_transform_vector(&cam->inv_view_projection, &v44, &v44); - ((pos_scale*)&lens_flare_pos)->get_screen_pos_scale(cam->view_projection, position, false); - - float_t v17 = lens_flare_pos.x - (float_t)render_width * 0.5f; - float_t v19 = v5 / (float_t)render_height * 0.5f; - float_t v20 = lens_flare_pos.y - (float_t)render_height * 0.5f; - - float_t v22 = sqrtf(v17 * v19 * v17 * v19 + v20 * v19 * v20 * v19 + 1.0f); - float_t v23 = ((float_t)render_width * (flt_1411ACB8C / v5)) * (v22 * v22 * 0.5f) - * ((float_t)render_height * (flt_1411ACB8C / v5)); - float_t v24 = vec3::distance(position, view_point) * flt_1411ACB84; - emission *= 1.0f / (float_t)(1.0f - cosf((float_t)(3.0 * DEG_TO_RAD))); - - sun_quad_shader_data shader_data = {}; - shader_data.g_emission = emission; - - gl_state_active_bind_texture_2d(0, tex); - shaders_ft.set(SHADER_FT_SUN); - gl_state_bind_vertex_array(query_vao); - sun_quad_ubo.Bind(0); - - int32_t query_index = (lens_flare_query_index + 1) % 3; - lens_flare_query_index = query_index; - int32_t next_query_index = (query_index + 2) % 3; - - if (lens_shaft_query_data[next_query_index] == -1) - lens_shaft_query_data[next_query_index] = 0; - - if (lens_flare_query_data[next_query_index] == -1) - lens_flare_query_data[next_query_index] = 0; - - gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_state_set_depth_mask(GL_FALSE); - gl_state_disable_cull_face(); - - mat4 mat; - mat4_mul_translate(&cam->view, &position, &mat); - mat4_clear_rot(&mat, &mat); - mat4_scale_rot(&mat, v24 * 0.2f, &mat); - mat4_mul(&mat, &cam->projection, &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; - sun_quad_ubo.WriteMemory(shader_data); - - glBeginQuery(GL_SAMPLES_PASSED, lens_shaft_query[next_query_index]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glEndQuery(GL_SAMPLES_PASSED); - - mat4_mul_translate(&cam->view, (vec3*)&v44, &mat); - mat4_clear_rot(&mat, &mat); - mat4_scale_rot(&mat, v24 * 2.0f, &mat); - mat4_mul(&mat, &cam->projection, &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; - sun_quad_ubo.WriteMemory(shader_data); - - glBeginQuery(GL_SAMPLES_PASSED, lens_flare_query[next_query_index]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glEndQuery(GL_SAMPLES_PASSED); - - gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_state_set_depth_mask(GL_TRUE); - gl_state_enable_cull_face(); - - if (lens_shaft_query_data[query_index] != -1) { - int32_t res = 0; - glGetQueryObjectiv(lens_shaft_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); - if (res) - glGetQueryObjectuiv(lens_shaft_query[query_index], GL_QUERY_RESULT, &lens_shaft_query_data[query_index]); - } - - if (lens_flare_query_data[query_index] != -1) { - int32_t res = 0; - glGetQueryObjectiv(lens_flare_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); - if (res) - glGetQueryObjectuiv(lens_flare_query[query_index], GL_QUERY_RESULT, &lens_flare_query_data[query_index]); - } - - if (emission.x + emission.y + emission.z > 0.0f) { - gl_state_enable_blend(); - gl_state_set_blend_func(GL_ONE, GL_ONE); - gl_state_set_depth_mask(GL_FALSE); - - mat4_mul_translate(&cam->view, &position, &mat); - mat4_clear_rot(&mat, &mat); - mat4_scale_rot(&mat, v24 * 1.1f, &mat); - mat4_mul(&mat, &cam->projection, &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; - sun_quad_ubo.WriteMemory(shader_data); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - gl_state_disable_blend(); - gl_state_set_blend_func(GL_ONE, GL_ZERO); - gl_state_set_depth_mask(GL_TRUE); - } - - gl_state_active_bind_texture_2d(0, 0); - gl_state_bind_vertex_array(0); - - if (lens_flare_appear_power <= 0.01f) - lens_flare_appear_power = 0.0; - else - lens_flare_appear_power *= 0.93f; - lens_shaft_scale = 100.0f; - lens_flare_power = 0.0f; - - float_t v34 = lens_flare_pos.x; - float_t v35 = lens_flare_pos.y; - float_t v32 = lens_flare_pos.z; - - float_t v33 = 0.0f; - if (v32 >= 0.0f - || v34 < (float_t)-render_width || v34 > (float_t)(2 * render_width) - || v35 < (float_t)-render_height || v35 > (float_t)(2 * render_height)) - lens_flare_texture = 0; - else { - for (GLuint& i : lens_flare_query_data) - if (i != -1) - v33 += min_def((float_t)i, v23); - v33 /= (v23 * 3.0f); - lens_flare_power = powf(v33, 0.7f); - - if (v33 > 0.0f && lens_shaft_query_data[query_index]) { - float_t v41 = max_def(v33 - 0.4f, 0.005f); - lens_shaft_scale = ((0.6f / v41) * lens_shaft_inv_scale) * (v5 * 3.4f); - } - } - - if (v32 >= 0.0f - || v34 < -12.0f || v34 > (float_t)(render_width + 12) - || v35 < -12.0f || v35 > (float_t)(render_height + 12)) { - field_A10 = 0.0f; - } - else if (v34 > -2.0f && v34 < (float_t)(render_width + 2) - && v35 > -2.0f && v35 < (float_t)(render_height + 2)) { - if (v33 > 0.4f && field_A10 == 0.0f && lens_flare_appear_power < 0.02f && !reset_exposure) - lens_flare_appear_power = 8.0f; - field_A10 = 1.0f; - } -} - -static void make_ghost_quad(uint8_t flags, float_t opacity, mat4* mat, float_t*& data) { - const float_t x0 = flags & 0x01 ? 0.5f : 0.0f; - const float_t x1 = flags & 0x01 ? 1.0f : 0.5f; - const float_t y0 = flags & 0x02 ? 0.5f : 0.0f; - const float_t y1 = flags & 0x02 ? 1.0f : 0.5f; - - vec4 p0 = { -0.5f, -0.5f, x0, y0 }; - vec4 p1 = { 0.5f, -0.5f, x1, y0 }; - vec4 p2 = { -0.5f, 0.5f, x0, y1 }; - vec4 p3 = { 0.5f, 0.5f, x1, y1 }; - mat4_transform_point(mat, (vec2*)&p0, (vec2*)&p0); - mat4_transform_point(mat, (vec2*)&p1, (vec2*)&p1); - mat4_transform_point(mat, (vec2*)&p2, (vec2*)&p2); - mat4_transform_point(mat, (vec2*)&p3, (vec2*)&p3); - - *(vec4*)&data[0] = p0; - data[4] = opacity; - *(vec4*)&data[5] = p1; - data[9] = opacity; - *(vec4*)&data[10] = p2; - data[14] = opacity; - *(vec4*)&data[15] = p2; - data[19] = opacity; - *(vec4*)&data[20] = p1; - data[24] = opacity; - *(vec4*)&data[25] = p3; - data[29] = opacity; - data += 30; -} - -void post_process::draw_lens_ghost(RenderTexture* rt) { - static const float_t v13[16] = { - -0.70f, -0.30f, 0.35f, 0.50f, - -0.45f, -0.80f, 0.20f, 0.41f, - 0.17f, -0.10f, 0.06f, 0.10f, - 0.14f, 0.04f, -0.13f, -0.22f, - }; - - static const float_t v14[16] = { - 0.8f, 1.0f, 1.0f, 1.0f, - 0.4f, 0.5f, 0.8f, 0.8f, - 0.6f, 0.7f, 0.8f, 0.7f, - 0.8f, 0.7f, 0.6f, 0.8f, - }; - - static const float_t v15[16] = { - 1.3f, 1.5f, 1.00f, 1.1f, - 2.5f, 0.8f, 0.50f, 0.5f, - 0.7f, 0.4f, 0.35f, 0.5f, - 0.4f, 0.3f, 0.60f, 0.4f, - }; - - if (!lens_flare_texture || lens_ghost_count <= 0) - return; - - if (lens_ghost_count > 16) - lens_ghost_count = 16; - - const float_t aspect = (float_t)render_width / (float_t)render_height; - - const float_t v7 = (lens_flare_pos.x - (float_t)(render_width / 2)) / (float_t)render_width; - const float_t v8 = -((lens_flare_pos.y - (float_t)(render_height / 2)) / (float_t)render_height); - const float_t v9 = (float_t)((1.1 - sqrtf(v8 * v8 + v7 * v7)) * lens_flare_power); - if (v9 < 0.001f) - return; - - const float_t v9a = v9 * v9; - - float_t angle = atan2f(v8, v7) - (float_t)M_PI_2; - const float_t angle_sin = sinf(angle); - const float_t angle_cos = cosf(angle); - - float_t* data = (float_t*)lens_ghost_vbo.MapMemory(); - if (!data) - return; - - const float_t lens_ghost = tone_map->lens_ghost; - const int32_t lens_ghost_count = this->lens_ghost_count; - for (int32_t i = 0; i < lens_ghost_count; i++) { - float_t opacity = v9 * v14[i] * lens_ghost; - - float_t scale = (v9a * 0.03f + 0.02f) * v15[i]; - - mat4 mat; - mat4_translate(v13[i] * v7 + 0.5f, v13[i] * v8 + 0.5f, 0.0f, &mat); - mat4_scale_rot(&mat, scale, scale * aspect, 1.0f, &mat); - mat4_mul_rotate_z(&mat, angle_sin, angle_cos, &mat); - make_ghost_quad((uint8_t)(i & 0x03), opacity, &mat, data); - } - - lens_ghost_vbo.UnmapMemory(); - - rt->Bind(); - rt->SetViewport(); - gl_state_enable_blend(); - gl_state_set_blend_func(GL_ONE, GL_ONE); - - uniform_value[U_REDUCE] = 4; - shaders_ft.set(SHADER_FT_REDUCE); - gl_state_active_bind_texture_2d(0, lens_ghost_texture); - gl_state_bind_vertex_array(lens_ghost_vao); - shaders_ft.draw_arrays(GL_TRIANGLES, 0, (GLsizei)(lens_ghost_count * 6LL)); - gl_state_bind_vertex_array(0); - - gl_state_disable_blend(); - gl_state_set_blend_func(GL_ONE, GL_ZERO); -} - -void post_process::init_fbo(int32_t render_width, int32_t render_height, - int32_t sprite_width, int32_t sprite_height, int32_t screen_width, int32_t screen_height) { - if (this->render_width == render_width && this->render_height == render_height - && this->sprite_width == sprite_width && this->sprite_height == sprite_height - && this->screen_width == screen_width && this->screen_height == screen_height) - return; - - if (this->render_width != render_width || this->render_height != render_height) { - blur->init_fbo(render_width, render_height); - dof->init_fbo(render_width, render_height); - - exposure->init_fbo(); - tone_map->init_fbo(); - - rend_texture.Init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); - buf_texture.Init(render_width, render_height, 0, GL_RGBA16F, 0); - - if (aet_back_tex) - texture_free(aet_back_tex); - aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), GL_RGBA8, render_width, render_height, 0, 0, false); - aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture.GetDepthTex()); - transparency_texture.Init(render_width, render_height, 0, GL_RGBA16F, 0); - - transparency->init_fbo(transparency_texture.GetColorTex(), - rend_texture.GetDepthTex(), render_width, render_height); - - mlaa_buffer.Init(render_width, render_height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F); - temp_buffer.Init(render_width, render_height, 0, GL_RGBA8, 0); - sss_contour_texture = &mlaa_buffer; - - gl_state_bind_texture_2d(rend_texture.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(mlaa_buffer.GetDepthTex()); - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - gl_state_bind_texture_2d(0); - - this->render_width = render_width; - this->render_height = render_height; - } - - if (this->sprite_width != sprite_width || this->sprite_height != sprite_height) { - screen_texture.Init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F - this->sprite_width = sprite_width; - this->sprite_height = sprite_height; - } - - screen_x_offset = (screen_width - sprite_width) / 2 + (screen_width - sprite_width) % 2; - screen_y_offset = (screen_height - sprite_height) / 2 + (screen_height - sprite_height) % 2; - - this->screen_width = screen_width; - this->screen_height = screen_height; -} - -bool post_process::frame_texture_cont_capture_set(bool value) { - frame_texture[0].capture = value; - return true; -} - -void post_process::frame_texture_free() { - for (post_process_frame_texture& i : frame_texture) { - for (post_process_frame_texture_render_texture& j : i.render_textures) { - j.texture = 0; - j.render_texture.Free(); - j.type = POST_PROCESS_FRAME_TEXTURE_MAX; - } - - i.capture = false; - } -} - -int32_t post_process::frame_texture_load(int32_t slot, post_process_frame_texture_type type, texture* tex) { - if (!tex || slot < 0 || slot >= 6) - return -1; - - for (post_process_frame_texture_render_texture& i : frame_texture[slot].render_textures) - if (!i.texture) { - i.render_texture.SetColorDepthTextures(tex->tex); - i.texture = tex; - i.type = type; - return (int32_t)(&i - frame_texture[slot].render_textures); - } - return -1; -} - -void post_process::frame_texture_reset() { - for (post_process_frame_texture& i : frame_texture) { - for (post_process_frame_texture_render_texture& j : i.render_textures) { - j.texture = 0; - j.type = POST_PROCESS_FRAME_TEXTURE_MAX; - } - - i.capture = false; - } -} - -void post_process::frame_texture_reset_capture() { - for (post_process_frame_texture& i : frame_texture) - if (&i - frame_texture) - i.capture = false; -} - -bool post_process::frame_texture_slot_capture_set(int32_t index) { - if (index < 1 || index >= 5) - return false; - - frame_texture[index].capture = true; - return true; -} - -bool post_process::frame_texture_unload(int32_t slot, texture* tex) { - if (!tex || slot < 0 || slot >= 6) - return false; - - for (post_process_frame_texture_render_texture& i : frame_texture[slot].render_textures) - if (i.texture == tex) { - i.render_texture.Free(); - i.texture = 0; - i.type = POST_PROCESS_FRAME_TEXTURE_MAX; - return true; - } - return false; -} - -int32_t post_process::movie_texture_set(texture* movie_texture) { - if (!movie_texture) - return -1; - - int32_t index = 0; - while (movie_textures_data[index]) - if (++index >= 1) - return -1; - - movie_textures_data[index] = movie_texture; - movie_textures[index].SetColorDepthTextures(movie_texture->tex); - return index; -} - -void post_process::get_frame_texture(GLuint tex, post_process_frame_texture_type type) { - for (post_process_frame_texture& i : frame_texture) { - if (!i.capture) - continue; - - for (auto& j : i.render_textures) { - if (!j.texture || j.type != type || j.render_texture.Bind() < 0) - continue; - - texture* dst_tex = j.texture; - - gl_state_active_bind_texture_2d(0, tex); - gl_state_bind_sampler(0, samplers[0]); - glViewport(0, 0, dst_tex->width, dst_tex->height); - uniform_value[U_REDUCE] = 0; - shaders_ft.set(SHADER_FT_REDUCE); - RenderTexture::DrawQuad(&shaders_ft, 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_state_bind_framebuffer(0); - } - } -} - -void post_process::movie_texture_free(texture* movie_texture) { - if (!movie_texture) - return; - - int32_t index = 0; - while (movie_textures_data[index] != movie_texture) - if (++index >= 1) - return; - - movie_textures_data[index] = 0; - movie_textures[index].Free(); -} - -int32_t post_process::render_texture_set(texture* render_texture, bool task_photo) { - if (!render_texture) - return -1; - - int32_t index = 0; - if (task_photo) - index = 15; - else - while (render_textures_data[index]) - if (++index >= 15) - return -1; - - render_textures_data[index] = render_texture; - render_textures[index].SetColorDepthTextures(render_texture->tex); - return index; -} - -void post_process::render_texture_free(texture* render_texture, bool task_photo) { - if (!render_texture) - return; - - int32_t index = 0; - if (task_photo) - index = 15; - else - while (render_textures_data[index] != render_texture) - if (++index >= 15) - return; - - render_textures_data[index] = 0; - render_textures[index].Free(); -} - -void post_process::reset() { - mlaa = true; - mag_filter = POST_PROCESS_MAG_FILTER_BILINEAR; - dof_debug_set(0); - dof_pv_set(0); - blur->initialize_data(2.0f, 1.0f); - - for (int32_t i = 0; i < 2; i++) { - tone_map->reset_saturate_coeff(i, 0); - tone_map->reset_scene_fade(i); - tone_map->reset_tone_trans(i); - } - - reset_exposure = true; -} - -void post_process::set_render_texture(bool aet_back) { - if (aet_back) { - aet_back_texture.Bind(); - this->aet_back = 1; - } - else - rend_texture.Bind(); - glViewport(0, 0, render_width, render_height); -} - -#define MAX_EDGE_DETECTION_LEN (3) -#define GRID_SIDE_LEN (2 * MAX_EDGE_DETECTION_LEN + 1) -#define SIDE_LEN (5 * GRID_SIDE_LEN) - -static void post_process_generate_area_texture(post_process* pp) { - uint8_t* data = (uint8_t*)malloc(SIDE_LEN * SIDE_LEN * 2); - if (!data) - return; - - for (int32_t cross2 = 0; cross2 < 5; cross2++) - for (int32_t cross1 = 0; cross1 < 5; cross1++) - post_process_calculate_area_texture_data(data, cross1, cross2); - - glGenTextures(1, &pp->mlaa_area_texture); - gl_state_bind_texture_2d(pp->mlaa_area_texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, SIDE_LEN, SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data); - gl_state_bind_texture_2d(0); - free(data); -} - -static void post_process_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2) { - uint8_t* _data = &data[(SIDE_LEN * GRID_SIDE_LEN * cross2 + GRID_SIDE_LEN * cross1) * 2]; - for (int32_t dright = 0; dright < GRID_SIDE_LEN; dright++) { - for (int32_t dleft = 0; dleft < GRID_SIDE_LEN; dleft++) { - float_t val_left = 0.0f; - float_t val_right = 0.0f; - post_process_calculate_area_texture_data_area(&val_left, &val_right, cross1, cross2, dleft, dright); - _data[0] = (uint8_t)(val_left * 255.9f); - _data[1] = (uint8_t)(val_right * 255.9f); - _data += 2; - } - _data += GRID_SIDE_LEN * 4 * 2; - } -} - -static void post_process_calculate_area_texture_data_area(float_t* val_left, - float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright) { - auto 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; - if (a1 >= a2 - 1) - return (v3 * 0.5f) * 0.5f; - else - return ((float_t)(a1 + 1) * v2 + 0.5f + v3) * 0.5f; - }; - - int32_t dist = dleft + dright + 1; - float_t _val_left = 0.0f; - float_t _val_right = 0.0f; - switch (cross2) { - case 0: - switch (cross1) { - case 1: - _val_right = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN)); - break; - case 3: - _val_left = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN)); - break; - } - break; - case 1: - switch (cross1) { - case 0: - _val_right = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN)); - break; - case 1: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_right = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_right = calc_area_tex_val(dright, v12); - else - _val_right = calc_area_tex_val(v15, v12) * 2.0f; - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft >= v12) - _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - case 3: - case 4: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_left = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_right = calc_area_tex_val(dright, v12); - else - _val_left = _val_right = calc_area_tex_val(v15, v12); - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft < v12) - _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - } - break; - case 3: - switch (cross1) { - case 0: - _val_left = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN)); - break; - case 1: - case 4: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_right = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_left = calc_area_tex_val(dright, v12); - else - _val_left = _val_right = calc_area_tex_val(v15, v12); - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft < v12) - _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - case 3: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_left = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_left = calc_area_tex_val(dright, v12); - else - _val_left = calc_area_tex_val(v15, v12) * 2.0f; - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft < v12) - _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - } - break; - case 4: - switch (cross1) { - case 1: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_right = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_left = calc_area_tex_val(dright, v12); - else - _val_left = _val_right = calc_area_tex_val(v15, v12); - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft < v12) - _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - case 3: - if (dist % 2) { - int32_t v12 = dist / 2 + 1; - int32_t v15 = dist / 2; - if (dleft < v15) - _val_left = calc_area_tex_val(dleft, v12); - else if (dright < v15) - _val_right = calc_area_tex_val(dright, v12); - else - _val_left = _val_right = calc_area_tex_val(v15, v12); - } - else { - int32_t v12 = dist / 2; - float_t v14 = -0.5f / (float_t)v12; - if (dleft < v12) - _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; - else - _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; - } - break; - } - break; - } - - *val_left = _val_left; - *val_right = _val_right; - return; -} diff --git a/src/CRE/post_process.hpp b/src/CRE/post_process.hpp deleted file mode 100644 index 49d715a0..00000000 --- a/src/CRE/post_process.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../KKdLib/default.hpp" -#include "../KKdLib/vec.hpp" -#include "GL/array_buffer.hpp" -#include "GL/uniform_buffer.hpp" -#include "post_process/blur.hpp" -#include "post_process/dof.hpp" -#include "post_process/exposure.hpp" -#include "post_process/tone_map.hpp" -#include "post_process/transparency.hpp" -#include "camera.hpp" - -enum post_process_frame_texture_type { - POST_PROCESS_FRAME_TEXTURE_PRE_PP = 0, - POST_PROCESS_FRAME_TEXTURE_POST_PP, - POST_PROCESS_FRAME_TEXTURE_FB, - POST_PROCESS_FRAME_TEXTURE_MAX, -}; - -enum post_process_mag_filter_type { - POST_PROCESS_MAG_FILTER_NEAREST = 0, - POST_PROCESS_MAG_FILTER_BILINEAR, - POST_PROCESS_MAG_FILTER_SHARPEN_5_TAP, - POST_PROCESS_MAG_FILTER_SHARPEN_4_TAP, - POST_PROCESS_MAG_FILTER_CONE_4_TAP, - POST_PROCESS_MAG_FILTER_CONE_2_TAP, - POST_PROCESS_MAG_FILTER_MAX, -}; - -struct sun_quad_shader_data { - vec4 g_transform[4]; - vec4 g_emission; -}; - -struct post_process_frame_texture_render_texture { - texture* texture; - RenderTexture render_texture; - post_process_frame_texture_type type; - - post_process_frame_texture_render_texture(); - ~post_process_frame_texture_render_texture(); -}; - - -struct post_process_frame_texture { - post_process_frame_texture_render_texture render_textures[4]; - bool capture; - - post_process_frame_texture(); - ~post_process_frame_texture(); -}; - -struct post_process { - bool ssaa; - bool mlaa; - int32_t ss_alpha_mask; - RenderTexture rend_texture; - RenderTexture buf_texture; - RenderTexture aet_back_texture; - texture* aet_back_tex; - RenderTexture transparency_texture; - RenderTexture screen_texture; - texture* render_textures_data[16]; - RenderTexture render_textures[16]; - texture* movie_textures_data[1]; - RenderTexture movie_textures[1]; - int32_t aet_back; - post_process_blur* blur; - post_process_dof* dof; - post_process_exposure* exposure; - post_process_tone_map* tone_map; - post_process_transparency* transparency; - GLuint samplers[3]; - GLuint query_vao; - GLuint lens_ghost_vao; - GL::ArrayBuffer lens_ghost_vbo; - RenderTexture mlaa_buffer; - RenderTexture temp_buffer; - GLuint mlaa_area_texture; - RenderTexture* sss_contour_texture; - GL::UniformBuffer sun_quad_ubo; - int32_t texture_counter; - GLuint lens_shaft_query[3]; - GLuint lens_flare_query[3]; - GLuint lens_shaft_query_data[3]; - GLuint lens_flare_query_data[3]; - int32_t lens_flare_query_index; - GLuint lens_flare_texture; - GLuint lens_shaft_texture; - GLuint lens_ghost_texture; - int32_t lens_ghost_count; - vec3 lens_flare_pos; - float_t lens_shaft_scale; - float_t lens_shaft_inv_scale; - float_t lens_flare_power; - float_t field_A10; - float_t lens_flare_appear_power; - int32_t render_width; - int32_t render_height; - vec3 view_point; - vec3 interest; - vec3 view_point_prev; - vec3 interest_prev; - int32_t stage_index; - int32_t stage_index_prev; - bool reset_exposure; - int32_t sprite_width; - int32_t sprite_height; - int32_t screen_x_offset; - int32_t screen_y_offset; - int32_t screen_width; - int32_t screen_height; - post_process_mag_filter_type mag_filter; - post_process_frame_texture frame_texture[6]; - - post_process(); - ~post_process(); - - void apply(camera* cam, texture* light_proj_tex, int32_t npr_param); - void apply_mlaa(GLuint* samplers, int32_t ss_alpha_mask); - void ctrl(camera* cam); - void draw_lens_flare(camera* cam); - void draw_lens_ghost(RenderTexture* rt); - void init_fbo(int32_t render_width, int32_t render_height, - int32_t sprite_width, int32_t sprite_height, int32_t screen_width, int32_t screen_height); - bool frame_texture_cont_capture_set(bool value); - void frame_texture_free(); - int32_t frame_texture_load(int32_t slot, post_process_frame_texture_type type, texture* tex); - void frame_texture_reset(); - void frame_texture_reset_capture(); - bool frame_texture_slot_capture_set(int32_t index); - bool frame_texture_unload(int32_t slot, texture* tex); - void get_frame_texture(GLuint tex, post_process_frame_texture_type type); - int32_t movie_texture_set(texture* movie_texture); - void movie_texture_free(texture* movie_texture); - int32_t render_texture_set(texture* render_texture, bool task_photo); - void render_texture_free(texture* render_texture, bool task_photo); - void reset(); - void set_render_texture(bool aet_back = false); -}; - diff --git a/src/CRE/post_process/blur.cpp b/src/CRE/post_process/blur.cpp deleted file mode 100644 index 7ececda4..00000000 --- a/src/CRE/post_process/blur.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "blur.hpp" -#include "../fbo.hpp" -#include "../gl_state.hpp" -#include "../post_process.hpp" -#include "../render_context.hpp" -#include "../shader_ft.hpp" - -struct gaussian_coef_shader_data { - vec4 g_coef[8]; -}; - -static void post_process_blur_radius_calculate(post_process_blur* blur); -static void post_process_blur_radius_calculate_gaussian_kernel(float_t* gaussian_kernel, - float_t radius, int32_t stride, int32_t offset); - -post_process_blur::post_process_blur() : data(), -width(), height(), width_down(), height_down(), tex_down(), count_down() { - reduce_width[0] = 256; - reduce_height[0] = 144; - reduce_width[1] = 128; - reduce_height[1] = 72; - reduce_width[2] = 64; - reduce_height[2] = 36; - reduce_width[3] = 32; - reduce_height[3] = 18; - reduce_width[4] = 8; - reduce_height[4] = 8; - for (int32_t i = 0; i < 5; i++) - reduce_texture[i].Init(reduce_width[i], reduce_height[i], 0, GL_RGBA16F, 0); - downsample_texture.Init(reduce_width[0], reduce_height[0], 0, GL_RGBA16F, 0); - gaussian_coef_ubo.Create(sizeof(gaussian_coef_shader_data)); -} - -post_process_blur:: ~post_process_blur() { - if (!this) - return; - - gaussian_coef_ubo.Destroy(); - for (int32_t i = 0; i < count_down; i++) - tex_down[i].Free(); - free_def(tex_down); - free_def(height_down); - free_def(width_down); -} - -void post_process_blur::downsample(RenderTexture* rt) { - int32_t i = 0; - if (count_down > 0) { - uniform_value[U_REDUCE] = 1; - shaders_ft.set(SHADER_FT_REDUCE); - for (; i < count_down; i++) { - glViewport(0, 0, width_down[i], height_down[i]); - tex_down[i].Bind(); - gl_state_active_bind_texture_2d(0, (i ? tex_down[i - 1] : *rt).GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, width_down[i], height_down[i], - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - } - i--; - } - - uniform_value[U_REDUCE] = 3; - shaders_ft.set(SHADER_FT_REDUCE); - - glViewport(0, 0, reduce_width[0], reduce_height[0]); - reduce_texture[0].Bind(); - gl_state_active_bind_texture_2d(0, (count_down > 0 ? tex_down[i] : *rt).GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, width, height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.1f, 1.1f, 1.1f, 0.0f); - - downsample_texture.Bind(); - gl_state_active_bind_texture_2d(0, reduce_texture[0].GetColorTex()); - for (int32_t i = 1; i < 5; i++) { - float_t scale; - if (i == 4) { - scale = 1.0f; - uniform_value[U_EXPOSURE] = 0; - shaders_ft.set(SHADER_FT_EXPOSURE); - } - else - { - scale = 0.75; - uniform_value[U_REDUCE] = 1; - shaders_ft.set(SHADER_FT_REDUCE); - } - - glViewport(0, 0, reduce_width[i], reduce_height[i]); - RenderTexture::DrawQuad(&shaders_ft, 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_state_active_bind_texture_2d(0, reduce_texture[i].GetColorTex()); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); - } -} - -void post_process_blur::get_blur() { - uniform_value[U_ALPHA_MASK] = 0; - - vec3 intensity = data.intensity; - vec3* gauss = data.gauss; - - gaussian_coef_shader_data gaussian_coef = {}; - for (int32_t i = 0; i < POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE && i < 8; i++) { - *(vec3*)&gaussian_coef.g_coef[i] = gauss[i] * intensity; - gaussian_coef.g_coef[i].w = 0.0f; - } - - gaussian_coef_ubo.WriteMemory(gaussian_coef); - - uniform_value[U_GAUSS] = 0; - shaders_ft.set(SHADER_FT_GAUSS); - gaussian_coef_ubo.Bind(1); - - downsample_texture.Bind(); - for (int32_t i = 1; i < 4; i++) { - glViewport(0, 0, reduce_width[i], reduce_height[i]); - gl_state_active_bind_texture_2d(0, reduce_texture[i].GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, reduce_width[i], reduce_height[i], - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); - } - - for (int32_t i = 1; i < 4; i++) { - glViewport(0, 0, reduce_width[i], reduce_height[i]); - gl_state_active_bind_texture_2d(0, reduce_texture[i].GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, reduce_width[i], reduce_height[i], - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); - } - - uniform_value[U_GAUSS] = 1; - shaders_ft.set(SHADER_FT_GAUSS); - - glViewport(0, 0, reduce_width[0], reduce_height[0]); - gl_state_active_bind_texture_2d(0, reduce_texture[0].GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, reduce_width[0], reduce_height[0], - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - data.intensity.x * 0.5f, data.intensity.y * 0.5f, data.intensity.z * 0.5f, 1.0f); - - uniform_value[U_REDUCE] = 7; - shaders_ft.set(SHADER_FT_REDUCE); - - glViewport(0, 0, reduce_width[0], reduce_height[0]); - reduce_texture[0].Bind(); - gl_state_active_bind_texture_2d(0, downsample_texture.GetColorTex()); - gl_state_active_bind_texture_2d(1, reduce_texture[1].GetColorTex()); - gl_state_active_bind_texture_2d(2, reduce_texture[2].GetColorTex()); - gl_state_active_bind_texture_2d(3, reduce_texture[3].GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, reduce_width[3], reduce_height[3], - 1.0f, 1.0f, 0.0f, 0.0f, 0.25f, 0.15f, 0.25f, 0.25f, 0.25f); -} - -void post_process_blur::init_fbo(int32_t width, int32_t height) { - if (!this || (this->width == width && this->height == height)) - return; - - this->width = width > 1 ? width : 1; - this->height = height > 1 ? height : 1; - - int32_t i = 0; - width = this->width; - height = this->height; - while (width > 512 && height > 288) { - width /= 2; - height /= 2; - i++; - } - - RenderTexture* tex_down = this->tex_down; - int32_t* width_down = this->width_down; - int32_t* height_down = this->height_down; - - if (!tex_down) - tex_down = force_malloc(i); - else if (count_down < i) { - RenderTexture* temp = force_malloc(i); - memcpy(temp, tex_down, sizeof(RenderTexture) * count_down); - free_def(tex_down); - tex_down = temp; - } - - if (!width_down) - width_down = force_malloc(i); - else if (count_down < i) { - int32_t* temp = force_malloc(i); - memcpy(temp, width_down, sizeof(int32_t) * count_down); - free_def(width_down); - width_down = temp; - } - - if (!height_down) - height_down = force_malloc(i); - else if (count_down < i) { - int32_t* temp = force_malloc(i); - memcpy(temp, height_down, sizeof(int32_t) * count_down); - free_def(height_down); - height_down = temp; - } - - count_down = i; - - i = 0; - width = this->width; - height = this->height; - while (width > 512 && height > 288) { - width_down[i] = width /= 2; - height_down[i] = height /= 2; - i++; - } - - for (i = 0; i < count_down; i++) - tex_down[i].Init(width_down[i], height_down[i], 0, GL_RGBA16F, 0); - - gl_state_bind_framebuffer(0); - - this->tex_down = tex_down; - this->width_down = width_down; - this->height_down = height_down; -} - -void post_process_blur::initialize_data(const vec3& radius, const vec3& intensity) { - data.radius = vec3::clamp(radius, 1.0f, 3.0f); - data.intensity = vec3::clamp(intensity, 0.0f, 2.0f); - post_process_blur_radius_calculate(this); -} - -vec3 post_process_blur::get_intensity() { - return data.intensity; -} - -void post_process_blur::set_intensity(const vec3& value) { - data.intensity = vec3::clamp(value, 0.0f, 2.0f); -} - -vec3 post_process_blur::get_radius() { - return data.radius; -} - -void post_process_blur::set_radius(const vec3& value) { - vec3 temp = vec3::clamp(value, 1.0f, 3.0f); - if (temp != data.radius) { - data.radius = temp; - post_process_blur_radius_calculate(this); - } -} - -static void post_process_blur_radius_calculate(post_process_blur* blur) { - float_t radius_scale = 0.8f; - vec3 radius = blur->data.radius; - post_process_blur_radius_calculate_gaussian_kernel((float_t*)blur->data.gauss, radius.x * radius_scale, 3, 0); - post_process_blur_radius_calculate_gaussian_kernel((float_t*)blur->data.gauss, radius.y * radius_scale, 3, 1); - post_process_blur_radius_calculate_gaussian_kernel((float_t*)blur->data.gauss, radius.z * radius_scale, 3, 2); -} - -static void post_process_blur_radius_calculate_gaussian_kernel(float_t* gaussian_kernel, - float_t radius, int32_t stride, int32_t offset) { - if (stride < 1) - stride = 1; - if (offset < 0) - offset = 0; - - gaussian_kernel[0 * stride + offset] = 1.0f; - for (int32_t i = 1; i < POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE; i++) - gaussian_kernel[i * stride + offset] = 0.0f; - double_t temp_gaussian_kernel[POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE]; - double_t s = radius; - s = -1.0 / (2.0 * s * s); - double_t sum = 0.5; - temp_gaussian_kernel[0] = 1.0; - for (size_t i = 1; i < POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE; i++) - sum += temp_gaussian_kernel[i] = exp(i * i * s); - - sum = 0.5 / sum; - for (size_t i = 0; i < POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE; i++) - gaussian_kernel[i * stride + offset] = (float_t)(temp_gaussian_kernel[i] * sum); -} diff --git a/src/CRE/post_process/blur.hpp b/src/CRE/post_process/blur.hpp deleted file mode 100644 index eecf3231..00000000 --- a/src/CRE/post_process/blur.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../../KKdLib/default.hpp" -#include "../../KKdLib/vec.hpp" -#include "../GL/uniform_buffer.hpp" -#include "../shared.hpp" -#include "../render_texture.hpp" - -#define POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE 7 - -struct post_process_blur_data { - vec3 gauss[POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE]; - vec3 radius; - vec3 intensity; -}; - -struct post_process_blur { - post_process_blur_data data; - int32_t width; - int32_t height; - RenderTexture reduce_texture[5]; - RenderTexture downsample_texture; - int32_t reduce_width[5]; - int32_t reduce_height[5]; - int32_t* width_down; - int32_t* height_down; - RenderTexture* tex_down; - int32_t count_down; - GL::UniformBuffer gaussian_coef_ubo; - - post_process_blur(); - ~post_process_blur(); - - void downsample(RenderTexture* rt); - void get_blur(); - void init_fbo(int32_t width, int32_t height); - void initialize_data(const vec3& radius, const vec3& intensity); - - vec3 get_intensity(); - void set_intensity(const vec3& value); - vec3 get_radius(); - void set_radius(const vec3& value); -}; diff --git a/src/CRE/post_process/dof.cpp b/src/CRE/post_process/dof.cpp deleted file mode 100644 index d20c75a3..00000000 --- a/src/CRE/post_process/dof.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "dof.hpp" -#include "../../KKdLib/str_utils.hpp" -#include "../rob/rob.hpp" -#include "../gl_state.hpp" -#include "../shader_ft.hpp" - -struct dof_common_shader_data { - vec4 g_depth_params; //x=(n-f)/(nf), y=1/n, z=coc_from_z_scale, w=coc_from_z_offset - vec4 g_spread_scale; //x=scale_from_meter_to_pixel, y=scale_from_meter_to_sample, - // z=scale_from_pixel_to_sample, w=scale_from_sample_to_pixel - vec4 g_depth_params2; //x=distance_to_focus_m, y=focus_range, - // z=k/(fuzzing_range*fuzzing_range), w=max_coc_radius_in_pixel //yzw=for_f2 -}; - -static const dof_debug dof_debug_default = { - (dof_debug_flags)0, - 10.0f, - 0.04f, - 1.4f, - { - 10.0f, - 1.0f, - 0.5f, - 1.0f, - }, -}; - -static const dof_pv dof_pv_default = { - false, - { - 10.0f, - 1.0f, - 0.5f, - 1.0f, - }, -}; - -namespace renderer { - struct DOF3 { - static void apply_f2(post_process_dof* dof, RenderTexture* rt, - RenderTexture* buf, 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); - static void apply_physical(post_process_dof* dof, RenderTexture* rt, - RenderTexture* buf, 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); - - static void render_tiles(post_process_dof* dof, - GLuint depth_texture, bool f2); - static void downsample(post_process_dof* dof, - GLuint color_texture, GLuint depth_texture, bool f2); - static void main_filter(post_process_dof* dof, bool f2); - static void upsample(post_process_dof* dof, RenderTexture* rt, RenderTexture* buf, - GLuint color_texture, GLuint depth_texture, bool f2); - - static void update_data(post_process_dof* dof, 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 post_process_dof_calculate_texcoords(vec2* data, float_t size); -static void post_process_dof_free_fbo(post_process_dof* dof); - -dof_debug dof_debug_data; -dof_pv dof_pv_data; - -post_process_dof::post_process_dof() : width(), height(), -textures(), fbo(), samplers(), vao(), texcoords_ubo() { - -} - -post_process_dof::~post_process_dof() { - if (!this) - return; - - post_process_dof_free_fbo(this); -} - -void post_process_dof::apply(RenderTexture* rt, RenderTexture* buf, camera* cam) { - if (!this) - return; - - bool use_dof_f2 = false; - 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) { - float_t focus = dof_debug_data.focus; - if (dof_debug_data.flags & DOF_DEBUG_AUTO_FOCUS) { - rob_chara* rob_chr = 0; - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { - rob_chara* rob_chr = rob_chara_array_get(i); - if (!rob_chr || !rob_chr->is_visible()) - continue; - - mat4 mat = mat4_identity; - rob_chr->sub_1405163C0(4, mat); - - vec3 chara_trans = 0.0f; - mat4_get_translation(&mat, &chara_trans); - - mat4 view_transpose; - mat4_transpose(&cam->view, &view_transpose); - focus = -vec3::dot(*(vec3*)&view_transpose.row2, chara_trans) - - view_transpose.row2.w - 0.1f; - break; - } - } - - focus = max_def(focus, (float_t)cam->min_distance); - renderer::DOF3::apply_physical(this, rt, buf, rt->GetColorTex(), rt->GetDepthTex(), - (float_t)cam->min_distance, (float_t)cam->max_distance, focus, - dof_debug_data.focal_length, (float_t)cam->fov_rad, dof_debug_data.f_number); - } - else { - float_t fuzzing_range = max_def(dof_debug_data.f2.fuzzing_range, 0.01f); - renderer::DOF3::apply_f2(this, rt, buf, rt->GetColorTex(), rt->GetDepthTex(), - (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, - dof_debug_data.f2.focus, dof_debug_data.f2.focus_range, - fuzzing_range, dof_debug_data.f2.ratio); - use_dof_f2 = true; - } - } - } - 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); - renderer::DOF3::apply_f2(this, rt, buf, rt->GetColorTex(), rt->GetDepthTex(), - (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, - dof_pv_data.f2.focus, dof_pv_data.f2.focus_range, - fuzzing_range, dof_pv_data.f2.ratio); - enum_or(dof_debug_data.flags, DOF_DEBUG_ENABLE_DOF); - dof_debug_data.f2 = dof_pv_data.f2; - use_dof_f2 = true; - } - else - enum_and(dof_debug_data.flags, ~DOF_DEBUG_ENABLE_DOF); -} - -void post_process_dof::init_fbo(int32_t width, int32_t height) { - if (!this || (this->width == width && this->height == height)) - return; - - post_process_dof_free_fbo(this); - - this->width = width; - this->height = height; - int32_t w20 = max_def(width / 20, 1); - int32_t h20 = max_def(height / 20, 1); - int32_t w2 = max_def(width / 2, 1); - int32_t h2 = max_def(height / 2, 1); - glGenTextures(6, textures); - gl_state_bind_texture_2d(textures[0]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); - fbo[0].init_data(w20, h20, &textures[0], 1, 0); - gl_state_bind_texture_2d(textures[1]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); - fbo[1].init_data(w20, h20, &textures[1], 1, 0); - gl_state_bind_texture_2d(textures[2]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); - gl_state_bind_texture_2d(textures[3]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); - fbo[2].init_data(w2, h2, &textures[2], 2, 0); - gl_state_bind_texture_2d(textures[4]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); - gl_state_bind_texture_2d(textures[5]); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w2, h2); - fbo[3].init_data(w2, h2, &textures[4], 2, 0); - - vec2 data[50] = {}; - post_process_dof_calculate_texcoords(data, 3.0f); - common_ubo.Create(sizeof(dof_common_shader_data)); - texcoords_ubo.Create(sizeof(data), data); - - glGenSamplers(2, samplers); - glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenVertexArrays(1, &vao); -} - -void dof_debug_get(dof_debug* debug) { - if (debug) - *debug = dof_debug_data; -} - -void dof_debug_set(dof_debug* debug) { - if (debug) - dof_debug_data = *debug; - else - dof_debug_data = dof_debug_default; -} - -void dof_pv_get(dof_pv* pv) { - if (pv) - *pv = dof_pv_data; -} - -void dof_pv_set(dof_pv* pv) { - if (pv) - dof_pv_data = *pv; - else - dof_pv_data = dof_pv_default; -} - -static void post_process_dof_calculate_texcoords(vec2* data, float_t size) { - size_t i; - size_t j; - float_t v6; - float_t v7; - float_t v8; - float_t v9; - float_t v11; - - const float_t t = (float_t)(1.0 / 3.0); - size *= 3.0f; - for (i = 0; i < 7; i++) { - v6 = (float_t)i * t - 1.0f; - for (j = 0; j < 7; j++) { - v7 = (float_t)j * t - 1.0f; - if (-v6 >= v7) { - if (v7 < v6) { - v8 = -v7; - v9 = (v6 / v7) + 4.0f; - } - else if (v6 == 0.0f) { - v8 = 0.0f; - v9 = 0.0f; - } - else { - v8 = -v6; - v9 = 6.0f - (v7 / v6); - } - } - else if (v6 < v7) { - v8 = (float_t)j * t - 1.0f; - v9 = v6 / v7; - } - else { - v8 = (float_t)i * t - 1.0f; - v9 = 2.0f - (v7 / v6); - } - v8 *= size; - v11 = v9 * (float_t)(M_PI * 0.25); - - *data++ = vec2(cosf(v11), sinf(v11)) * v8; - } - } -} - -static void post_process_dof_free_fbo(post_process_dof* dof) { - if (dof->vao) { - glDeleteVertexArrays(1, &dof->vao); - dof->vao = 0; - } - - if (dof->samplers[0]) { - glDeleteSamplers(2, dof->samplers); - dof->samplers[0] = 0; - } - - dof->texcoords_ubo.Destroy(); - dof->common_ubo.Destroy(); - - if (dof->textures[0]) { - glDeleteTextures(6, dof->textures); - dof->textures[0] = 0; - } -} - -namespace renderer { - void DOF3::apply_f2(post_process_dof* dof, RenderTexture* rt, - RenderTexture* buf, 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_state_begin_event("renderer::DOF3::apply_f2"); - gl_state_disable_blend(); - gl_state_set_depth_mask(GL_FALSE); - gl_state_set_depth_func(GL_ALWAYS); - update_data(dof, min_distance, max_distance, - fov, focus, 0.0f, 1.0f, focus_range, fuzzing_range, ratio); - - uniform_value[U_DOF] = 1; - - gl_state_bind_vertex_array(dof->vao); - render_tiles(dof, depth_texture, true); - downsample(dof, color_texture, depth_texture, true); - main_filter(dof, true); - upsample(dof, rt, buf, color_texture, depth_texture, true); - - shader::unbind(); - for (int32_t i = 0; i < 8; i++) { - gl_state_bind_sampler(i, 0); - gl_state_active_bind_texture_2d(i, 0); - } - gl_state_bind_vertex_array(0); - gl_state_end_event(); - } - - void DOF3::apply_physical(post_process_dof* dof, RenderTexture* rt, - RenderTexture* buf, 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_state_begin_event("renderer::DOF3::apply_physical"); - gl_state_disable_blend(); - gl_state_set_depth_mask(GL_FALSE); - gl_state_set_depth_func(GL_ALWAYS); - update_data(dof, min_distance, max_distance, - fov, focus, focal_length, f_number, 0.0f, 0.1f, 0.0f); - - uniform_value[U_DOF] = 0; - - gl_state_bind_vertex_array(dof->vao); - render_tiles(dof, depth_texture, false); - downsample(dof, color_texture, depth_texture, false); - main_filter(dof, false); - upsample(dof, rt, buf, color_texture, depth_texture, false); - - shader::unbind(); - for (int32_t i = 0; i < 8; i++) { - gl_state_bind_sampler(i, 0); - gl_state_active_bind_texture_2d(i, 0); - } - gl_state_bind_vertex_array(0); - gl_state_end_event(); - } - - void DOF3::render_tiles(post_process_dof* dof, GLuint depth_texture, bool f2) { - gl_state_begin_event("renderer::DOF3::render_tiles"); - gl_state_bind_framebuffer(dof->fbo[0].buffer); - glViewport(0, 0, dof->fbo[0].width, dof->fbo[0].height); - uniform_value[U_DOF_STAGE] = 0; - shaders_ft.set(SHADER_FT_DOF); - dof->common_ubo.Bind(0); - gl_state_active_bind_texture_2d(0, depth_texture); - gl_state_bind_sampler(0, dof->samplers[1]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - gl_state_bind_framebuffer(dof->fbo[1].buffer); - glViewport(0, 0, dof->fbo[1].width, dof->fbo[1].height); - uniform_value[U_DOF_STAGE] = 1; - shaders_ft.set(SHADER_FT_DOF); - gl_state_active_bind_texture_2d(0, dof->textures[0]); - gl_state_bind_sampler(0, dof->samplers[1]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - gl_state_end_event(); - - } - - void DOF3::downsample(post_process_dof* dof, - GLuint color_texture, GLuint depth_texture, bool f2) { - gl_state_begin_event("renderer::DOF3::downsample"); - gl_state_bind_framebuffer(dof->fbo[2].buffer); - glViewport(0, 0, dof->fbo[2].width, dof->fbo[2].height); - uniform_value[U_DOF_STAGE] = 2; - shaders_ft.set(SHADER_FT_DOF); - dof->common_ubo.Bind(0); - gl_state_active_bind_texture_2d(0, depth_texture); - gl_state_bind_sampler(0, dof->samplers[1]); - gl_state_active_bind_texture_2d(1, color_texture); - gl_state_bind_sampler(1, dof->samplers[0]); - gl_state_active_bind_texture_2d(2, dof->textures[1]); - gl_state_bind_sampler(2, dof->samplers[1]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - gl_state_end_event(); - } - - void DOF3::main_filter(post_process_dof* dof, bool f2) { - gl_state_begin_event("renderer::DOF3::main_filter"); - gl_state_bind_framebuffer(dof->fbo[3].buffer); - glViewport(0, 0, dof->fbo[3].width, dof->fbo[3].height); - uniform_value[U_DOF_STAGE] = 3; - shaders_ft.set(SHADER_FT_DOF); - dof->common_ubo.Bind(0); - dof->texcoords_ubo.Bind(1); - gl_state_active_bind_texture_2d(0, dof->textures[3]); - gl_state_bind_sampler(0, dof->samplers[1]); - gl_state_active_bind_texture_2d(1, dof->textures[2]); - gl_state_bind_sampler(1, dof->samplers[1]); - gl_state_active_bind_texture_2d(2, dof->textures[1]); - gl_state_bind_sampler(2, dof->samplers[1]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - gl_state_end_event(); - } - - void DOF3::upsample(post_process_dof* dof, RenderTexture* rt, RenderTexture* buf, - GLuint color_texture, GLuint depth_texture, bool f2) { - gl_state_begin_event("renderer::DOF3::upsample"); - buf->Bind(); - glViewport(0, 0, dof->width, dof->height); - uniform_value[U_DOF_STAGE] = 4; - shaders_ft.set(SHADER_FT_DOF); - dof->common_ubo.Bind(0); - gl_state_active_bind_texture_2d(0, dof->textures[4]); - gl_state_bind_sampler(0, dof->samplers[1]); - gl_state_active_bind_texture_2d(1, dof->textures[5]); - gl_state_bind_sampler(1, dof->samplers[1]); - gl_state_active_bind_texture_2d(2, dof->textures[1]); - gl_state_bind_sampler(2, dof->samplers[1]); - gl_state_active_bind_texture_2d(3, color_texture); - gl_state_bind_sampler(3, dof->samplers[1]); - gl_state_active_bind_texture_2d(4, depth_texture); - gl_state_bind_sampler(4, dof->samplers[1]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - fbo::blit(buf->fbos[0], rt->fbos[0], - 0, 0, buf->GetWidth(), buf->GetHeight(), - 0, 0, rt->GetWidth(), rt->GetHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR); - gl_state_end_event(); - } - - void DOF3::update_data(post_process_dof* dof, 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) - fl = dist + 0.1f; - fl = fl / (dist - fl) * fl / f_number; - - dof_common_shader_data shader_data = {}; - shader_data.g_depth_params.x = 1.0f / (min_dist * max_dist) * (min_dist - max_dist); - shader_data.g_depth_params.y = 1.0f / min_dist; - shader_data.g_depth_params.z = -((fl * dist * (min_dist - max_dist)) * (1.0f / (min_dist * max_dist))); - shader_data.g_depth_params.w = (1.0f - 1.0f / min_dist * dist) * fl; - shader_data.g_spread_scale.x = 720.0f / (tanf(fov * 0.5f) * (min_dist * 2.0f)); - shader_data.g_spread_scale.y = shader_data.g_spread_scale.x * (float_t)(1.0 / 3.0); - shader_data.g_spread_scale.z = (float_t)(1.0 / 3.0); - shader_data.g_spread_scale.w = 3.0f; - shader_data.g_depth_params2.x = dist; - 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; - dof->common_ubo.WriteMemory(shader_data); - } -} diff --git a/src/CRE/post_process/dof.hpp b/src/CRE/post_process/dof.hpp deleted file mode 100644 index 6f06ed2b..00000000 --- a/src/CRE/post_process/dof.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../../KKdLib/default.hpp" -#include "../../KKdLib/vec.hpp" -#include "../GL/uniform_buffer.hpp" -#include "../camera.hpp" -#include "../fbo.hpp" -#include "../render_texture.hpp" -#include "../shared.hpp" - -enum dof_debug_flags { - DOF_DEBUG_USE_UI_PARAMS = 0x01, - DOF_DEBUG_ENABLE_DOF = 0x02, - DOF_DEBUG_ENABLE_PHYS_DOF = 0x04, - DOF_DEBUG_AUTO_FOCUS = 0x08, -}; - -struct dof_f2 { - float_t focus; - float_t focus_range; - float_t fuzzing_range; - float_t ratio; -}; - -struct dof_debug { - dof_debug_flags flags; - float_t focus; - float_t focal_length; - float_t f_number; - dof_f2 f2; -}; - -struct dof_pv { - bool enable; - dof_f2 f2; -}; - -struct post_process_dof { - int32_t width; - int32_t height; - GLuint textures[6]; - fbo fbo[4]; - GLuint samplers[2]; - GLuint vao; - GL::UniformBuffer common_ubo; - GL::UniformBuffer texcoords_ubo; - - post_process_dof(); - ~post_process_dof(); - - void apply(RenderTexture* rt, RenderTexture* buf, camera* cam); - void init_fbo(int32_t width, int32_t height); -}; - -extern dof_debug dof_debug_data; -extern dof_pv dof_pv_data; - -extern void dof_debug_get(dof_debug* debug); -extern void dof_debug_set(dof_debug* debug = 0); -extern void dof_pv_get(dof_pv* pv); -extern void dof_pv_set(dof_pv* pv = 0); diff --git a/src/CRE/post_process/exposure.cpp b/src/CRE/post_process/exposure.cpp deleted file mode 100644 index 74874108..00000000 --- a/src/CRE/post_process/exposure.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "exposure.hpp" -#include "../rob/rob.hpp" -#include "../fbo.hpp" -#include "../gl_state.hpp" -#include "../post_process.hpp" -#include "../shader_ft.hpp" - -struct exposure_measure_shader_data { - vec4 g_spot_weight; - vec4 g_spot_coefficients[32]; -}; - -post_process_exposure_chara_data::post_process_exposure_chara_data() : spot_weight(), query(), query_data() { - for (GLuint& i : query_data) - i = -1; -} - -post_process_exposure::post_process_exposure() : exposure_history_counter(), -chara_data(), query_index() { - chara_data = new post_process_exposure_chara_data[ROB_CHARA_COUNT]; - exposure_measure_ubo.Create(sizeof(exposure_measure_shader_data)); -} - -post_process_exposure::~post_process_exposure() { - if (!this) - return; - - exposure_measure_ubo.Destroy(); - - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) - glDeleteQueries(3, chara_data[i].query); - - delete chara_data; -} - -void post_process_exposure::get_exposure(camera* cam, int32_t render_width, - int32_t render_height, bool reset_exposure, GLuint in_tex_0, GLuint in_tex_1) { - bool v2 = false; - if (!reset_exposure) { - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { - memset(&chara_data[i].spot_coefficients, - 0, sizeof(chara_data[i].spot_coefficients)); - chara_data[i].spot_weight = 0.0f; - } - - post_process_exposure_chara_data* v6 = chara_data; - float_t v18 = (float_t)render_height / (float_t)render_width; - float_t v20 = powf(tanf((float_t)(cam->fov_rad * 0.5f)) * 3.4f, 2.0f); - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, v6++) { - rob_chara* rob_chr = rob_chara_array_get(i); - if (!rob_chr || !rob_chr->is_visible()) - continue; - - vec4 v34 = { 0.05f, 0.0f, -0.04f, 1.0f }; - vec4 v33 = { 1.0f, 0.0f, 0.0f, 0.0f }; - - mat4 v44 = mat4_identity; - rob_chr->sub_1405163C0(4, v44); - - mat4 v42; - mat4 v43; - mat4_mul(&v44, &cam->view, &v42); - mat4_mul(&v42, &cam->projection, &v43); - - vec4 v41; - vec4 v40; - mat4_transform_vector(&v42, &v34, &v41); - mat4_transform_vector(&v43, &v34, &v40); - - float_t v12 = 1.0f / v40.w; - float_t v13 = v40.x * v12; - float_t v14 = v40.y * v12; - if (v41.z >= 0.0f || fabsf(v13) >= 1.0f || fabsf(v14) >= 1.0f) - continue; - - float_t v31 = 0.5f - (fabsf(v14) - 1.0f) * 2.5f; - float_t v32 = 0.5f - (fabsf(v13) - 1.0f) * 2.5f; - - float_t v16; - if (v32 <= v31) - v16 = v32; - else - v16 = v31; - - if (v16 > 1.0f) - v16 = 1.0f; - - vec4 v39; - mat4_transform_vector(&v42, &v33, &v39); - - float_t v17 = (v39.z + 1.0f) * 0.5f; - if (v17 > 0.8f) - v17 = 0.8f; - else if (v17 < 0.2f) - v17 = 0.0f; - - float_t v21 = 0.25f / sqrtf(powf(v20 * 3.4f, 2.0f) * (v41.z * v41.z)); - float_t v22; - if (v21 < 0.055f) { - v22 = (v21 - 0.035f) * 50.0f; - if (v22 < 0.0f) - v22 = 0.0f; - } - else if (v21 > 0.5f) { - v22 = 1.0f - (v21 - 0.5f) * 3.3333333f; - if (v22 < 0.0f) - v22 = 0.0f; - } - else - v22 = 1.0f; - - v6->spot_coefficients[0].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[0].y = (v14 + v21 * 0.1f + 1.0f) * 0.5f; - v6->spot_coefficients[0].z = 0.0f; - v6->spot_coefficients[0].w = 4.0f; - v6->spot_coefficients[1].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[1].y = (v14 - v21 * 0.3f + 1.0f) * 0.5f; - v6->spot_coefficients[1].z = 0.0f; - v6->spot_coefficients[1].w = 4.0f; - v6->spot_coefficients[2].x = (v13 + v21 * -0.5f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[2].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; - v6->spot_coefficients[2].z = 0.0f; - v6->spot_coefficients[2].w = 3.0f; - v6->spot_coefficients[3].x = (v13 - v21 * 0.6f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[3].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; - v6->spot_coefficients[3].z = 0.0f; - v6->spot_coefficients[3].w = 2.0f; - v6->spot_coefficients[4].x = (v13 + v21 * 0.6f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[4].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; - v6->spot_coefficients[4].z = 0.0f; - v6->spot_coefficients[4].w = 2.0f; - v6->spot_coefficients[5].x = (v13 + v21 * 0.5f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[5].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; - v6->spot_coefficients[5].z = 0.0f; - v6->spot_coefficients[5].w = 3.0f; - v6->spot_coefficients[6].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; - v6->spot_coefficients[6].y = (v14 - v21 * 0.8f + 1.0f) * 0.5f; - v6->spot_coefficients[6].z = 0.0f; - v6->spot_coefficients[6].w = 3.0f; - v6->spot_weight = v16 * 1.6f * v17 * v22; - if (v6->spot_weight > 0.0f && !v6->query_data[query_index]) - v2 = true; - } - } - - if (!v2 || reset_exposure) { - exposure_measure_shader_data exposure_measure = {}; - exposure_measure.g_spot_weight = { - chara_data[0].spot_weight, - chara_data[1].spot_weight, - chara_data[2].spot_weight, - chara_data[3].spot_weight - }; - - post_process_exposure_chara_data* chara_data = this->chara_data; - 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]; - exposure_measure_ubo.WriteMemory(exposure_measure); - - if (reset_exposure) - glViewport(0, 0, 32, 1); - else - glViewport(exposure_history_counter, 0, 1, 1); - exposure_history.Bind(); - - uniform_value[U_EXPOSURE] = 1; - shaders_ft.set(SHADER_FT_EXPOSURE); - exposure_measure_ubo.Bind(1); - gl_state_active_bind_texture_2d(0, in_tex_0); - gl_state_active_bind_texture_2d(1, in_tex_1); - RenderTexture::DrawQuad(&shaders_ft, reset_exposure ? 32 : 1, 1, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - exposure_history_counter++; - exposure_history_counter %= 32; - } - - glViewport(0, 0, 1, 1); - exposure.Bind(); - uniform_value[U_EXPOSURE] = 2; - shaders_ft.set(SHADER_FT_EXPOSURE); - gl_state_active_bind_texture_2d(0, exposure_history.GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, 1, 1, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); -} - -void post_process_exposure::get_exposure_chara_data(void* pp_data, camera* cam) { - shader::unbind(); - - post_process* pp = (post_process*)pp_data; - - gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_state_set_depth_mask(GL_FALSE); - gl_state_disable_cull_face(); - - shaders_ft.set(SHADER_FT_SUN_NO_TEXTURED); - gl_state_bind_vertex_array(pp->query_vao); - pp->sun_quad_ubo.Bind(0); - - post_process_exposure_chara_data* chara = chara_data; - int32_t query_index = (this->query_index + 1) % 3; - this->query_index = query_index; - int32_t next_query_index = (query_index + 2) % 3; - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, chara++) { - rob_chara* rob_chr = rob_chara_array_get(i); - if (!rob_chr || !rob_chr->is_visible()) - continue; - - float_t max_face_depth = rob_chr->get_max_face_depth(); - - mat4 mat = mat4_identity; - rob_chr->sub_1405163C0(4, mat); - mat4_mul(&mat, &cam->view, &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, &cam->projection, &mat); - - sun_quad_shader_data shader_data = {}; - 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; - shader_data.g_emission = 0.0f; - pp->sun_quad_ubo.WriteMemory(shader_data); - - glBeginQuery(GL_SAMPLES_PASSED, chara->query[next_query_index]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glEndQuery(GL_SAMPLES_PASSED); - - if (chara->query_data[next_query_index] == -1) - chara->query_data[next_query_index] = 0; - - if (chara->query_data[query_index] != -1) { - int32_t res = 0; - glGetQueryObjectiv(chara->query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); - if (res) - glGetQueryObjectuiv(chara->query[query_index], GL_QUERY_RESULT, chara->query_data); - else - chara->query_data[query_index] = 0; - } - } - - gl_state_bind_vertex_array(0); - - gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl_state_set_depth_mask(GL_TRUE); - gl_state_enable_cull_face(); -} - -void post_process_exposure::init_fbo() { - if (!this) - return; - - exposure_history_counter = 0; - - if (!exposure_history.color_texture) - exposure_history.Init(32, 1, 0, GL_R32F, 0); - if (!exposure.color_texture) - exposure.Init(2, 2, 0, GL_R32F, 0); - - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) - if (!chara_data[i].query[0]) - glGenQueries(3, chara_data[i].query); -} diff --git a/src/CRE/post_process/exposure.hpp b/src/CRE/post_process/exposure.hpp deleted file mode 100644 index 99b8a37b..00000000 --- a/src/CRE/post_process/exposure.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../../KKdLib/default.hpp" -#include "../../KKdLib/vec.hpp" -#include "../GL/uniform_buffer.hpp" -#include "../camera.hpp" -#include "../render_texture.hpp" -#include "../shared.hpp" - -struct post_process_exposure_chara_data { - vec4 spot_coefficients[8]; - float_t spot_weight; - GLuint query[3]; - GLuint query_data[3]; - - post_process_exposure_chara_data(); -}; - -struct post_process_exposure { - RenderTexture exposure_history; - RenderTexture exposure; - int32_t exposure_history_counter; - post_process_exposure_chara_data* chara_data; - int32_t query_index; - GL::UniformBuffer exposure_measure_ubo; - - post_process_exposure(); - ~post_process_exposure(); - - void get_exposure(camera* cam, int32_t render_width, int32_t render_height, - bool reset_exposure, GLuint in_tex_0, GLuint in_tex_1); - void get_exposure_chara_data(void* pp, camera* cam); - void init_fbo(); -}; diff --git a/src/CRE/post_process/tone_map.cpp b/src/CRE/post_process/tone_map.cpp deleted file mode 100644 index aef4daee..00000000 --- a/src/CRE/post_process/tone_map.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "tone_map.hpp" -#include "../fbo.hpp" -#include "../gl_state.hpp" -#include "../post_process.hpp" -#include "../render_context.hpp" -#include "../shader_ft.hpp" - -static void post_process_tone_map_calculate_data(post_process_tone_map* tm); -static void post_process_tone_map_calculate_tex(post_process_tone_map* tm); - -extern render_context* rctx_ptr; - -post_process_tone_map::post_process_tone_map() : saturate_lock(), lens_shaft_scale(), -lens_flare_power(), lens_flare_appear_power(), saturate_index(), scene_fade_index(), -tone_trans_index(), saturate_coeff(), scene_fade_alpha(), scene_fade_blend_func(), -tone_map_method(), update(), shader_data(), tone_map_ubo(), tone_map_tex() { - exposure = 2.0f; - exposure_rate = 1.0f; - auto_exposure = true; - gamma = 1.0f; - gamma_rate = 1.0f; - saturate_power = 1; - - for (int32_t i = 0; i < 2; i++) { - reset_saturate_coeff(i, 0); - reset_scene_fade(i); - reset_tone_trans(i); - } - - update_lut = true; - lens_shaft_inv_scale = 1.0f; - lens_flare = 1.0f; - lens_shaft = 1.0f; - lens_ghost = 1.0f; - - tone_map_ubo.Create(sizeof(post_process_tone_map_shader_data)); -} - -post_process_tone_map::~post_process_tone_map() { - if (!this) - return; - - tone_map_ubo.Destroy(); - glDeleteTextures(1, &tone_map_tex); -} - -void post_process_tone_map::apply(RenderTexture* in_tex, texture* light_proj_tex, texture* back_2d_tex, - RenderTexture* rt, RenderTexture* buf_rt,/* RenderTexture* contour_rt,*/ - GLuint in_tex_0, GLuint in_tex_1, int32_t npr_param, void* pp_data) { - if (!this) - return; - - gl_state_begin_event("PostProcess::tone_map"); - post_process* pp = (post_process*)pp_data; - - set_lens_flare_power(pp->lens_flare_power); - set_lens_flare_appear_power(pp->lens_flare_appear_power); - - post_process_tone_map_calculate_data(this); - - if (update_lut) { - update_lut = false; - saturate_lock = false; - - post_process_tone_map_calculate_tex(this); - - if (GLAD_GL_VERSION_4_5) - glTextureSubImage2D(tone_map_tex, 0, 0, 0, - 16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); - else { - gl_state_bind_texture_2d(tone_map_tex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - 16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); - gl_state_bind_texture_2d(0); - } - } - - uniform_value[U_TONE_MAP] = (int32_t)tone_map_method; - uniform_value[U_FLARE] = 0; - uniform_value[U_SCENE_FADE] = scene_fade_alpha[scene_fade_index] > 0.009999999f ? 1 : 0; - uniform_value[U_AET_BACK] = 0; - uniform_value[U_LIGHT_PROJ] = 0; - //uniform_value[U25] = 0; - - gl_state_active_bind_texture_2d(0, in_tex->GetColorTex()); - gl_state_active_bind_texture_2d(1, in_tex_0); - gl_state_active_bind_texture_2d(2, tone_map_tex); - gl_state_active_bind_texture_2d(3, in_tex_1); - gl_state_active_bind_texture_2d(4, rctx_ptr->empty_texture_2d); - gl_state_active_bind_texture_2d(5, rctx_ptr->empty_texture_2d); - gl_state_active_bind_texture_2d(6, rctx_ptr->empty_texture_2d); - - if (back_2d_tex) { - gl_state_active_bind_texture_2d(6, back_2d_tex->tex); - uniform_value[U_AET_BACK] = 1; - } - - if (light_proj_tex) { - gl_state_active_bind_texture_2d(6, light_proj_tex->tex); - uniform_value[U_LIGHT_PROJ] = 1; - } - - shader_data.g_texcoord_transforms[0] = { 1.0f, 0.0f, 0.0f, 0.0f }; - shader_data.g_texcoord_transforms[1] = { 0.0f, 1.0f, 0.0f, 0.0f }; - 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 }; - - if (pp->lens_flare_texture) { - static const vec4 border_color = 0.0f; - - const float_t aspect = (float_t)pp->render_height / (float_t)pp->render_width; - - uniform_value[U_FLARE] = 1; - gl_state_active_bind_texture_2d(4, pp->lens_flare_texture); - gl_state_bind_sampler(4, pp->samplers[2]); - mat4 mat; - mat4_translate(0.5f, 0.5f, 0.0f, &mat); - mat4_scale_rot(&mat, 0.75f, 0.75f, 1.0f, &mat); - mat4_mul_rotate_z(&mat, (pp->lens_flare_pos.x / (float_t)pp->render_width) - * 25.0f * DEG_TO_RAD_FLOAT, &mat); - mat4_mul_translate(&mat, -((1.0f / (float_t)pp->render_width) * pp->lens_flare_pos.x), - (pp->lens_flare_pos.y - (float_t)pp->render_height) - * (1.0f / (float_t)pp->render_width), 0.0f, &mat); - mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); - mat4_transpose(&mat, &mat); - shader_data.g_texcoord_transforms[4] = mat.row0; - shader_data.g_texcoord_transforms[5] = mat.row1; - - if (pp->lens_shaft_scale < 50.0f) { - uniform_value[U_FLARE] = 2; - gl_state_active_bind_texture_2d(5, pp->lens_shaft_texture); - gl_state_bind_sampler(5, pp->samplers[2]); - mat4_translate(0.5f, 0.5f, 0.0f, &mat); - mat4_scale_rot(&mat, pp->lens_shaft_scale, pp->lens_shaft_scale, 1.0f, &mat); - mat4_mul_rotate_z(&mat, (pp->lens_flare_pos.x / (float_t)pp->render_width) - * 60.0f * DEG_TO_RAD_FLOAT, &mat); - mat4_mul_translate(&mat, -((1.0f / (float_t)pp->render_width) * pp->lens_flare_pos.x), - (pp->lens_flare_pos.y - (float_t)pp->render_height) - * (1.0f / (float_t)pp->render_width), 0.0f, &mat); - mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); - mat4_transpose(&mat, &mat); - shader_data.g_texcoord_transforms[6] = mat.row0; - shader_data.g_texcoord_transforms[7] = mat.row1; - } - else { - 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 { - 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 }; - 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 }; - } - - if (npr_param == 1) { - /*gl_state_active_bind_texture_2d(16, contour_rt->GetColorTex()); - gl_state_bind_sampler(16, pp->samplers[1]); - gl_state_active_bind_texture_2d(17, contour_rt->GetDepthTex()); - gl_state_bind_sampler(17, pp->samplers[1]);*/ - gl_state_active_bind_texture_2d(14, rt->GetDepthTex()); - gl_state_bind_sampler(14, pp->samplers[1]); - } - - tone_map_ubo.WriteMemory(shader_data); - - buf_rt->Bind(); - buf_rt->SetViewport(); - shaders_ft.set(SHADER_FT_TONEMAP); - tone_map_ubo.Bind(1); - RenderTexture::Draw(&shaders_ft); - gl_state_active_bind_texture_2d(2, 0); - - fbo::blit(buf_rt->fbos[0], rt->fbos[0], - 0, 0, buf_rt->GetWidth(), buf_rt->GetHeight(), - 0, 0, rt->GetWidth(), rt->GetHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR); - gl_state_end_event(); -} - -bool post_process_tone_map::get_auto_exposure() { - return auto_exposure; -} - -float_t post_process_tone_map::get_exposure() { - return exposure; -} - -float_t post_process_tone_map::get_exposure_rate() { - return exposure_rate; -} - -float_t post_process_tone_map::get_gamma() { - return gamma; -} - -float_t post_process_tone_map::get_gamma_rate() { - return gamma_rate; -} - -vec3 post_process_tone_map::get_lens() { - vec3 value; - value.x = lens_flare; - value.y = lens_shaft; - value.z = lens_ghost; - return value; -} - -float_t post_process_tone_map::get_lens_flare_appear_power() { - return lens_flare_appear_power; -} - -float_t post_process_tone_map::get_lens_flare_power() { - return lens_flare_power; -} - -float_t post_process_tone_map::get_saturate_coeff() { - return saturate_coeff[0]; -} - -int32_t post_process_tone_map::get_saturate_power() { - return saturate_power; -} - -vec4 post_process_tone_map::get_scene_fade() { - vec4 scene_fade; - *(vec3*)&scene_fade = scene_fade_color[0]; - scene_fade.w = scene_fade_alpha[0]; - return scene_fade; -} - -float_t post_process_tone_map::get_scene_fade_alpha() { - return scene_fade_alpha[0]; -} - -int32_t post_process_tone_map::get_scene_fade_blend_func() { - return scene_fade_blend_func[0]; -} - -vec3 post_process_tone_map::get_scene_fade_color() { - return scene_fade_color[0]; -} - -::tone_map_method post_process_tone_map::get_tone_map_method() { - return tone_map_method; -} - -void post_process_tone_map::get_tone_trans(vec3& start, vec3& end) { - start = tone_trans_start[0]; - end = tone_trans_end[0]; -} - -void post_process_tone_map::init_fbo() { - if (!this) - return; - - if (!tone_map_tex) { - if (GLAD_GL_VERSION_4_5) { - glCreateTextures(GL_TEXTURE_2D, 1, &tone_map_tex); - - glTextureStorage2D(tone_map_tex, 1, GL_RG16F, 16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES, 1); - glTextureParameteri(tone_map_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTextureParameteri(tone_map_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - const GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; - glTextureParameteri(tone_map_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTextureParameteri(tone_map_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTextureParameteriv(tone_map_tex, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - } - else { - glGenTextures(1, &tone_map_tex); - - gl_state_bind_texture_2d(tone_map_tex); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, 16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - const GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); - gl_state_bind_texture_2d(0); - } - } -} - -void post_process_tone_map::reset_saturate_coeff(int32_t index, bool lock) { - set_saturate_coeff(1.0f, index, lock); - - if (index == 1) - saturate_index = 0; -} - -void post_process_tone_map::reset_scene_fade(int32_t index) { - scene_fade_color[index] = 0.0f; - scene_fade_alpha[index] = 0.0f; - scene_fade_blend_func[index] = 0; - - if (index == 1) - scene_fade_index = 0; - update = true; -} - -void post_process_tone_map::reset_tone_trans(int32_t index) { - tone_trans_scale[index] = 1.0f; - tone_trans_offset[index] = 0.0f; - tone_trans_start[index] = 0.0f; - tone_trans_end[index] = 1.0f; - - if (index == 1) - tone_trans_index = 0; - update = true; -} - -void post_process_tone_map::set_auto_exposure(bool value) { - auto_exposure = value; -} - -void post_process_tone_map::set_exposure(float_t value) { - exposure = value; -} - -void post_process_tone_map::set_exposure_rate(float_t value) { - exposure_rate = value; -} - -void post_process_tone_map::set_gamma(float_t value) { - if (value != gamma) { - gamma = value; - update_lut = true; - } -} - -void post_process_tone_map::set_gamma_rate(float_t value) { - if (value != gamma_rate) { - gamma_rate = value; - update_lut = true; - } -} - -void post_process_tone_map::set_lens(vec3 value) { - lens_flare = value.x; - lens_shaft = value.y; - lens_ghost = value.z; - update = true; -} - -void post_process_tone_map::set_lens_flare_appear_power(float_t value) { - lens_flare_appear_power = value; -} - -void post_process_tone_map::set_lens_flare_power(float_t value) { - lens_flare_power = value; -} - -void post_process_tone_map::set_saturate_coeff(float_t value, int32_t index, bool lock) { - if (saturate_lock) - return; - - saturate_coeff[index] = value; - update_lut = true; - update = true; - - if (lock) { - saturate_lock = true; - saturate_index = 0; - } - else if (index == 1) - saturate_index = 1; -} - -void post_process_tone_map::set_saturate_power(int32_t value) { - if (value != saturate_power) { - saturate_power = value; - update_lut = true; - } -} - -void post_process_tone_map::set_scene_fade(const vec4& value, int32_t index) { - scene_fade_color[index] = *(vec3*)&value; - scene_fade_alpha[index] = value.w; - - if (index == 1) - scene_fade_index = 1; - update = true; -} - -void post_process_tone_map::set_scene_fade_alpha(float_t value, int32_t index) { - scene_fade_alpha[index] = value; - - if (index == 1) - scene_fade_index = 1; - update = true; -} - -void post_process_tone_map::set_scene_fade_blend_func(int32_t value, int32_t index) { - if (value < 0 || value > 2) - return; - - scene_fade_blend_func[index] = value; - - if (index == 1) - scene_fade_index = 1; - update = true; -} - - -void post_process_tone_map::set_scene_fade_color(const vec3& value, int32_t index) { - scene_fade_color[index] = value; - - if (index == 1) - scene_fade_index = 1; - update = true; -} - -void post_process_tone_map::set_tone_map_method(::tone_map_method value) { - tone_map_method = value; -} - -void post_process_tone_map::set_tone_trans(const vec3& start, const vec3& end, int32_t index) { - for (int32_t i = 0; i < 3; i++) - if (fabsf((&end.x)[i] - (&start.x)[i]) < 0.0001f) { - reset_tone_trans(0); - return; - } - - tone_trans_end[index] = end; - tone_trans_start[index] = start; - - vec3 scale = vec3::rcp(end - start); - tone_trans_scale[index] = scale; - tone_trans_offset[index] = -(scale * start); - - if (index == 1) - tone_trans_index = 1; - update = true; -} - -static void post_process_tone_map_calculate_data(post_process_tone_map* tm) { - int32_t scene_fade_blend_func = tm->scene_fade_blend_func[tm->scene_fade_index]; - - post_process_tone_map_shader_data* tmshd = &tm->shader_data; - tmshd->g_exposure.x = tm->exposure * tm->exposure_rate; - tmshd->g_exposure.y = 0.0625f; - tmshd->g_exposure.z = tm->exposure * tm->exposure_rate * 0.5f; - tmshd->g_exposure.w = tm->auto_exposure ? 1.0f : 0.0f; - tmshd->g_flare_coef.x = (tm->lens_flare * 2.0f) * (tm->lens_flare_appear_power + tm->lens_flare_power); - tmshd->g_flare_coef.y = tm->lens_shaft * 2.0f; - tmshd->g_flare_coef.z = 0.0f; - tmshd->g_flare_coef.w = 0.0f; - *(vec3*)&tmshd->g_fade_color = tm->scene_fade_color[tm->scene_fade_index]; - tmshd->g_fade_color.w = tm->scene_fade_alpha[tm->scene_fade_index]; - if (scene_fade_blend_func == 1 || scene_fade_blend_func == 2) - *(vec3*)&tmshd->g_fade_color = *(vec3*)&tmshd->g_fade_color * tmshd->g_fade_color.w; - *(vec3*)&tmshd->g_tone_scale = tm->tone_trans_scale[tm->tone_trans_index]; - *(vec3*)&tmshd->g_tone_offset = tm->tone_trans_offset[tm->tone_trans_index]; - tmshd->g_tone_scale.w = (float_t)scene_fade_blend_func; - tmshd->g_tone_offset.w = tm->gamma > 0.0f ? 2.0f / (tm->gamma * 3.0f) : 0.0f; -} - -static void post_process_tone_map_calculate_tex(post_process_tone_map* tm) { - const float_t post_process_tone_map_scale = (float_t)(1.0 / (double_t)POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES); - const int32_t post_process_tone_map_size = 16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES; - - int32_t i, j; - int32_t saturate_power; - float_t saturate_coeff; - - vec2* tex_data = tm->tex_data; - float_t gamma_power, gamma, saturation; - gamma_power = tm->gamma * tm->gamma_rate * 1.5f; - saturate_power = tm->saturate_power; - saturate_coeff = tm->saturate_coeff[tm->saturate_index]; - - tex_data->x = 0.0f; - tex_data->y = 0.0f; - tex_data++; - for (i = 1; i < post_process_tone_map_size; i++, tex_data++) { - gamma = powf(1.0f - expf(-i * post_process_tone_map_scale), gamma_power); - saturation = gamma * 2.0f - 1.0f; - for (j = 0; j < saturate_power; j++) { - saturation *= saturation; - saturation *= saturation; - saturation *= saturation; - saturation *= saturation; - } - - tex_data->x = gamma; - tex_data->y = gamma * saturate_coeff - * ((float_t)POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES / (float_t)i) * (1.0f - saturation); - } -} diff --git a/src/CRE/post_process/tone_map.hpp b/src/CRE/post_process/tone_map.hpp deleted file mode 100644 index 59987691..00000000 --- a/src/CRE/post_process/tone_map.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../../KKdLib/default.hpp" -#include "../../KKdLib/light_param/glow.hpp" -#include "../../KKdLib/vec.hpp" -#include "../GL/uniform_buffer.hpp" -#include "../shared.hpp" -#include "../render_texture.hpp" - -#define POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES 32 - -struct post_process_tone_map_shader_data { - vec4 g_exposure; - vec4 g_flare_coef; - vec4 g_fade_color; - vec4 g_tone_scale; //xyz=tone_scale, w=fade_func - vec4 g_tone_offset; //xyz=tone_offset, w=inv_tone - vec4 g_texcoord_transforms[8]; -}; - -struct post_process_tone_map { - vec2 tex_data[16 * POST_PROCESS_TONE_MAP_SAT_GAMMA_SAMPLES]; - bool update_lut; - bool saturate_lock; - float_t lens_shaft_scale; - float_t lens_shaft_inv_scale; - float_t lens_flare_power; - float_t lens_flare_appear_power; - int32_t saturate_index; - int32_t scene_fade_index; - int32_t tone_trans_index; - float_t saturate_coeff[2]; - vec3 scene_fade_color[2]; - float_t scene_fade_alpha[2]; - int32_t scene_fade_blend_func[2]; - vec3 tone_trans_scale[2]; - vec3 tone_trans_offset[2]; - vec3 tone_trans_start[2]; - vec3 tone_trans_end[2]; - tone_map_method tone_map_method; - float_t exposure; - float_t exposure_rate; - bool auto_exposure; - float_t gamma; - float_t gamma_rate; - int32_t saturate_power; - float_t lens_flare; - float_t lens_shaft; - float_t lens_ghost; - bool update; - post_process_tone_map_shader_data shader_data; - GL::UniformBuffer tone_map_ubo; - GLuint tone_map_tex; - - post_process_tone_map(); - ~post_process_tone_map(); - - void apply(RenderTexture* in_tex, texture* light_proj_tex, texture* back_2d_tex, - RenderTexture* rt, RenderTexture* buf_rt,/* RenderTexture* contour_rt,*/ - GLuint in_tex_0, GLuint in_tex_1, int32_t npr_param, void* pp); - bool get_auto_exposure(); - float_t get_exposure(); - float_t get_exposure_rate(); - float_t get_gamma(); - float_t get_gamma_rate(); - vec3 get_lens(); - float_t get_lens_flare_appear_power(); - float_t get_lens_flare_power(); - float_t get_saturate_coeff(); - int32_t get_saturate_power(); - vec4 get_scene_fade(); - float_t get_scene_fade_alpha(); - int32_t get_scene_fade_blend_func(); - vec3 get_scene_fade_color(); - ::tone_map_method get_tone_map_method(); - void get_tone_trans(vec3& start, vec3& end); - void init_fbo(); - void reset_saturate_coeff(int32_t index, bool lock); - void reset_scene_fade(int32_t index); - void reset_tone_trans(int32_t index); - void set_auto_exposure(bool value); - void set_exposure(float_t value); - void set_exposure_rate(float_t value); - void set_gamma(float_t value); - void set_gamma_rate(float_t value); - void set_lens(vec3 value); - void set_lens_flare_appear_power(float_t value); - void set_lens_flare_power(float_t value); - void set_saturate_coeff(float_t value, int32_t index, bool lock); - void set_saturate_power(int32_t value); - void set_scene_fade(const vec4& value, int32_t index); - void set_scene_fade_alpha(float_t value, int32_t index); - void set_scene_fade_blend_func(int32_t value, int32_t index); - void set_scene_fade_color(const vec3& value, int32_t index); - void set_tone_map_method(::tone_map_method value); - void set_tone_trans(const vec3& start, const vec3& end, int32_t index); -}; diff --git a/src/CRE/post_process/transparency.cpp b/src/CRE/post_process/transparency.cpp deleted file mode 100644 index 28752f2e..00000000 --- a/src/CRE/post_process/transparency.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "transparency.hpp" -#include "../../KKdLib/str_utils.hpp" -#include "../rob/rob.hpp" -#include "../gl_state.hpp" -#include "../shader_ft.hpp" - -static void post_process_transparency_free_fbo(post_process_transparency* transparency); - -post_process_transparency::post_process_transparency() : sampler(), vao() { - -} - -post_process_transparency::~post_process_transparency() { - post_process_transparency_free_fbo(this); -} - -void post_process_transparency::combine(RenderTexture* rt, - RenderTexture* buf_rt, float_t alpha, void* rctx) { - transparency_batch_shader_data shader_data = {}; - shader_data.g_opacity = { alpha, 0.0f, 0.0f, 0.0f }; - ((render_context*)rctx)->transparency_batch_ubo.WriteMemory(shader_data); - - gl_state_disable_blend(); - gl_state_disable_depth_test(); - buf_rt->Bind(); - shaders_ft.set(SHADER_FT_TRANSPARENCY); - ((render_context*)rctx)->transparency_batch_ubo.Bind(0); - gl_state_active_bind_texture_2d(0, fbo.textures[0]); - gl_state_active_bind_texture_2d(1, rt->GetColorTex()); - RenderTexture::DrawCustom(); - gl_state_enable_depth_test(); - - fbo::blit(buf_rt->fbos[0], rt->fbos[0], - 0, 0, buf_rt->GetWidth(), buf_rt->GetHeight(), - 0, 0, rt->GetWidth(), rt->GetHeight(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); -} - -void post_process_transparency::copy(RenderTexture* rt) { - fbo::blit(rt->fbos[0], fbo.buffer, - 0, 0, rt->GetWidth(), rt->GetHeight(), - 0, 0, fbo.width, fbo.height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); -} - -void post_process_transparency::init_fbo(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height) { - if (fbo.textures && (fbo.textures[0] == color_texture - && fbo.textures[1] == depth_texture - && fbo.width == width && fbo.height == height)) - return; - - post_process_transparency_free_fbo(this); - - GLuint color_textures[1]; - color_textures[0] = color_texture; - fbo.init_data(width, height, color_textures, 1, depth_texture); - - glGenSamplers(1, &sampler); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenVertexArrays(1, &vao); -} - -static void post_process_transparency_free_fbo(post_process_transparency* transparency) { - if (transparency->vao) { - glDeleteVertexArrays(1, &transparency->vao); - transparency->vao = 0; - } - - if (transparency->sampler) { - glDeleteSamplers(1, &transparency->sampler); - transparency->sampler = 0; - } - - transparency->fbo.free_data(); -} diff --git a/src/CRE/post_process/transparency.hpp b/src/CRE/post_process/transparency.hpp deleted file mode 100644 index e5cf06e1..00000000 --- a/src/CRE/post_process/transparency.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../../KKdLib/default.hpp" -#include "../../KKdLib/vec.hpp" -#include "../fbo.hpp" -#include "../render_texture.hpp" -#include "../shared.hpp" - -struct post_process_transparency { - fbo fbo; - GLuint sampler; - GLuint vao; - - post_process_transparency(); - ~post_process_transparency(); - - void combine(RenderTexture* rt, RenderTexture* buf_rt, float_t alpha, void* rctx); - void copy(RenderTexture* rt); - void init_fbo(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height); -}; diff --git a/src/CRE/pv_param.cpp b/src/CRE/pv_param.cpp index fd904870..e6d23153 100644 --- a/src/CRE/pv_param.cpp +++ b/src/CRE/pv_param.cpp @@ -4,7 +4,7 @@ */ #include "pv_param.hpp" -#include "post_process.hpp" +#include "render.hpp" #include "render_context.hpp" #include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/str_utils.hpp" @@ -883,7 +883,7 @@ namespace pv_param_task { else value = vec3::lerp(data.data_prev.color, data.data.color, frame / duration); - rctx_ptr->post_process.blur->set_intensity(value); + rctx_ptr->render.set_intensity(value); frame += get_delta_frame(); if (frame > duration) { @@ -937,9 +937,8 @@ namespace pv_param_task { contrast = lerp_def(data.data_prev.contrast, data.data.contrast, t); } - post_process_tone_map* tone_map = rctx_ptr->post_process.tone_map; - tone_map->set_saturate_coeff(saturation, 1, false); - tone_map->set_exposure(exposure * 2.0f); + rctx_ptr->render.set_saturate_coeff(saturation, 1, false); + rctx_ptr->render.set_exposure(exposure * 2.0f); vec3 tone_trans_start; vec3 tone_trans_end; @@ -947,7 +946,7 @@ namespace pv_param_task { CalcToneTrans(contrast + gamma.y, tone_trans_start.y, tone_trans_end.y); CalcToneTrans(contrast + gamma.z, tone_trans_start.z, tone_trans_end.z); - tone_map->set_tone_trans(tone_trans_start, tone_trans_end, 1); + rctx_ptr->render.set_tone_trans(tone_trans_start, tone_trans_end, 1); frame += get_delta_frame(); if (frame > duration) { @@ -1225,7 +1224,6 @@ namespace pv_param_task { return; #endif - post_process_dof* dof = rctx_ptr->post_process.dof; dof_pv pv; dof_pv_get(&pv); pv.f2.focus = focus; diff --git a/src/CRE/render.cpp b/src/CRE/render.cpp new file mode 100644 index 00000000..8ae0df23 --- /dev/null +++ b/src/CRE/render.cpp @@ -0,0 +1,2162 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "render.hpp" +#include "rob/rob.hpp" +#include "gl_state.hpp" +#include "render_context.hpp" +#include "shader_ft.hpp" +#include "stage.hpp" +#include "stage_modern.hpp" +#include "static_var.hpp" +#include "texture.hpp" + +extern bool task_stage_is_modern; + +extern render_context* rctx_ptr; + +#define MLAA_MAX_EDGE_DETECTION_LEN (3) +#define MLAA_GRID_SIDE_LEN (2 * MLAA_MAX_EDGE_DETECTION_LEN + 1) +#define MLAA_SIDE_LEN (5 * MLAA_GRID_SIDE_LEN) + +#define TONE_MAP_SAT_GAMMA_SAMPLES 32 + +namespace rndr { + static void generate_mlaa_area_texture(Render* rend); + static void calculate_mlaa_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2); + static void calculate_mlaa_area_texture_data_inner(float_t* val_left, + float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright); + + Render::ExposureCharaData::ExposureCharaData() : spot_weight(), query(), query_data() { + reset(); + } + + Render::ExposureCharaData::~ExposureCharaData() { + + } + + void Render::ExposureCharaData::reset() { + for (GLuint& i : query_data) + i = -1; + spot_weight = 0.0f; + } + + Render::FrameTextureData::FrameTextureData() : texture() { + type = FRAME_TEXTURE_MAX; + } + + Render::FrameTextureData::~FrameTextureData() { + + } + + Render::FrameTexture::FrameTexture() : capture() { + + } + + Render::FrameTexture::~FrameTexture() { + + } + + Render::Render() : base_downsample(), ss_alpha_mask(), taa_tex(), aet_back_tex(), reduce_tex(), + reduce_tex_draw(), exposure_tex(), exposure_history(), tonemap_lut_texture(), mlaa_area_texture(), + texture_counter(), lens_shaft_query(), lens_flare_query(), lens_shaft_query_data(), + lens_flare_query_data(), lens_flare_query_index(), lens_flare_texture(), lens_shaft_texture(), + lens_ghost_texture(), lens_ghost_count(), width(), height(), inner_width(), inner_height(), + render_width(), render_height(), render_post_width(), render_post_height(), render_post_width_scale(), + render_post_height_scale(), reduce_width(), reduce_height(), taa_texture_selector(), + taa_texture(), reset_exposure(), screen_x_offset(), screen_y_offset(), screen_width(), + screen_height(), saturate_lock(), exposure_history_counter(), exposure_query_index(), + lens_shaft_scale(), lens_flare_power(), field_A10(), lens_flare_appear_power(), + render_textures_data(), movie_textures_data(), aet_back(), dof(), transparency_tex(), + transparency(), saturate_index(), scene_fade_index(), tone_trans_index(), saturate_coeff(), + scene_fade_alpha(), scene_fade_blend_func(), tone_map(), mag_filter(), fade(), update() { + exposure = 2.0f; + exposure_rate = 1.0f; + auto_exposure = 1; + + taa_blend = -1.0f; + + stage_index = -1; + stage_index_prev = -1; + + reset_exposure = true; + + gamma = 1.0; + gamma_rate = 1.0f; + + mag_filter = MAG_FILTER_BILINEAR; + + saturate_power = 1; + + for (int32_t i = 0; i < 2; i++) { + reset_saturate_coeff(i, false); + reset_scene_fade(i); + reset_tone_trans(i); + } + + fade_alpha = -1.0f; + + update_lut = true; + + lens_shaft_inv_scale = 1.0f; + lens_flare = 1.0f; + lens_shaft = 1.0f; + lens_ghost = 1.0f; + + radius = 2.0f; + intensity = 1.0f; + + for (GLuint& i : lens_shaft_query_data) + i = -1; + + for (GLuint& i : lens_flare_query_data) + i = -1; + } + + Render::~Render() { + if (aet_back_tex) + texture_free(aet_back_tex); + + if (dof) { + delete dof; + dof = 0; + } + + if (transparency) { + delete transparency; + transparency = 0; + } + } + + void Render::apply_post_process(camera* cam, texture* light_proj_tex, int32_t npr_param) { + render_context* rctx = rctx_ptr; + + for (int32_t i = 0; i < 8; i++) + gl_state_bind_sampler(i, 0); + + dof->apply(&rend_texture[0]); + + draw_lens_ghost(); + + get_frame_texture(rend_texture[0].GetColorTex(), FRAME_TEXTURE_PRE_PP); + + downsample(); + + reduce_tex_draw = 0; + get_blur(); + + calc_exposure(cam); + apply_tone_map(light_proj_tex, npr_param); + + if (mlaa) + apply_mlaa(ss_alpha_mask); + + for (int32_t i = 0; i < 16; i++) { + if (!render_textures_data[i]) + continue; + + render_textures[i].Bind(); + + texture* t = render_textures_data[i]; + if (render_width[0] > t->width * 2 || render_height[0] > t->height * 2) + uniform_value[U_REDUCE] = 1; + else + uniform_value[U_REDUCE] = 0; + + glViewport(0, 0, t->width, t->height); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(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); + } + + get_frame_texture(taa_tex[2]->tex, FRAME_TEXTURE_POST_PP); + + frame_texture_reset_capture(); + + rctx->screen_buffer.Bind(); + glViewport(0, 0, rctx->sprite_width, rctx->sprite_height); + if (ssaa) { + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + uniform_value[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(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_value[U_ALPHA_MASK] = 0; + } + else { + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + if (mag_filter == MAG_FILTER_NEAREST) + gl_state_bind_sampler(0, rctx->render_samplers[1]); + else + gl_state_bind_sampler(0, rctx->render_samplers[0]); + + switch (mag_filter) { + case MAG_FILTER_NEAREST: + case MAG_FILTER_BILINEAR: + default: + uniform_value[U_MAGNIFY] = 0; + break; + case MAG_FILTER_SHARPEN_5_TAP: + uniform_value[U_MAGNIFY] = 2; + break; + case MAG_FILTER_SHARPEN_4_TAP: + uniform_value[U_MAGNIFY] = 3; + break; + case MAG_FILTER_CONE_4_TAP: + uniform_value[U_MAGNIFY] = 4; + break; + case MAG_FILTER_CONE_2_TAP: + uniform_value[U_MAGNIFY] = 5; + break; + } + + shaders_ft.set(SHADER_FT_MAGNIFY); + draw_quad(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(); + + for (int32_t i = 0; i < 8; i++) + gl_state_bind_sampler(i, 0); + } + + void Render::bind_render_texture(bool aet_back) { + if (aet_back) { + aet_back_texture.Bind(); + this->aet_back = 1; + } + else + rend_texture[0].Bind(); + glViewport(0, 0, render_width[0], render_height[0]); + } + + void Render::ctrl(camera* cam) { + view_point_prev = view_point; + interest_prev = interest; + cam->get_view_point(view_point); + cam->get_interest(interest); + + stage_index_prev = stage_index; + if (task_stage_is_modern) + stage_index = (int32_t)task_stage_modern_get_current_stage_hash(); + else + stage_index = task_stage_get_current_stage_index(); + + reset_exposure = cam->fast_change_hist1 && !cam->fast_change_hist0; + if (reset_exposure) { + float_t view_point_dist = vec3::distance(view_point, view_point_prev); + + vec3 dir = vec3::normalize(interest - view_point); + vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); + + float_t dir_diff_angle = vec3::dot(dir, dir_prev); + if (dir_diff_angle < 0.5f) + dir_diff_angle = 0.0f; + if (view_point_dist < dir_diff_angle * 0.4f) + reset_exposure = false; + } + else if (stage_index != stage_index_prev) + reset_exposure = true; + } + + void Render::draw_quad(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; + + float_t w = (float_t)max_def(width, 1); + float_t h = (float_t)max_def(height, 1); + quad_shader_data quad = {}; + quad.g_texcoord_modifier = { 0.5f * s0, 0.5f * t0, 0.5f * s0 + s1, 0.5f * t0 + t1 }; // x * 0.5 * y0 + 0.5 * y0 + y1 + quad.g_texel_size = { scale / w, scale / h, w, h }; + quad.g_color = { param_x, param_y, param_z, param_w }; + quad.g_texture_lod = 0.0f; + + rctx_ptr->quad_ubo.WriteMemory(quad); + rctx_ptr->quad_ubo.Bind(0); + gl_state_bind_vertex_array(rctx_ptr->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + } + + void Render::draw_lens_flare(camera* cam) { + static float_t flt_1411ACB84 = sinf(0.01365909819f); + static float_t flt_1411ACB8C = tanf(0.01365909819f) * 2.0f * 0.94f; + + if (!lens_flare_texture) + return; + + GLuint tex = obj_database_get_obj_set_texture(5, 4549); + if (!tex) + return; + + float_t v5 = tanf((float_t)(cam->get_fov() * DEG_TO_RAD) * 0.5f); + light_set* set = &rctx_ptr->light_set[LIGHT_SET_MAIN]; + light_data* data = &set->lights[LIGHT_SUN]; + + vec3 position; + vec4 emission; + if (data->get_type() == LIGHT_PARALLEL) { + data->get_position(position); + data->get_diffuse(emission); + } + else { + set->lights[LIGHT_STAGE].get_position(position); + position = vec3::normalize(position) * 500.0f; + set->lights[LIGHT_STAGE].get_ibl_color0(emission); + data->set_type(LIGHT_PARALLEL); + data->set_position(position); + data->set_diffuse(emission); + } + + vec4 v44; + *(vec3*)&v44 = position; + v44.w = 1.0f; + + mat4_transform_vector(&cam->view_projection, &v44, &v44); + + float_t v13 = 1.0f / v44.w; + float_t v14 = v44.x * v13; + float_t v15 = v44.y * v13; + float_t v16 = (float_t)width * 0.01f / (float_t)height; + v14 = clamp_def(v14, -0.99f, 0.99f); + v15 = clamp_def(v15, v16 - 1.0f, 1.0f - v16); + v44.x = v14 * v44.w; + v44.y = v15 * v44.w; + + mat4_transform_vector(&cam->inv_view_projection, &v44, &v44); + ((pos_scale*)&lens_flare_pos)->get_screen_pos_scale(cam->view_projection, position, false); + + float_t v17 = lens_flare_pos.x - (float_t)width * 0.5f; + float_t v19 = v5 / (float_t)height * 0.5f; + float_t v20 = lens_flare_pos.y - (float_t)height * 0.5f; + + float_t v22 = sqrtf(v17 * v19 * v17 * v19 + v20 * v19 * v20 * v19 + 1.0f); + float_t v23 = ((float_t)render_width[0] * (flt_1411ACB8C / v5)) * (v22 * v22 * 0.5f) + * ((float_t)render_height[0] * (flt_1411ACB8C / v5)); + float_t v24 = vec3::distance(position, view_point) * flt_1411ACB84; + emission *= 1.0f / (float_t)(1.0f - cosf((float_t)(3.0 * DEG_TO_RAD))); + + sun_quad_shader_data shader_data = {}; + shader_data.g_emission = emission; + + gl_state_active_bind_texture_2d(0, tex); + shaders_ft.set(SHADER_FT_SUN); + gl_state_bind_vertex_array(rctx_ptr->common_vao); + rctx_ptr->sun_quad_ubo.Bind(0); + + int32_t query_index = (lens_flare_query_index + 1) % 3; + lens_flare_query_index = query_index; + int32_t next_query_index = (query_index + 2) % 3; + + if (lens_shaft_query_data[next_query_index] == -1) + lens_shaft_query_data[next_query_index] = 0; + + if (lens_flare_query_data[next_query_index] == -1) + lens_flare_query_data[next_query_index] = 0; + + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_cull_face(); + + mat4 mat; + mat4_mul_translate(&cam->view, &position, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 0.2f, &mat); + mat4_mul(&mat, &cam->projection, &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_ptr->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, lens_shaft_query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + mat4_mul_translate(&cam->view, (vec3*)&v44, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 2.0f, &mat); + mat4_mul(&mat, &cam->projection, &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_ptr->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, lens_flare_query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_set_depth_mask(GL_TRUE); + gl_state_enable_cull_face(); + + if (lens_shaft_query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(lens_shaft_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(lens_shaft_query[query_index], GL_QUERY_RESULT, &lens_shaft_query_data[query_index]); + } + + if (lens_flare_query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(lens_flare_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(lens_flare_query[query_index], GL_QUERY_RESULT, &lens_flare_query_data[query_index]); + } + + if (emission.x + emission.y + emission.z > 0.0f) { + gl_state_enable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ONE); + gl_state_set_depth_mask(GL_FALSE); + + mat4_mul_translate(&cam->view, &position, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 1.1f, &mat); + mat4_mul(&mat, &cam->projection, &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_ptr->sun_quad_ubo.WriteMemory(shader_data); + + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + gl_state_disable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + gl_state_set_depth_mask(GL_TRUE); + } + + gl_state_active_bind_texture_2d(0, 0); + gl_state_bind_vertex_array(0); + + if (lens_flare_appear_power <= 0.01f) + lens_flare_appear_power = 0.0; + else + lens_flare_appear_power *= 0.93f; + lens_shaft_scale = 100.0f; + lens_flare_power = 0.0f; + + float_t v34 = lens_flare_pos.x; + float_t v35 = lens_flare_pos.y; + float_t v32 = lens_flare_pos.z; + + float_t v33 = 0.0f; + if (v32 >= 0.0f + || v34 < (float_t)-width || v34 >(float_t)(2 * width) + || v35 < (float_t)-height || v35 >(float_t)(2 * height)) + lens_flare_texture = 0; + else { + for (GLuint& i : lens_flare_query_data) + if (i != -1) + v33 += min_def((float_t)i, v23); + v33 /= (v23 * 3.0f); + lens_flare_power = powf(v33, 0.7f); + + if (v33 > 0.0f && lens_shaft_query_data[query_index]) { + float_t v41 = max_def(v33 - 0.4f, 0.005f); + lens_shaft_scale = ((0.6f / v41) * lens_shaft_inv_scale) * (v5 * 3.4f); + } + } + + if (v32 >= 0.0f + || v34 < -12.0f || v34 >(float_t)(width + 12) + || v35 < -12.0f || v35 >(float_t)(height + 12)) { + field_A10 = 0.0f; + } + else if (v34 > -2.0f && v34 < (float_t)(width + 2) + && v35 > -2.0f && v35 < (float_t)(height + 2)) { + if (v33 > 0.4f && field_A10 == 0.0f && lens_flare_appear_power < 0.02f && !reset_exposure) + lens_flare_appear_power = 8.0f; + field_A10 = 1.0f; + } + } + + bool Render::frame_texture_cont_capture_set(bool value) { + frame_texture[0].capture = value; + return true; + } + + void Render::frame_texture_free() { + for (Render::FrameTexture& i : frame_texture) { + for (Render::FrameTextureData& j : i.data) { + j.texture = 0; + j.render_texture.Free(); + j.type = FRAME_TEXTURE_MAX; + } + + i.capture = false; + } + } + + int32_t Render::frame_texture_load(int32_t slot, Render::FrameTextureType type, texture* tex) { + if (!tex || slot < 0 || slot >= 6) + return -1; + + for (Render::FrameTextureData& i : frame_texture[slot].data) + if (!i.texture) { + i.render_texture.SetColorDepthTextures(tex->tex); + i.texture = tex; + i.type = type; + return (int32_t)(&i - frame_texture[slot].data); + } + return -1; + } + + void Render::frame_texture_reset() { + for (Render::FrameTexture& i : frame_texture) { + for (Render::FrameTextureData& j : i.data) { + j.texture = 0; + j.type = FRAME_TEXTURE_MAX; + } + + i.capture = false; + } + } + + bool Render::frame_texture_slot_capture_set(int32_t index) { + if (index < 1 || index >= 5) + return false; + + frame_texture[index].capture = true; + return true; + } + + bool Render::frame_texture_unload(int32_t slot, texture* tex) { + if (!tex || slot < 0 || slot >= 6) + return false; + + for (Render::FrameTextureData& i : frame_texture[slot].data) + if (i.texture == tex) { + i.render_texture.Free(); + i.texture = 0; + i.type = FRAME_TEXTURE_MAX; + return true; + } + return false; + } + + void Render::free() { + if (transparency) { + delete transparency; + transparency = 0; + } + + for (int32_t i = 0; i < 1; i++) + if (transparency_tex[i]) { + texture_free(transparency_tex[i]); + transparency_tex[i] = 0; + texture_counter--; + } + + if (dof) { + delete dof; + dof = 0; + } + + if (!texture_counter) + return; + + for (int32_t i = 0; i < downsample_max_count; i++) + rend_texture[i].Free(); + + for (int32_t i = 0; i < 3; i++) { + taa_buffer[i].Free(); + + if (taa_tex[i]) { + texture_free(taa_tex[i]); + taa_tex[i] = 0; + texture_counter--; + } + } + + aet_back_texture.Free(); + + if (aet_back_tex) { + texture_free(aet_back_tex); + aet_back_tex = 0; + texture_counter--; + } + + mlaa_buffer.Free(); + temp_buffer.Free(); + + sss_contour_texture = 0; + + downsample_texture.Free(); + field_3E8.Free(); + + for (int32_t i = 0; i < 5; i++) + reduce_texture->Free(); + + for (int32_t i = 0; i < 5; i++) + if (reduce_tex[i]) { + texture_free(reduce_tex[i]); + reduce_tex[i] = 0; + texture_counter--; + } + + if (exposure_history) { + texture_free(exposure_history); + exposure_history = 0; + texture_counter--; + } + + exposure_texture.Free(); + + if (exposure_tex) { + glDeleteTextures(1, &exposure_tex); + exposure_tex = 0; + } + + if (tonemap_lut_texture) { + glDeleteTextures(1, &tonemap_lut_texture); + tonemap_lut_texture = 0; + } + if (mlaa_area_texture) { + glDeleteTextures(1, &mlaa_area_texture); + mlaa_area_texture = 0; + } + + glDeleteQueries(3, lens_shaft_query); + glDeleteQueries(3, lens_flare_query); + + for (ExposureCharaData& i : exposure_chara_data) { + glDeleteQueries(3, i.query); + i.query[0] = 0; + } + } + + bool Render::get_auto_exposure() { + return auto_exposure; + } + + float_t Render::get_exposure() { + return exposure; + } + + float_t Render::get_exposure_rate() { + return exposure_rate; + } + + float_t Render::get_gamma() { + return gamma; + } + + float_t Render::get_gamma_rate() { + return gamma_rate; + } + + vec3 Render::get_lens() { + vec3 value; + value.x = lens_flare; + value.y = lens_shaft; + value.z = lens_ghost; + return value; + } + + float_t Render::get_lens_flare_appear_power() { + return lens_flare_appear_power; + } + + float_t Render::get_lens_flare_power() { + return lens_flare_power; + } + + void Render::get_exposure_chara_data(camera* cam) { + shader::unbind(); + + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_cull_face(); + + shaders_ft.set(SHADER_FT_SUN_NO_TEXTURED); + gl_state_bind_vertex_array(rctx_ptr->common_vao); + rctx_ptr->sun_quad_ubo.Bind(0); + + ExposureCharaData* chara_data = exposure_chara_data; + int32_t query_index = (this->exposure_query_index + 1) % 3; + this->exposure_query_index = query_index; + int32_t next_query_index = (query_index + 2) % 3; + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, chara_data++) { + rob_chara* rob_chr = rob_chara_array_get(i); + if (!rob_chr || !rob_chr->is_visible()) + continue; + + float_t max_face_depth = rob_chr->get_max_face_depth(); + + mat4 mat = mat4_identity; + rob_chr->sub_1405163C0(4, mat); + mat4_mul(&mat, &cam->view, &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, &cam->projection, &mat); + + sun_quad_shader_data shader_data = {}; + 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; + shader_data.g_emission = 0.0f; + rctx_ptr->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, chara_data->query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + if (chara_data->query_data[next_query_index] == -1) + chara_data->query_data[next_query_index] = 0; + + if (chara_data->query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(chara_data->query[query_index], + GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(chara_data->query[query_index], + GL_QUERY_RESULT, chara_data->query_data); + else + chara_data->query_data[query_index] = 0; + } + } + + gl_state_bind_vertex_array(0); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_set_depth_mask(GL_TRUE); + gl_state_enable_cull_face(); + } + + vec3 Render::get_intensity() { + return intensity; + } + + vec3 Render::get_radius() { + return radius; + } + + float_t Render::get_saturate_coeff() { + return saturate_coeff[0]; + } + + int32_t Render::get_saturate_power() { + return saturate_power; + } + + vec4 Render::get_scene_fade() { + vec4 scene_fade; + *(vec3*)&scene_fade = scene_fade_color[0]; + scene_fade.w = scene_fade_alpha[0]; + return scene_fade; + } + + float_t Render::get_scene_fade_alpha() { + return scene_fade_alpha[0]; + } + + int32_t Render::get_scene_fade_blend_func() { + return scene_fade_blend_func[0]; + } + + vec3 Render::get_scene_fade_color() { + return scene_fade_color[0]; + } + + int32_t Render::get_taa() { + return taa; + } + + tone_map_method Render::get_tone_map() { + return tone_map; + } + + void Render::get_tone_trans(vec3& start, vec3& end) { + start = tone_trans_start[0]; + end = tone_trans_end[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; + this->hd_res = hd_res; + this->ss_alpha_mask = ss_alpha_mask; + + mlaa = 1; + taa = ssaa || ss_alpha_mask ? 0 : 1; + mag_filter = hd_res ? MAG_FILTER_SHARPEN_4_TAP : MAG_FILTER_BILINEAR; + + this->width = width; + this->height = height; + + if (ssaa) { + inner_width = 2 * width; + inner_height = 2 * height; + } + else { + inner_width = width; + inner_height = height; + } + + screen_x_offset = 0; + screen_y_offset = 0; + + screen_width = width; + screen_height = height; + reduce_width[0] = 256; + reduce_height[0] = 144; + reduce_width[1] = 128; + reduce_height[1] = 72; + reduce_width[2] = 64; + reduce_height[2] = 36; + reduce_width[3] = 32; + reduce_height[3] = 18; + reduce_width[4] = 8; + reduce_height[4] = 8; + + update_res(true, 1); + + rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); + + gl_state_bind_texture_2d(rend_texture[0].GetColorTex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + 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); + + for (int32_t i = 0; i < 3; i++) { + taa_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + taa_buffer[i].SetColorDepthTextures(taa_tex[i]->tex, 0, rend_texture[0].GetDepthTex()); + } + + aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture[0].GetDepthTex()); + + mlaa_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_DEPTH_COMPONENT24); + temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); + sss_contour_texture = &mlaa_buffer; + + 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_state_bind_texture_2d(rend_texture[i].GetColorTex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + downsample_texture.Init(reduce_width[0], reduce_height[0], 0, GL_RGBA16F, GL_ZERO); + + gl_state_bind_texture_2d(downsample_texture.GetColorTex()); + + const vec4 border_color = 0.0f; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + field_3E8.Init(512, 256, 0, GL_RGBA8, GL_ZERO); + + dof = new renderer::DOF3(render_post_width[0], render_post_height[0]); + + transparency_tex[0] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA16F, render_post_width[0], render_post_height[0], 0, 0, 0); + transparency = new renderer::Transparency(transparency_tex[0]->tex, + rend_texture[0].GetDepthTex(), render_post_width[0], render_post_height[0]); + } + + void Render::init_tone_map_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_state_bind_texture_2d(reduce_tex[i]->tex); + + const vec4 border_color = 0.0f; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + } + + reduce_texture[0].SetColorDepthTextures(reduce_tex[0]->tex); + + exposure_history = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_R32F, 32, 1, 0, 0, 0); + + glGenTextures(1, &exposure_tex); + gl_state_bind_texture_2d(exposure_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_state_bind_texture_2d(0); + + exposure_texture.SetColorDepthTextures(exposure_tex); + + glGenTextures(1, &tonemap_lut_texture); + gl_state_bind_texture_2d(tonemap_lut_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, 0, GL_RG, GL_HALF_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(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_state_bind_texture_2d(0); + + generate_mlaa_area_texture(this); + + glGenQueries(3, lens_shaft_query); + glGenQueries(3, lens_flare_query); + + for (GLuint& i : lens_shaft_query_data) + i = -1; + + for (GLuint& i : lens_flare_query_data) + i = -1; + + for (ExposureCharaData& i : exposure_chara_data) { + glGenQueries(3, i.query); + for (GLuint& j : i.query_data) + j = -1; + } + } + + int32_t Render::movie_texture_set(texture* movie_texture) { + if (!movie_texture) + return -1; + + int32_t index = 0; + while (movie_textures_data[index]) + if (++index >= 1) + return -1; + + movie_textures_data[index] = movie_texture; + movie_textures[index].SetColorDepthTextures(movie_texture->tex); + return index; + } + + void Render::movie_texture_free(texture* movie_texture) { + if (!movie_texture) + return; + + int32_t index = 0; + while (movie_textures_data[index] != movie_texture) + if (++index >= 1) + return; + + movie_textures_data[index] = 0; + movie_textures[index].Free(); + } + + int32_t Render::render_texture_set(texture* render_texture, bool task_photo) { + if (!render_texture) + return -1; + + int32_t index = 0; + if (task_photo) + index = 15; + else + while (render_textures_data[index]) + if (++index >= 15) + return -1; + + render_textures_data[index] = render_texture; + render_textures[index].SetColorDepthTextures(render_texture->tex); + return index; + } + + void Render::render_texture_free(texture* render_texture, bool task_photo) { + if (!render_texture) + return; + + int32_t index = 0; + if (task_photo) + index = 15; + else + while (render_textures_data[index] != render_texture) + if (++index >= 15) + return; + + render_textures_data[index] = 0; + render_textures[index].Free(); + } + + void Render::reset_saturate_coeff(int32_t index, bool lock) { + set_saturate_coeff(1.0f, index, lock); + + if (index == 1) + saturate_index = 0; + } + + void Render::reset_scene_fade(int32_t index) { + scene_fade_color[index] = 0.0f; + scene_fade_alpha[index] = 0.0f; + scene_fade_blend_func[index] = 0; + + if (index == 1) + scene_fade_index = 0; + update = true; + } + + void Render::reset_tone_trans(int32_t index) { + tone_trans_scale[index] = 1.0f; + tone_trans_offset[index] = 0.0f; + tone_trans_start[index] = 0.0f; + tone_trans_end[index] = 1.0f; + + if (index == 1) + tone_trans_index = 0; + update = true; + } + + void Render::resize(int32_t width, int32_t height) { + this->width = width; + this->height = height; + + if (ssaa) { + inner_width = 2 * width; + inner_height = 2 * height; + } + else { + inner_width = width; + inner_height = height; + } + + screen_x_offset = 0; + screen_y_offset = 0; + + screen_width = width; + screen_height = height; + + update_res(true, 1); + + rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); + + gl_state_bind_texture_2d(rend_texture[0].GetColorTex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + 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); + + for (int32_t i = 0; i < 3; i++) { + texture_free(taa_tex[i]); + taa_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + taa_buffer[i].SetColorDepthTextures(taa_tex[i]->tex, 0, rend_texture[0].GetDepthTex()); + } + + texture_free(aet_back_tex); + aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture[0].GetDepthTex()); + + mlaa_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_DEPTH_COMPONENT24); + temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); + sss_contour_texture = &mlaa_buffer; + + 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_state_bind_texture_2d(rend_texture[i].GetColorTex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + dof->resize(render_post_width[0], render_post_height[0]); + + for (int32_t i = 0; i < 1; i++) + if (transparency_tex[i]) { + texture_free(transparency_tex[i]); + transparency_tex[i] = 0; + texture_counter--; + } + + transparency_tex[0] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA16F, render_post_width[0], render_post_height[0], 0, 0, 0); + transparency->resize(transparency_tex[0]->tex, rend_texture[0].GetDepthTex(), + render_post_width[0], render_post_height[0]); + } + + void Render::set_auto_exposure(bool value) { + auto_exposure = value; + } + + void Render::set_exposure(float_t value) { + exposure = value; + } + + void Render::set_exposure_rate(float_t value) { + exposure_rate = value; + } + + void Render::set_gamma(float_t value) { + if (value != gamma) { + gamma = value; + update_lut = true; + } + } + + void Render::set_gamma_rate(float_t value) { + if (value != gamma_rate) { + gamma_rate = value; + update_lut = true; + } + } + + void Render::set_intensity(const vec3& value) { + intensity = vec3::clamp(value, 0.0f, 2.0f); + } + + void Render::set_lens(vec3 value) { + lens_flare = value.x; + lens_shaft = value.y; + lens_ghost = value.z; + update = true; + } + + void Render::set_radius(const vec3& value) { + radius = vec3::clamp(value, 1.0f, 3.0f); + } + + void Render::set_saturate_coeff(float_t value, int32_t index, bool lock) { + if (saturate_lock) + return; + + saturate_coeff[index] = value; + update_lut = true; + update = true; + + if (lock) { + saturate_lock = true; + saturate_index = 0; + } + else if (index == 1) + saturate_index = 1; + } + + void Render::set_saturate_power(int32_t value) { + if (value != saturate_power) { + saturate_power = value; + update_lut = true; + } + } + + void Render::set_scene_fade(const vec4& value, int32_t index) { + scene_fade_color[index] = *(vec3*)&value; + scene_fade_alpha[index] = value.w; + + if (index == 1) + scene_fade_index = 1; + update = true; + } + + void Render::set_scene_fade_alpha(float_t value, int32_t index) { + scene_fade_alpha[index] = value; + + if (index == 1) + scene_fade_index = 1; + update = true; + } + + void Render::set_scene_fade_blend_func(int32_t value, int32_t index) { + if (value < 0 || value > 2) + return; + + scene_fade_blend_func[index] = value; + + if (index == 1) + scene_fade_index = 1; + update = true; + } + + + void Render::set_scene_fade_color(const vec3& value, int32_t index) { + scene_fade_color[index] = value; + + if (index == 1) + scene_fade_index = 1; + update = true; + } + + void Render::set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height) { + screen_x_offset = x_offset; + screen_y_offset = y_offset; + screen_width = min_def(width, this->width); + screen_height = min_def(height, this->height); + + update_res(false, -1); + update = true; + } + + void Render::set_taa(int32_t value) { + taa = value; + taa_blend = -1.0f; + update = 1; + } + + void Render::set_tone_map(tone_map_method value) { + tone_map = value; + } + + void Render::set_tone_trans(const vec3& start, const vec3& end, int32_t index) { + for (int32_t i = 0; i < 3; i++) + if (fabsf((&end.x)[i] - (&start.x)[i]) < 0.0001f) { + reset_tone_trans(0); + return; + } + + tone_trans_end[index] = end; + tone_trans_start[index] = start; + + vec3 scale = vec3::rcp(end - start); + tone_trans_scale[index] = scale; + tone_trans_offset[index] = -(scale * start); + + if (index == 1) + tone_trans_index = 1; + update = true; + } + + void Render::downsample() { + uniform_value[U_REDUCE] = 1; + shaders_ft.set(SHADER_FT_REDUCE); + for (int32_t i = 1; i < downsample_count - 1; i++) { + rend_texture[i].Bind(); + gl_state_active_bind_texture_2d(0, rend_texture[i - 1].GetColorTex()); + glViewport(0, 0, render_width[i], render_height[i]); + draw_quad( + 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_value[U_REDUCE] = 3; + shaders_ft.set(SHADER_FT_REDUCE); + + int32_t downsample = max_def(downsample_count - 2, 0); + glViewport(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(); + gl_state_active_bind_texture_2d(0, rend_texture[downsample].GetColorTex()); + draw_quad( + 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_state_active_bind_texture_2d(0, reduce_tex[0]->tex); + for (int32_t i = 1; i < 5; i++) { + float_t scale; + if (i == 4) { + scale = 1.0f; + uniform_value[U_EXPOSURE] = 0; + shaders_ft.set(SHADER_FT_EXPOSURE); + } + else + { + scale = 0.75; + uniform_value[U_REDUCE] = 1; + shaders_ft.set(SHADER_FT_REDUCE); + } + + glViewport(0, 0, reduce_width[i], reduce_height[i]); + draw_quad(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_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + } + + void Render::transparency_combine(float_t alpha) { + transparency->combine(rend_texture, alpha); + } + + void Render::transparency_copy() { + transparency->copy(rend_texture[0].GetColorTex()); + } + + void Render::update_res(bool set, int32_t base_downsample) { + int32_t hd_res_widths[4]; + int32_t hd_res_heights[4]; + hd_res_widths[0] = 1280; + hd_res_heights[0] = 720; + hd_res_widths[1] = 1024; + hd_res_heights[1] = 576; + hd_res_widths[2] = 1024; + hd_res_heights[2] = 576; + hd_res_widths[3] = 960; + hd_res_heights[3] = 544; + + base_downsample = min_def(base_downsample, 3); + + if (set) + this->base_downsample = base_downsample; + else + base_downsample = max_def(base_downsample, this->base_downsample); + + base_downsample = clamp_def(base_downsample, 0, 3); + + int32_t hd_res_width = hd_res_widths[base_downsample]; + int32_t hd_res_height = hd_res_heights[base_downsample]; + if (hd_res && (screen_width > hd_res_width || screen_height > hd_res_height)) { + render_width[0] = hd_res_width; + render_height[0] = hd_res_height; + + if (set) { + inner_width = render_width[0]; + inner_height = render_height[0]; + } + } + else { + /*float_t round_val = ssaa ? 1.0f : 16.0f; + render_width[0] = (int32_t)(prj::ceilf((float_t)screen_width + * (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 + * (float_t)inner_height / (float_t)height); + } + + int32_t downsample = 1; + for (int32_t i = 0; i < 4; i++) { + int32_t width = (render_width[i] + 1) / 2; + int32_t height = (render_height[i] + 1) / 2; + if (width <= reduce_width[0] && height <= reduce_height[0]) + break; + + render_width[i + 1] = width; + render_height[i + 1] = height; + downsample++; + } + this->downsample_count = downsample; + + if (set) { + downsample_max_count = downsample; + for (int32_t i = 0; i < downsample; i++) { + render_post_width[i] = render_width[i]; + render_post_height[i] = render_height[i]; + } + } + + 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]; + + taa_blend = -1.0f; + } + + void Render::apply_mlaa(int32_t ss_alpha_mask) { + render_context* rctx = rctx_ptr; + + gl_state_begin_event("PostProcess::mlaa"); + mlaa_buffer.Bind(); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + uniform_value[U_MLAA] = 0; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(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_state_active_bind_texture_2d(0, mlaa_buffer.GetColorTex()); + gl_state_active_bind_texture_2d(1, mlaa_area_texture); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + gl_state_bind_sampler(1, rctx->render_samplers[1]); + uniform_value[U_MLAA] = 1; + uniform_value[U_MLAA_SEARCH] = 2; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(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); + + RenderTexture& buf_texture = rctx->render_buffer; + buf_texture.Bind(); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_active_bind_texture_2d(1, temp_buffer.GetColorTex()); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + uniform_value[U_MLAA] = 2; + uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(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_value[U_ALPHA_MASK] = 0; + gl_state_active_bind_texture_2d(0, 0); + gl_state_active_bind_texture_2d(1, 0); + + fbo_blit(buf_texture.fbos[0], taa_buffer[2].fbos[0], + 0, 0, buf_texture.GetWidth(), buf_texture.GetHeight(), + 0, 0, taa_tex[2]->width, taa_tex[2]->height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + gl_state_end_event(); + } + + void Render::apply_tone_map(texture* light_proj_tex, int32_t npr_param) { + if (!this) + return; + + gl_state_begin_event("PostProcess::tone_map"); + + update_tone_map_lut(); + + uniform_value[U_TONE_MAP] = (int32_t)tone_map; + uniform_value[U_FLARE] = 0; + uniform_value[U_SCENE_FADE] = scene_fade_alpha[scene_fade_index] > 0.01f ? 1 : 0; + uniform_value[U_AET_BACK] = 0; + uniform_value[U_LIGHT_PROJ] = 0; + //uniform_value[U25] = 0; + + gl_state_active_bind_texture_2d(0, rend_texture[0].GetColorTex()); + gl_state_active_bind_texture_2d(1, reduce_tex_draw); + gl_state_active_bind_texture_2d(2, tonemap_lut_texture); + gl_state_active_bind_texture_2d(3, exposure_tex); + gl_state_active_bind_texture_2d(4, rctx_ptr->empty_texture_2d); + gl_state_active_bind_texture_2d(5, rctx_ptr->empty_texture_2d); + gl_state_active_bind_texture_2d(6, rctx_ptr->empty_texture_2d); + + if (aet_back) { + gl_state_active_bind_texture_2d(6, aet_back_tex->tex); + uniform_value[U_AET_BACK] = 1; + } + + if (light_proj_tex) { + gl_state_active_bind_texture_2d(6, light_proj_tex->tex); + uniform_value[U_LIGHT_PROJ] = 1; + } + + int32_t scene_fade_blend_func = this->scene_fade_blend_func[scene_fade_index]; + + tone_map_shader_data shader_data; + shader_data.g_exposure.x = exposure * exposure_rate; + shader_data.g_exposure.y = 0.0625f; + shader_data.g_exposure.z = exposure * exposure_rate * 0.5f; + shader_data.g_exposure.w = auto_exposure ? 1.0f : 0.0f; + shader_data.g_flare_coef.x = (lens_flare * 2.0f) * (lens_flare_appear_power + lens_flare_power); + shader_data.g_flare_coef.y = lens_shaft * 2.0f; + shader_data.g_flare_coef.z = 0.0f; + shader_data.g_flare_coef.w = 0.0f; + *(vec3*)&shader_data.g_fade_color = scene_fade_color[scene_fade_index]; + shader_data.g_fade_color.w = scene_fade_alpha[scene_fade_index]; + if (scene_fade_blend_func == 1 || scene_fade_blend_func == 2) + *(vec3*)&shader_data.g_fade_color *= shader_data.g_fade_color.w; + *(vec3*)&shader_data.g_tone_scale = tone_trans_scale[tone_trans_index]; + *(vec3*)&shader_data.g_tone_offset = tone_trans_offset[tone_trans_index]; + shader_data.g_tone_scale.w = (float_t)scene_fade_blend_func; + shader_data.g_tone_offset.w = gamma > 0.0f ? 2.0f / (gamma * 3.0f) : 0.0f; + + shader_data.g_texcoord_transforms[0] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[1] = { 0.0f, 1.0f, 0.0f, 0.0f }; + 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 }; + + if (lens_flare_texture) { + static const vec4 border_color = 0.0f; + + const float_t aspect = (float_t)height / (float_t)width; + + uniform_value[U_FLARE] = 1; + gl_state_active_bind_texture_2d(4, lens_flare_texture); + gl_state_bind_sampler(4, rctx_ptr->render_samplers[2]); + mat4 mat; + mat4_translate(0.5f, 0.5f, 0.0f, &mat); + mat4_scale_rot(&mat, 0.75f, 0.75f, 1.0f, &mat); + mat4_mul_rotate_z(&mat, (lens_flare_pos.x / (float_t)width) + * 25.0f * DEG_TO_RAD_FLOAT, &mat); + mat4_mul_translate(&mat, -((1.0f / (float_t)width) * lens_flare_pos.x), + (lens_flare_pos.y - (float_t)height) * (1.0f / (float_t)width), 0.0f, &mat); + mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); + mat4_transpose(&mat, &mat); + shader_data.g_texcoord_transforms[4] = mat.row0; + shader_data.g_texcoord_transforms[5] = mat.row1; + + if (lens_shaft_scale < 50.0f) { + uniform_value[U_FLARE] = 2; + gl_state_active_bind_texture_2d(5, lens_shaft_texture); + gl_state_bind_sampler(5, rctx_ptr->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); + mat4_mul_rotate_z(&mat, (lens_flare_pos.x / (float_t)width) + * 60.0f * DEG_TO_RAD_FLOAT, &mat); + mat4_mul_translate(&mat, -((1.0f / (float_t)width) * lens_flare_pos.x), + (lens_flare_pos.y - (float_t)height) * (1.0f / (float_t)width), 0.0f, &mat); + mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); + mat4_transpose(&mat, &mat); + shader_data.g_texcoord_transforms[6] = mat.row0; + shader_data.g_texcoord_transforms[7] = mat.row1; + } + else { + 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 { + 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 }; + 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 }; + } + + if (npr_param == 1) { + /*gl_state_active_bind_texture_2d(16, sss_contour_texture->GetColorTex()); + gl_state_bind_sampler(16, rctx_ptr->render_samplers[1]); + gl_state_active_bind_texture_2d(17, sss_contour_texture->GetDepthTex()); + gl_state_bind_sampler(17, rctx_ptr->render_samplers[1]);*/ + gl_state_active_bind_texture_2d(14, rend_texture[0].GetDepthTex()); + gl_state_bind_sampler(14, rctx_ptr->render_samplers[1]); + } + + rctx_ptr->tone_map_ubo.WriteMemory(shader_data); + + glViewport(0, 0, render_width[0], render_height[0]); + taa_buffer[2].Bind(); + shaders_ft.set(SHADER_FT_TONEMAP); + rctx_ptr->tone_map_ubo.Bind(1); + gl_state_bind_vertex_array(rctx_ptr->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_active_bind_texture_2d(2, 0); + gl_state_end_event(); + } + + + void Render::calc_exposure(camera* cam) { + bool v2 = false; + if (!reset_exposure) { + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + exposure_chara_data[i].reset(); + + ExposureCharaData* chara_data = exposure_chara_data; + float_t v18 = (float_t)height / (float_t)width; + float_t v20 = powf(tanf((float_t)(cam->fov_rad * 0.5f)) * 3.4f, 2.0f); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, chara_data++) { + rob_chara* rob_chr = rob_chara_array_get(i); + if (!rob_chr || !rob_chr->is_visible()) + continue; + + vec4 v34 = { 0.05f, 0.0f, -0.04f, 1.0f }; + vec4 v33 = { 1.0f, 0.0f, 0.0f, 0.0f }; + + mat4 v44 = mat4_identity; + rob_chr->sub_1405163C0(4, v44); + + mat4 v42; + mat4 v43; + mat4_mul(&v44, &cam->view, &v42); + mat4_mul(&v42, &cam->projection, &v43); + + vec4 v41; + vec4 v40; + mat4_transform_vector(&v42, &v34, &v41); + mat4_transform_vector(&v43, &v34, &v40); + + float_t v12 = 1.0f / v40.w; + float_t v13 = v40.x * v12; + float_t v14 = v40.y * v12; + if (v41.z >= 0.0f || fabsf(v13) >= 1.0f || fabsf(v14) >= 1.0f) + continue; + + float_t v31 = 0.5f - (fabsf(v14) - 1.0f) * 2.5f; + float_t v32 = 0.5f - (fabsf(v13) - 1.0f) * 2.5f; + + float_t v16; + if (v32 <= v31) + v16 = v32; + else + v16 = v31; + + if (v16 > 1.0f) + v16 = 1.0f; + + vec4 v39; + mat4_transform_vector(&v42, &v33, &v39); + + float_t v17 = (v39.z + 1.0f) * 0.5f; + if (v17 > 0.8f) + v17 = 0.8f; + else if (v17 < 0.2f) + v17 = 0.0f; + + float_t v21 = 0.25f / sqrtf(powf(v20 * 3.4f, 2.0f) * (v41.z * v41.z)); + float_t v22; + if (v21 < 0.055f) { + v22 = (v21 - 0.035f) * 50.0f; + if (v22 < 0.0f) + v22 = 0.0f; + } + else if (v21 > 0.5f) { + v22 = 1.0f - (v21 - 0.5f) * 3.3333333f; + if (v22 < 0.0f) + v22 = 0.0f; + } + else + v22 = 1.0f; + + chara_data->spot_coefficients[0].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[0].y = (v14 + v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[0].z = 0.0f; + chara_data->spot_coefficients[0].w = 4.0f; + chara_data->spot_coefficients[1].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[1].y = (v14 - v21 * 0.3f + 1.0f) * 0.5f; + chara_data->spot_coefficients[1].z = 0.0f; + chara_data->spot_coefficients[1].w = 4.0f; + chara_data->spot_coefficients[2].x = (v13 + v21 * -0.5f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[2].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; + chara_data->spot_coefficients[2].z = 0.0f; + chara_data->spot_coefficients[2].w = 3.0f; + chara_data->spot_coefficients[3].x = (v13 - v21 * 0.6f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[3].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[3].z = 0.0f; + chara_data->spot_coefficients[3].w = 2.0f; + chara_data->spot_coefficients[4].x = (v13 + v21 * 0.6f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[4].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[4].z = 0.0f; + chara_data->spot_coefficients[4].w = 2.0f; + chara_data->spot_coefficients[5].x = (v13 + v21 * 0.5f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[5].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; + chara_data->spot_coefficients[5].z = 0.0f; + chara_data->spot_coefficients[5].w = 3.0f; + chara_data->spot_coefficients[6].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[6].y = (v14 - v21 * 0.8f + 1.0f) * 0.5f; + chara_data->spot_coefficients[6].z = 0.0f; + chara_data->spot_coefficients[6].w = 3.0f; + chara_data->spot_weight = v16 * 1.6f * v17 * v22; + if (chara_data->spot_weight > 0.0f && !chara_data->query_data[exposure_query_index]) + v2 = true; + } + } + + if (!v2 || reset_exposure) { + exposure_measure_shader_data exposure_measure = {}; + exposure_measure.g_spot_weight = { + exposure_chara_data[0].spot_weight, + exposure_chara_data[1].spot_weight, + exposure_chara_data[2].spot_weight, + exposure_chara_data[3].spot_weight + }; + + ExposureCharaData* chara_data = exposure_chara_data; + 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_ptr->exposure_measure_ubo.WriteMemory(exposure_measure); + + glViewport(0, 0, 1, 1); + downsample_texture.Bind(); + + uniform_value[U_EXPOSURE] = 1; + shaders_ft.set(SHADER_FT_EXPOSURE); + rctx_ptr->exposure_measure_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, reduce_tex[4]->tex); + gl_state_active_bind_texture_2d(1, reduce_tex[2]->tex); + draw_quad(1, 1, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + + gl_state_active_bind_texture_2d(0, exposure_history->tex); + if (reset_exposure) + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 32, 1); + else + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, exposure_history_counter, 0, 0, 0, 1, 1); + exposure_history_counter = (exposure_history_counter + 1) % 32; + } + + glViewport(0, 0, 1, 1); + exposure_texture.Bind(); + uniform_value[U_EXPOSURE] = 2; + shaders_ft.set(SHADER_FT_EXPOSURE); + gl_state_active_bind_texture_2d(0, exposure_history->tex); + draw_quad(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, + 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) { + float_t first_val = (start - step * 0.5f) * 2.0f; + for (int32_t i = 0; i < kernel_size; i++) + gaussian_kernel[i * stride + offset] = 0.0f; + + float_t temp_gaussian_kernel[20]; + float_t s = radius * radius_scale; + s = 1.0f / (2.0f * s * s); + + double_t sum = first_val; + temp_gaussian_kernel[0] = first_val; + float_t val = start; + for (size_t i = 1; i < kernel_size; i++) { + sum += temp_gaussian_kernel[i] = expf(-(val * val * s)) * step; + val += step; + } + + sum = 1.0f / sum; + for (size_t i = 0; i < kernel_size; i++) + gaussian_kernel[i * stride + offset] = (float_t)(temp_gaussian_kernel[i] * sum); + }; + + vec3 gauss[20]; + calculate_gaussian_kernel((float_t*)gauss, radius.x, 3, 0); + calculate_gaussian_kernel((float_t*)gauss, radius.y, 3, 1); + calculate_gaussian_kernel((float_t*)gauss, radius.z, 3, 2); + + vec3 intensity = this->intensity * (intensity_scale * 0.5f); + + gaussian_coef_shader_data gaussian_coef = {}; + for (int32_t i = 0; i < kernel_size && i < 8; i++) { + *(vec3*)&gaussian_coef.g_coef[i] = gauss[i] * intensity; + gaussian_coef.g_coef[i].w = 0.0f; + } + rctx_ptr->gaussian_coef_ubo.WriteMemory(gaussian_coef); + } + + static void make_ghost_quad(uint8_t flags, float_t opacity, mat4* mat, float_t*& data) { + const float_t x0 = flags & 0x01 ? 0.5f : 0.0f; + const float_t x1 = flags & 0x01 ? 1.0f : 0.5f; + const float_t y0 = flags & 0x02 ? 0.5f : 0.0f; + const float_t y1 = flags & 0x02 ? 1.0f : 0.5f; + + vec4 p0 = { -0.5f, -0.5f, x0, y0 }; + vec4 p1 = { 0.5f, -0.5f, x1, y0 }; + vec4 p2 = { -0.5f, 0.5f, x0, y1 }; + vec4 p3 = { 0.5f, 0.5f, x1, y1 }; + mat4_transform_point(mat, (vec2*)&p0, (vec2*)&p0); + mat4_transform_point(mat, (vec2*)&p1, (vec2*)&p1); + mat4_transform_point(mat, (vec2*)&p2, (vec2*)&p2); + mat4_transform_point(mat, (vec2*)&p3, (vec2*)&p3); + + *(vec4*)&data[0] = p0; + data[4] = opacity; + *(vec4*)&data[5] = p1; + data[9] = opacity; + *(vec4*)&data[10] = p2; + data[14] = opacity; + *(vec4*)&data[15] = p2; + data[19] = opacity; + *(vec4*)&data[20] = p1; + data[24] = opacity; + *(vec4*)&data[25] = p3; + data[29] = opacity; + data += 30; + } + + void Render::draw_lens_ghost() { + static const float_t v13[16] = { + -0.70f, -0.30f, 0.35f, 0.50f, + -0.45f, -0.80f, 0.20f, 0.41f, + 0.17f, -0.10f, 0.06f, 0.10f, + 0.14f, 0.04f, -0.13f, -0.22f, + }; + + static const float_t v14[16] = { + 0.8f, 1.0f, 1.0f, 1.0f, + 0.4f, 0.5f, 0.8f, 0.8f, + 0.6f, 0.7f, 0.8f, 0.7f, + 0.8f, 0.7f, 0.6f, 0.8f, + }; + + static const float_t v15[16] = { + 1.3f, 1.5f, 1.00f, 1.1f, + 2.5f, 0.8f, 0.50f, 0.5f, + 0.7f, 0.4f, 0.35f, 0.5f, + 0.4f, 0.3f, 0.60f, 0.4f, + }; + + if (!lens_flare_texture || lens_ghost_count <= 0) + return; + + if (lens_ghost_count > 16) + lens_ghost_count = 16; + + const float_t aspect = (float_t)render_width[0] / (float_t)render_height[0]; + + const float_t v7 = (lens_flare_pos.x - (float_t)(width / 2)) / (float_t)width; + const float_t v8 = -((lens_flare_pos.y - (float_t)(height / 2)) / (float_t)height); + const float_t v9 = (float_t)((1.1 - sqrtf(v8 * v8 + v7 * v7)) * lens_flare_power); + if (v9 < 0.001f) + return; + + const float_t v9a = v9 * v9; + + float_t angle = atan2f(v8, v7) - (float_t)M_PI_2; + const float_t angle_sin = sinf(angle); + const float_t angle_cos = cosf(angle); + + float_t* data = (float_t*)rctx_ptr->lens_ghost_vbo.MapMemory(); + if (!data) + return; + + const float_t lens_ghost = this->lens_ghost; + const int32_t lens_ghost_count = this->lens_ghost_count; + for (int32_t i = 0; i < lens_ghost_count; i++) { + float_t opacity = v9 * v14[i] * lens_ghost; + + float_t scale = (v9a * 0.03f + 0.02f) * v15[i]; + + mat4 mat; + mat4_translate(v13[i] * v7 + 0.5f, v13[i] * v8 + 0.5f, 0.0f, &mat); + mat4_scale_rot(&mat, scale, scale * aspect, 1.0f, &mat); + mat4_mul_rotate_z(&mat, angle_sin, angle_cos, &mat); + make_ghost_quad((uint8_t)(i & 0x03), opacity, &mat, data); + } + + rctx_ptr->lens_ghost_vbo.UnmapMemory(); + + glViewport(0, 0, render_width[0], render_height[0]); + rend_texture[0].Bind(); + gl_state_enable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ONE); + + uniform_value[U_REDUCE] = 4; + shaders_ft.set(SHADER_FT_REDUCE); + gl_state_active_bind_texture_2d(0, lens_ghost_texture); + gl_state_bind_vertex_array(rctx_ptr->lens_ghost_vao); + shaders_ft.draw_arrays(GL_TRIANGLES, 0, (GLsizei)(lens_ghost_count * 6LL)); + gl_state_bind_vertex_array(0); + + gl_state_disable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + } + + void Render::frame_texture_reset_capture() { + for (Render::FrameTexture& i : frame_texture) + if (&i - frame_texture) + i.capture = false; + } + + void Render::get_blur() { + uniform_value[U_ALPHA_MASK] = 0; + uniform_value[U_GAUSS] = 0; + shaders_ft.set(SHADER_FT_GAUSS); + calc_gaussian_blur(1.0f, 1.0f, 7, 0.8f, 1.0f); + rctx_ptr->gaussian_coef_ubo.Bind(1); + + downsample_texture.Bind(); + for (int32_t i = 1; i < 4; i++) { + glViewport(0, 0, reduce_width[i], reduce_height[i]); + gl_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + draw_quad(reduce_width[i], reduce_height[i], + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + + for (int32_t i = 1; i < 4; i++) { + glViewport(0, 0, reduce_width[i], reduce_height[i]); + gl_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + draw_quad(reduce_width[i], reduce_height[i], + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + + uniform_value[U_GAUSS] = 1; + shaders_ft.set(SHADER_FT_GAUSS); + + glViewport(0, 0, reduce_width[0], reduce_height[0]); + gl_state_active_bind_texture_2d(0, reduce_tex[0]->tex); + draw_quad(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_value[U_REDUCE] = 7; + shaders_ft.set(SHADER_FT_REDUCE); + + glViewport(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(); + gl_state_active_bind_texture_2d(0, downsample_texture.GetColorTex()); + gl_state_active_bind_texture_2d(1, reduce_tex[1]->tex); + gl_state_active_bind_texture_2d(2, reduce_tex[2]->tex); + gl_state_active_bind_texture_2d(3, reduce_tex[3]->tex); + draw_quad(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]->tex; + } + + void Render::get_frame_texture(GLuint tex, Render::FrameTextureType type) { + for (Render::FrameTexture& i : frame_texture) { + if (!i.capture) + continue; + + for (auto& j : i.data) { + if (!j.texture || j.type != type || j.render_texture.Bind() < 0) + continue; + + texture* dst_tex = j.texture; + + gl_state_active_bind_texture_2d(0, tex); + gl_state_bind_sampler(0, rctx_ptr->render_samplers[0]); + glViewport(0, 0, dst_tex->width, dst_tex->height); + uniform_value[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_state_bind_framebuffer(0); + } + } + } + + void Render::update_tone_map_lut() { + if (!update_lut) + return; + + update_lut = false; + saturate_lock = false; + + const float_t tone_map_scale = (float_t)(1.0 / (double_t)TONE_MAP_SAT_GAMMA_SAMPLES); + const int32_t tone_map_size = 16 * TONE_MAP_SAT_GAMMA_SAMPLES; + + vec2 tex_data[16 * TONE_MAP_SAT_GAMMA_SAMPLES]; + float_t gamma_power = gamma * gamma_rate * 1.5f; + int32_t saturate_power = this->saturate_power; + float_t saturate_coeff = this->saturate_coeff[saturate_index]; + + tex_data[0].x = 0.0f; + tex_data[0].y = 0.0f; + for (int32_t i = 1; i < tone_map_size; i++) { + float_t gamma = powf(1.0f - expf((float_t)-i * tone_map_scale), gamma_power); + float_t saturation = gamma * 2.0f - 1.0f; + for (int32_t j = 0; j < saturate_power; j++) { + saturation *= saturation; + saturation *= saturation; + saturation *= saturation; + saturation *= saturation; + } + + tex_data[i].x = gamma; + tex_data[i].y = gamma * saturate_coeff + * ((float_t)TONE_MAP_SAT_GAMMA_SAMPLES / (float_t)i) * (1.0f - saturation); + } + + if (GLAD_GL_VERSION_4_5) + glTextureSubImage2D(tonemap_lut_texture, 0, 0, 0, + 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); + else { + gl_state_bind_texture_2d(tonemap_lut_texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); + } + } + + static void generate_mlaa_area_texture(Render* rend) { + uint8_t* data = (uint8_t*)malloc(MLAA_SIDE_LEN * MLAA_SIDE_LEN * 2); + if (!data) + return; + + for (int32_t cross2 = 0; cross2 < 5; cross2++) + for (int32_t cross1 = 0; cross1 < 5; cross1++) + calculate_mlaa_area_texture_data(data, cross1, cross2); + + glGenTextures(1, &rend->mlaa_area_texture); + gl_state_bind_texture_2d(rend->mlaa_area_texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, MLAA_SIDE_LEN, MLAA_SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data); + gl_state_bind_texture_2d(0); + free(data); + } + + static void calculate_mlaa_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2) { + uint8_t* _data = &data[(MLAA_SIDE_LEN * MLAA_GRID_SIDE_LEN * cross2 + MLAA_GRID_SIDE_LEN * cross1) * 2]; + for (int32_t dright = 0; dright < MLAA_GRID_SIDE_LEN; dright++) { + for (int32_t dleft = 0; dleft < MLAA_GRID_SIDE_LEN; dleft++) { + float_t val_left = 0.0f; + float_t val_right = 0.0f; + calculate_mlaa_area_texture_data_inner(&val_left, &val_right, cross1, cross2, dleft, dright); + _data[0] = (uint8_t)(val_left * 255.9f); + _data[1] = (uint8_t)(val_right * 255.9f); + _data += 2; + } + _data += MLAA_GRID_SIDE_LEN * 4 * 2; + } + } + + static void calculate_mlaa_area_texture_data_inner(float_t* val_left, + float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright) { + auto 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; + if (a1 >= a2 - 1) + return (v3 * 0.5f) * 0.5f; + else + return ((float_t)(a1 + 1) * v2 + 0.5f + v3) * 0.5f; + }; + + int32_t dist = dleft + dright + 1; + float_t _val_left = 0.0f; + float_t _val_right = 0.0f; + switch (cross2) { + case 0: + switch (cross1) { + case 1: + _val_right = calc_area_tex_val(dleft, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 3: + _val_left = calc_area_tex_val(dleft, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + } + break; + case 1: + switch (cross1) { + case 0: + _val_right = calc_area_tex_val(dright, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 1: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_right = calc_area_tex_val(v15, v12) * 2.0f; + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft >= v12) + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + case 4: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + case 3: + switch (cross1) { + case 0: + _val_left = calc_area_tex_val(dright, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 1: + case 4: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = calc_area_tex_val(v15, v12) * 2.0f; + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + case 4: + switch (cross1) { + case 1: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + } + + *val_left = _val_left; + *val_right = _val_right; + return; + } +} diff --git a/src/CRE/render.hpp b/src/CRE/render.hpp new file mode 100644 index 00000000..b34d2d8a --- /dev/null +++ b/src/CRE/render.hpp @@ -0,0 +1,262 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/light_param/glow.hpp" +#include "../KKdLib/vec.hpp" +#include "GL/uniform_buffer.hpp" +#include "renderer/dof.hpp" +#include "renderer/transparency.hpp" +#include "camera.hpp" + +namespace rndr { + struct Render { + enum MagFilterType { + MAG_FILTER_NEAREST = 0, + MAG_FILTER_BILINEAR, + MAG_FILTER_SHARPEN_5_TAP, + MAG_FILTER_SHARPEN_4_TAP, + MAG_FILTER_CONE_4_TAP, + MAG_FILTER_CONE_2_TAP, + MAG_FILTER_MAX, + }; + + enum FrameTextureType { + FRAME_TEXTURE_PRE_PP = 0, + FRAME_TEXTURE_POST_PP, + FRAME_TEXTURE_FB, + FRAME_TEXTURE_MAX, + }; + + struct ExposureCharaData { + vec4 spot_coefficients[8]; + float_t spot_weight; + GLuint query[3]; + GLuint query_data[3]; + + ExposureCharaData(); + ~ExposureCharaData(); + + void reset(); + }; + + struct FrameTextureData { + texture* texture; + RenderTexture render_texture; + FrameTextureType type; + + FrameTextureData(); + ~FrameTextureData(); + }; + + struct FrameTexture { + FrameTextureData data[4]; + bool capture; + + FrameTexture(); + ~FrameTexture(); + }; + + int32_t downsample_count; + int32_t downsample_max_count; + int32_t ssaa; + int32_t taa; + int32_t mlaa; + int32_t cam_blur; + int32_t hd_res; + int32_t base_downsample; + int32_t ss_alpha_mask; + RenderTexture rend_texture[5]; + RenderTexture taa_buffer[3]; + texture* taa_tex[3]; + RenderTexture aet_back_texture; + texture* aet_back_tex; + RenderTexture downsample_texture; + RenderTexture reduce_texture[5]; + texture* reduce_tex[5]; + RenderTexture field_340; + GLuint reduce_tex_draw; + RenderTexture exposure_texture; + GLuint exposure_tex; + texture* exposure_history; + RenderTexture field_3B8; + RenderTexture field_3E8; + GLuint tonemap_lut_texture; + RenderTexture mlaa_buffer; + RenderTexture temp_buffer; + GLuint mlaa_area_texture; + RenderTexture* sss_contour_texture; + int32_t texture_counter; + GLuint lens_shaft_query[3]; + GLuint lens_flare_query[3]; + GLuint lens_shaft_query_data[3]; + GLuint lens_flare_query_data[3]; + int32_t lens_flare_query_index; + GLuint lens_flare_texture; + GLuint lens_shaft_texture; + GLuint lens_ghost_texture; + int32_t lens_ghost_count; + int32_t width; + int32_t height; + int32_t inner_width; + int32_t inner_height; + int32_t render_width[5]; + int32_t render_height[5]; + int32_t render_post_width[5]; + int32_t render_post_height[5]; + float_t render_post_width_scale; + float_t render_post_height_scale; + int32_t reduce_width[5]; + int32_t reduce_height[5]; + int32_t taa_texture_selector; + int32_t taa_texture; + float_t taa_blend; + vec3 view_point; + vec3 interest; + vec3 view_point_prev; + vec3 interest_prev; + mat4 cam_view_projection; + mat4 cam_view_projection_prev; + int32_t stage_index; + int32_t stage_index_prev; + bool reset_exposure; + int32_t screen_x_offset; + int32_t screen_y_offset; + int32_t screen_width; + int32_t screen_height; + int32_t update_lut; + int32_t saturate_lock; + ExposureCharaData exposure_chara_data[6]; + int32_t exposure_history_counter; + int32_t exposure_query_index; + vec3 lens_flare_pos; + float_t lens_shaft_scale; + float_t lens_shaft_inv_scale; + float_t lens_flare_power; + float_t field_A10; + float_t lens_flare_appear_power; + texture* render_textures_data[16]; + RenderTexture render_textures[16]; + texture* movie_textures_data[1]; + RenderTexture movie_textures[1]; + int32_t aet_back; + renderer::DOF3* dof; + texture* transparency_tex[1]; + renderer::Transparency* transparency; + int32_t saturate_index; + int32_t scene_fade_index; + int32_t tone_trans_index; + float_t saturate_coeff[2]; + vec3 scene_fade_color[2]; + float_t scene_fade_alpha[2]; + int32_t scene_fade_blend_func[2]; + vec3 tone_trans_scale[2]; + vec3 tone_trans_offset[2]; + vec3 tone_trans_start[2]; + vec3 tone_trans_end[2]; + tone_map_method tone_map; + float_t exposure; + float_t exposure_rate; + int32_t auto_exposure; + float_t gamma; + float_t gamma_rate; + int32_t saturate_power; + MagFilterType mag_filter; + float_t fade_alpha; + int32_t fade; + float_t lens_flare; + float_t lens_shaft; + float_t lens_ghost; + vec3 radius; + vec3 intensity; + int32_t update; + FrameTexture frame_texture[6]; + + Render(); + ~Render(); + + void apply_post_process(camera* cam, texture* light_proj_tex, int32_t npr_param); + void bind_render_texture(bool aet_back = false); + void ctrl(camera* cam); + void draw_quad(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(camera* cam); + bool frame_texture_cont_capture_set(bool value); + void frame_texture_free(); + int32_t frame_texture_load(int32_t slot, FrameTextureType type, texture* tex); + void frame_texture_reset(); + bool frame_texture_slot_capture_set(int32_t index); + bool frame_texture_unload(int32_t slot, texture* tex); + void free(); + bool get_auto_exposure(); + float_t get_exposure(); + void get_exposure_chara_data(camera* cam); + float_t get_exposure_rate(); + float_t get_gamma(); + float_t get_gamma_rate(); + vec3 get_intensity(); + vec3 get_lens(); + float_t get_lens_flare_appear_power(); + float_t get_lens_flare_power(); + vec3 get_radius(); + float_t get_saturate_coeff(); + int32_t get_saturate_power(); + vec4 get_scene_fade(); + float_t get_scene_fade_alpha(); + int32_t get_scene_fade_blend_func(); + vec3 get_scene_fade_color(); + int32_t get_taa(); + tone_map_method get_tone_map(); + void get_tone_trans(vec3& start, vec3& end); + 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(); + int32_t movie_texture_set(texture* movie_texture); + void movie_texture_free(texture* movie_texture); + int32_t render_texture_set(texture* render_texture, bool task_photo); + void render_texture_free(texture* render_texture, bool task_photo); + void reset_saturate_coeff(int32_t index, bool lock); + void reset_scene_fade(int32_t index); + void reset_tone_trans(int32_t index); + void resize(int32_t width, int32_t height); + void set_auto_exposure(bool value); + void set_exposure(float_t value); + void set_exposure_rate(float_t value); + void set_gamma(float_t value); + void set_gamma_rate(float_t value); + void set_intensity(const vec3& value); + void set_lens(vec3 value); + void set_radius(const vec3& value); + void set_saturate_coeff(float_t value, int32_t index, bool lock); + void set_saturate_power(int32_t value); + void set_scene_fade(const vec4& value, int32_t index); + void set_scene_fade_alpha(float_t value, int32_t index); + void set_scene_fade_blend_func(int32_t value, int32_t index); + void set_scene_fade_color(const vec3& value, int32_t index); + void set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height); + void set_taa(int32_t value); + void set_tone_map(tone_map_method value); + void set_tone_trans(const vec3& start, const vec3& end, int32_t index); + void transparency_combine(float_t alpha); + void transparency_copy(); + void update_res(bool set, int32_t base_downsample); + + private: + void apply_mlaa(int32_t ss_alpha_mask); + void apply_tone_map(texture* light_proj_tex, int32_t npr_param); + void calc_exposure(camera* cam); + void calc_gaussian_blur(float_t start, float_t step, + int32_t kernel_size, float_t radius_scale, float_t intensity_scale); + void draw_lens_ghost(); + void downsample(); + void frame_texture_reset_capture(); + void get_blur(); + void get_frame_texture(GLuint tex, FrameTextureType type); + void update_tone_map_lut(); + }; +} + diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index ea2edbaa..523e8396 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -4,26 +4,19 @@ */ #include "render_context.hpp" -#include "../KKdLib/sort.hpp" -#include "Glitter/glitter.hpp" -#include "rob/rob.hpp" -#include "file_handler.hpp" -#include "render_manager.hpp" #include "shader_ft.hpp" -#include "sprite.hpp" #include "sound.hpp" -#include "stage.hpp" +#include "sprite.hpp" +#include "task.hpp" float_t delta_frame_history = 0; int32_t delta_frame_history_int = 0; +extern float_t rob_frame; extern render_context* rctx_ptr; //extern void dw_gui_ctrl_disp(); -static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, - int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]); - static void render_context_light_param_data_ibl_set_diffuse(light_param_ibl_diffuse* diffuse, int32_t level); static void render_context_light_param_data_ibl_set_specular(light_param_ibl_specular* specular); @@ -44,42 +37,6 @@ static const GLuint MORPH_TEXCOORD0_INDEX = 13; static const GLuint MORPH_TEXCOORD1_INDEX = 14; static const GLuint BONE_INDEX_INDEX = 15; -struct struc_189 { - GLenum type; - int32_t width; - int32_t height; - int32_t max_level; - GLenum color_format; - GLenum depth_format; -}; - -static const struc_189 stru_140A24420[] = { - { GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA8 , GL_DEPTH_COMPONENT24 }, - { GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA16F, GL_DEPTH_COMPONENT24 }, - { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, - { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, - { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, - { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO }, - { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA32F, GL_ZERO }, - { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO }, - { GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA16F, GL_ZERO }, // Extra for buf -}; - -static const int32_t stru_140A244E0[][3] = { - { 1, 1, 1 }, - { 0, 0, 0 }, - { 6, 6, 6 }, - { 6, 6, 6 }, - { 6, 6, 6 }, - { 2, 2, 2 }, - { 3, 3, 3 }, - { 4, 4, 4 }, - { 5, 5, 5 }, - { 6, 6, 6 }, - { 7, 7, 7 }, - { 8, 8, 8 }, // Extra for buf -}; - draw_state_stats::draw_state_stats() : object_draw_count(), object_translucent_draw_count(), object_reflect_draw_count(), field_C(), field_10(), draw_count(), draw_triangle_count(), field_1C() { @@ -96,22 +53,6 @@ void draw_state_stats::reset() { field_1C = 0; } -sss_data::sss_data() : init(), enable(), npr_contour(), param() { - init = true; - enable = true; - npr_contour = true; - param = { 0.0f, 0.0f, 0.0f, 1.0f }; - - textures[0].Init(640, 360, 0, GL_RGBA16F, GL_ZERO /*GL_DEPTH_COMPONENT32F*/); - textures[1].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); - textures[2].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); - textures[3].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); -} - -sss_data::~sss_data() { - -} - draw_state::draw_state() : wireframe(), wireframe_overlay(), light(), self_shadow(), shader_debug_flag(), use_global_material(), fog_height(), ex_data_mat(), field_68() { shader = true; @@ -129,227 +70,26 @@ void draw_state::set_fog_height(bool value) { fog_height = value; } -material_list_struct::material_list_struct() : blend_color(), -has_blend_color(), emission(), has_emission() { - hash = (uint32_t)-1; +sss_data::sss_data() : init_data(), enable(), npr_contour(), param() { + init_data = true; + enable = true; + npr_contour = true; + param = { 0.0f, 0.0f, 0.0f, 1.0f }; } -material_list_struct::material_list_struct(uint32_t hash, vec4& blend_color, - vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission) : hash(hash), blend_color(blend_color), - has_blend_color(has_blend_color), emission(emission), has_emission(has_emission) { +sss_data::~sss_data() { } -texture_pattern_struct::texture_pattern_struct() : src(), dst() { +void sss_data::free() { } -texture_pattern_struct::texture_pattern_struct(texture_id src, texture_id dst) : src(src), dst(dst) { - -} - -texture_transform_struct::texture_transform_struct() { - id = (uint32_t)-1; - mat = mat4_identity; -} - -texture_transform_struct::texture_transform_struct(uint32_t id, mat4& mat) : id(id), mat(mat) { - -} - -namespace mdl { - EtcObjTeapot::EtcObjTeapot() { - size = 1.0f; - } - - EtcObjGrid::EtcObjGrid() { - w = 10; - h = 10; - ws = 20; - hs = 20; - } - - EtcObjCube::EtcObjCube() : wire() { - - } - - EtcObjSphere::EtcObjSphere() : wire() { - radius = 1.0f; - slices = 8; - stacks = 8; - } - - EtcObjPlane::EtcObjPlane() { - w = 10; - h = 10; - } - - EtcObjCone::EtcObjCone() : wire() { - base = 1.0f; - height = 1.0f; - slices = 8; - stacks = 8; - } - - EtcObjLine::EtcObjLine() { - pos[0] = { 0.0f, 0.0f, 0.0f }; - pos[1] = { 0.0f, 0.0f, 1.0f }; - } - - EtcObjCross::EtcObjCross() { - size = 0.1f; - } - - EtcObjCapsule::EtcObjCapsule() : wire() { - radius = 1.0f; - slices = 8; - stacks = 8; - pos[0] = { 0.0f, 0.0f, 0.0f }; - pos[1] = { 0.0f, 0.0f, 1.0f }; - } - - EtcObjEllipse::EtcObjEllipse() : wire() { - radius = 1.0f; - slices = 8; - stacks = 8; - pos[0] = { 0.0f, 0.0f, 0.0f }; - pos[1] = { 0.0f, 0.0f, 1.0f }; - } - - EtcObjCylinder::EtcObjCylinder() : wire() { - base = 1.0f; - top = 1.0f; - height = 1.0f; - slices = 8; - stacks = 8; - } - - EtcObj::Data::Data() : capsule() { - - } - - EtcObj::EtcObj() : type(), constant(), count(), offset() { - - } - - void EtcObj::init(EtcObjType type) { - this->type = type; - color = 0xFFFFFFFF; - //fog = false; - constant = false; - switch (type) { - case ETC_OBJ_TEAPOT: - data.teapot = {}; - break; - case ETC_OBJ_GRID: - data.grid = {}; - break; - case ETC_OBJ_CUBE: - data.cube = {}; - break; - case ETC_OBJ_SPHERE: - data.sphere = {}; - break; - case ETC_OBJ_PLANE: - data.plane = {}; - break; - case ETC_OBJ_CONE: - data.cone = {}; - break; - case ETC_OBJ_LINE: - data.line = {}; - break; - case ETC_OBJ_CROSS: - data.cross = {}; - break; - case ETC_OBJ_CAPSULE: // Added - data.capsule = {}; - break; - case ETC_OBJ_ELLIPSE: // Added - data.ellipse = {}; - break; - case ETC_OBJ_CYLINDER: // Added - data.cylinder = {}; - break; - } - } - - void ObjData::init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc) { - kind = mdl::OBJ_KIND_ETC; - this->mat = *mat; - args.etc = *etc; - - disp_manager->add_vertex_array(&args.etc, this->mat); - } - - void ObjData::init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, - obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, - int32_t mat_count, mat4* mats, /*GLuint vertex_buffer, GLuint index_buffer,*/ - obj_mesh_vertex_buffer* vertex_buffer, obj_mesh_index_buffer* index_buffer, vec4* blend_color, - vec4* emission, /*GLuint morph_vertex_buffer,*/ obj_mesh_vertex_buffer* morph_vertex_buffer, - int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)) { - kind = mdl::OBJ_KIND_NORMAL; - this->mat = *mat; - this->radius = radius; - - mdl::ObjSubMeshArgs* args = &this->args.sub_mesh; - args->mesh = mesh; - args->morph_weight = disp_manager->morph.weight; - args->material = material; - args->sub_mesh = sub_mesh; - args->textures = textures; - args->mat_count = mat_count; - args->mats = mats; - args->vertex_buffer = vertex_buffer; - args->index_buffer = index_buffer; - args->morph_vertex_buffer = morph_vertex_buffer; - - args->texture_pattern_count = disp_manager->texture_pattern_count; - for (int32_t i = 0; i < disp_manager->texture_pattern_count && i < TEXTURE_PATTERN_COUNT; i++) - args->texture_pattern_array[i] = disp_manager->texture_pattern_array[i]; - - args->texture_transform_count = disp_manager->texture_transform_count; - for (int32_t i = 0; i < disp_manager->texture_transform_count && i < TEXTURE_TRANSFORM_COUNT; i++) - args->texture_transform_array[i] = disp_manager->texture_transform_array[i]; - - if (blend_color && *blend_color != 1.0f) { - args->set_blend_color = true; - args->blend_color = *blend_color; - } - else { - args->set_blend_color = false; - args->blend_color = 1.0f; - } - - args->emission = *emission; - - args->chara_color = disp_manager->chara_color; - args->self_shadow = disp_manager->obj_flags & (mdl::OBJ_8 | mdl::OBJ_4) ? 1 : 0; - args->shadow = disp_manager->shadow_type; - args->texture_color_coefficients = disp_manager->texture_color_coefficients; - args->texture_color_coefficients.w = disp_manager->wet_param; - args->texture_color_offset = disp_manager->texture_color_offset; - args->texture_specular_coefficients = disp_manager->texture_specular_coefficients; - args->texture_specular_offset = disp_manager->texture_specular_offset; - args->instances_count = instances_count; - args->instances_mat = instances_mat; - args->func = func; - - disp_manager->add_vertex_array(args); - } - - void ObjData::init_translucent(const mat4* mat, ObjTranslucentArgs* translucent) { - kind = mdl::OBJ_KIND_TRANSLUCENT; - this->mat = *mat; - args.translucent = *translucent; - } - - void ObjData::init_user(const mat4* mat, UserArgsFunc func, void* data) { - kind = OBJ_KIND_USER; - this->mat = *mat; - args.user.func = func; - args.user.data = data; - } +void sss_data::init() { + textures[0].Init(640, 360, 0, GL_RGBA16F, GL_ZERO /*GL_DEPTH_COMPONENT32F*/); + textures[1].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); + textures[2].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); + textures[3].Init(320, 180, 0, GL_RGBA16F, GL_ZERO); } light_proj::light_proj(int32_t width, int32_t height) : enable(), texture_id() { @@ -369,7 +109,7 @@ void light_proj::resize(int32_t width, int32_t height) { draw_texture.Init(width, height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F); } -bool light_proj::set(render_context* rctx) { +bool light_proj::set() { if (!this) return false; @@ -383,8 +123,8 @@ bool light_proj::set(render_context* rctx) { glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); glClearBufferfv(GL_DEPTH, 0, &depth_clear); - if (set_mat(rctx, false)) { - rctx->draw_state.shader_index = SHADER_FT_SIL; + if (set_mat(false)) { + rctx_ptr->draw_state->shader_index = SHADER_FT_SIL; uniform_value[U0A] = 1; return true; } @@ -399,7 +139,8 @@ bool light_proj::set(render_context* rctx) { return false; } -bool light_proj::set_mat(render_context* rctx, bool set_mat) { +bool light_proj::set_mat(bool set_mat) { + render_context* rctx = rctx_ptr; light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; light_data* data = &set->lights[LIGHT_PROJECTION]; if (data->get_type() != LIGHT_SPOT) @@ -444,3049 +185,6 @@ bool light_proj::set_mat(render_context* rctx, bool set_mat) { return true; } -morph_struct::morph_struct() : weight() { - -} - -texture_data_struct::texture_data_struct() : field_0() { - -} - -namespace mdl { - DispManager::DispManager() : obj_flags(), shadow_type(), field_8(), field_C(), - culling(), show_alpha_center(), show_mat_center(), texture_pattern_count(), - texture_pattern_array(), wet_param(), texture_transform_count(), - texture_transform_array(), material_list_count(), material_list_array() { - put_index = -1; - object_culling = true; - object_sort = true; - chara_color = true; - buff_offset = 0; - buff_max = 0; - buff_size = 0x300000; - buff = force_malloc(0x300000); - texture_color_coefficients = 1.0f; - texture_color_offset = 0.0f; - texture_specular_coefficients = 1.0f; - texture_specular_offset = 0.0f; - } - - DispManager::~DispManager() { - for (DispManager::vertex_array& i : vertex_array_cache) - glDeleteVertexArrays(1, &i.vertex_array); - vertex_array_cache.clear(); - - for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { - glDeleteVertexArrays(1, &i.vertex_array); - - i.vertex_buffer.Destroy(); - i.index_buffer.Destroy(); - } - etc_vertex_array_cache.clear(); - - free_def(buff); - } - - void DispManager::add_vertex_array(ObjSubMeshArgs* args) { - const obj_mesh* mesh = args->mesh; - const obj_sub_mesh* sub_mesh = args->sub_mesh; - const obj_material_data* material = args->material; - - //GLuint vertex_buffer = args->vertex_buffer; - obj_mesh_vertex_buffer* vertex_buffer = args->vertex_buffer; - //GLuint morph_vertex_buffer = args->morph_vertex_buffer; - obj_mesh_vertex_buffer* morph_vertex_buffer = args->morph_vertex_buffer; - //GLuint index_buffer = args->index_buffer; - obj_mesh_index_buffer* index_buffer = args->index_buffer; - - int32_t texcoord_array[2] = { -1, -1 }; - int32_t color_tex_index = 0; - for (const obj_material_texture_data& i : material->material.texdata) { - if (i.tex_index == -1) - continue; - - int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( - i.shader_info.m.tex_type, color_tex_index); - if (texcoord_index < 0) - continue; - - texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; - - if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) - color_tex_index++; - } - - GLuint vertex_attrib_buffer_binding[16] = {}; - object_data_get_vertex_attrib_buffer_bindings(args, - texcoord_array, vertex_attrib_buffer_binding); - - bool compressed = mesh->attrib.m.compressed; - GLsizei size_vertex = (GLsizei)mesh->size_vertex; - obj_vertex_format vertex_format = mesh->vertex_format; - - DispManager::vertex_array* vertex_array = 0; - for (DispManager::vertex_array& i : vertex_array_cache) - if (i.alive_time >= 0 && i.vertex_buffer == vertex_buffer - && i.morph_vertex_buffer == morph_vertex_buffer - && i.index_buffer == index_buffer && i.vertex_format == vertex_format - && i.size_vertex == size_vertex && i.compressed == compressed - && !memcmp(i.vertex_attrib_buffer_binding, - vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) - && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) - if (i.vertex_array) { - i.alive_time = 60; - return; - } - else { - vertex_array = &i; - break; - } - - if (!vertex_array) - for (DispManager::vertex_array& i : vertex_array_cache) - if (i.alive_time <= 0) { - vertex_array = &i; - break; - } - - if (!vertex_array) { - vertex_array_cache.push_back({}); - vertex_array = &vertex_array_cache.back(); - } - - if (!vertex_array->vertex_array) { - glGenVertexArrays(1, &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); - glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - 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); - } - - vertex_array->vertex_buffer = vertex_buffer; - vertex_array->morph_vertex_buffer = morph_vertex_buffer; - vertex_array->index_buffer = index_buffer; - vertex_array->alive_time = 60; - vertex_array->vertex_format = vertex_format; - vertex_array->size_vertex = size_vertex; - vertex_array->compressed = compressed; - memcpy(&vertex_array->texcoord_array, texcoord_array, sizeof(texcoord_array)); - memcpy(&vertex_array->vertex_attrib_buffer_binding, - vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)); - - gl_state_bind_vertex_array(vertex_array->vertex_array); - //gl_state_bind_array_buffer(vertex_buffer); - gl_state_bind_array_buffer(vertex_buffer->get_buffer()); - if (index_buffer) - //gl_state_bind_element_array_buffer(index_buffer, true); - gl_state_bind_element_array_buffer(index_buffer->buffer, true); - -#if SHARED_OBJECT_BUFFER - //size_t offset = vertex_buffer_offset; - size_t offset = vertex_buffer->get_offset(); -#else - size_t offset = 0; -#endif - if (vertex_format & OBJ_VERTEX_POSITION) { - if (!vertex_array->vertex_attrib_array[POSITION_INDEX]) { - glEnableVertexAttribArray(POSITION_INDEX); - vertex_array->vertex_attrib_array[POSITION_INDEX] = true; - } - - 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; - } - - if (vertex_format & OBJ_VERTEX_NORMAL) { - if (!vertex_array->vertex_attrib_array[NORMAL_INDEX]) { - glEnableVertexAttribArray(NORMAL_INDEX); - vertex_array->vertex_attrib_array[NORMAL_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(NORMAL_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 12; - } - else { - glVertexAttribPointer(NORMAL_INDEX, - 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[NORMAL_INDEX]) { - glDisableVertexAttribArray(NORMAL_INDEX); - vertex_array->vertex_attrib_array[NORMAL_INDEX] = false; - } - - if (vertex_format & OBJ_VERTEX_TANGENT) { - if (!vertex_array->vertex_attrib_array[TANGENT_INDEX]) { - glEnableVertexAttribArray(TANGENT_INDEX); - vertex_array->vertex_attrib_array[TANGENT_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(TANGENT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else { - glVertexAttribPointer(TANGENT_INDEX, - 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[TANGENT_INDEX]) { - glDisableVertexAttribArray(TANGENT_INDEX); - vertex_array->vertex_attrib_array[TANGENT_INDEX] = false; - } - - if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) - offset += 12; - - for (int32_t i = 0; i < 2; i++) { - int32_t texcoord_index = texcoord_array[i]; - if (texcoord_index < 0) { - if (vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { - glDisableVertexAttribArray(TEXCOORD0_INDEX + i); - vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = false; - } - continue; - } - - if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) { - if (!vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { - glEnableVertexAttribArray(TEXCOORD0_INDEX + i); - vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = true; - } - - if (!compressed) - glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_FLOAT, GL_FALSE, - size_vertex, (void*)(offset + 8ULL * texcoord_index)); - else - glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_HALF_FLOAT, GL_FALSE, - size_vertex, (void*)(offset + 4ULL * texcoord_index)); - } - } - - if (!compressed) { - if (vertex_format & OBJ_VERTEX_TEXCOORD0) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD1) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 8; - } - else { - if (vertex_format & OBJ_VERTEX_TEXCOORD0) - offset += 4; - if (vertex_format & OBJ_VERTEX_TEXCOORD1) - offset += 4; - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 4; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 4; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) { - if (!vertex_array->vertex_attrib_array[COLOR0_INDEX]) { - glEnableVertexAttribArray(COLOR0_INDEX); - vertex_array->vertex_attrib_array[COLOR0_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(COLOR0_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else { - glVertexAttribPointer(COLOR0_INDEX, - 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[COLOR0_INDEX]) { - glDisableVertexAttribArray(COLOR0_INDEX); - vertex_array->vertex_attrib_array[COLOR0_INDEX] = false; - } - - if (vertex_format & OBJ_VERTEX_COLOR1) - offset += 16; - - if (vertex_format & OBJ_VERTEX_BONE_DATA) { - if (!vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { - glEnableVertexAttribArray(BONE_WEIGHT_INDEX); - vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(BONE_WEIGHT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else { - glVertexAttribPointer(BONE_WEIGHT_INDEX, - 4, GL_UNSIGNED_SHORT, GL_TRUE, size_vertex, (void*)offset); - offset += 8; - } - - if (!vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { - glEnableVertexAttribArray(BONE_INDEX_INDEX); - vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = true; - } - - glVertexAttribIPointer(BONE_INDEX_INDEX, - 4, GL_SHORT, size_vertex, (void*)offset); - offset += 8; - } - else { - if (vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { - glDisableVertexAttribArray(BONE_WEIGHT_INDEX); - vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { - glDisableVertexAttribArray(BONE_INDEX_INDEX); - vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = false; - } - } - - if (!compressed && vertex_format & OBJ_VERTEX_UNKNOWN) { - if (!vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { - glEnableVertexAttribArray(UNKNOWN_INDEX); - vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = true; - } - - glVertexAttribPointer(UNKNOWN_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else if (vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { - glDisableVertexAttribArray(UNKNOWN_INDEX); - vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = false; - } - - if (morph_vertex_buffer) { - //gl_state_bind_array_buffer(morph_vertex_buffer); - gl_state_bind_array_buffer(morph_vertex_buffer->get_buffer()); - -#if SHARED_OBJECT_BUFFER - //size_t offset = morph_vertex_buffer_offset; - size_t offset = morph_vertex_buffer->get_offset(); -#else - size_t offset = 0; -#endif - if (vertex_format & OBJ_VERTEX_POSITION) { - if (!vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { - glEnableVertexAttribArray(MORPH_POSITION_INDEX); - vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = true; - } - - glVertexAttribPointer(MORPH_POSITION_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 12; - } - else if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { - glDisableVertexAttribArray(MORPH_POSITION_INDEX); - vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; - } - - if (vertex_format & OBJ_VERTEX_NORMAL) { - if (!vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { - glEnableVertexAttribArray(MORPH_NORMAL_INDEX); - vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(MORPH_NORMAL_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 12; - } - else { - glVertexAttribPointer(MORPH_NORMAL_INDEX, - 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { - glDisableVertexAttribArray(MORPH_NORMAL_INDEX); - vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; - } - - if (vertex_format & OBJ_VERTEX_TANGENT) { - if (!vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { - glEnableVertexAttribArray(MORPH_TANGENT_INDEX); - vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(MORPH_TANGENT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else { - glVertexAttribPointer(MORPH_TANGENT_INDEX, - 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { - glDisableVertexAttribArray(MORPH_TANGENT_INDEX); - vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; - } - - if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) - offset += 12; - - if (vertex_format & OBJ_VERTEX_TEXCOORD0) { - if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { - glEnableVertexAttribArray(MORPH_TEXCOORD0_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, - 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; - } - else { - glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, - 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 4; - } - } - else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { - glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD1) { - if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { - glEnableVertexAttribArray(MORPH_TEXCOORD1_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = true; - } - - if (!compressed) { - glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, - 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; - } - else { - glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, - 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 4; - } - } - else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { - glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; - } - - if (!compressed) { - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 8; - } - else { - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 4; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 4; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) { - uniform_value[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; - } - - if (!compressed) { - glVertexAttribPointer(MORPH_COLOR_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; - } - else { - glVertexAttribPointer(MORPH_COLOR_INDEX, - 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; - } - } - else if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { - glDisableVertexAttribArray(MORPH_COLOR_INDEX); - vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; - } - - if (!compressed) { - if (vertex_format & OBJ_VERTEX_COLOR1) - offset += 16; - - if (vertex_format & OBJ_VERTEX_BONE_DATA) - offset += 32; - - if (vertex_format & OBJ_VERTEX_UNKNOWN) - offset += 16; - } - else { - if (vertex_format & OBJ_VERTEX_BONE_DATA) - offset += 16; - } - } - else { - if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { - glDisableVertexAttribArray(MORPH_POSITION_INDEX); - vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { - glDisableVertexAttribArray(MORPH_NORMAL_INDEX); - vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { - glDisableVertexAttribArray(MORPH_TANGENT_INDEX); - vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { - glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { - glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); - vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; - } - - if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { - glDisableVertexAttribArray(MORPH_COLOR_INDEX); - vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; - } - } - - gl_state_bind_array_buffer(0); - gl_state_bind_vertex_array(0); - if (index_buffer) - gl_state_bind_element_array_buffer(0); - } - - static void gen_cube_vertices(std::vector& data) { - data.resize(sizeof(vec3) * 2 * 4 * 6); - - vec3* vtx = (vec3*)data.data(); - *vtx++ = { -1.0f, -1.0f, -1.0f }; - *vtx++ = { 0.0f, 0.0f, -1.0f }; - *vtx++ = { 1.0f, 1.0f, -1.0f }; - *vtx++ = { 0.0f, 0.0f, -1.0f }; - *vtx++ = { 1.0f, -1.0f, -1.0f }; - *vtx++ = { 0.0f, 0.0f, -1.0f }; - *vtx++ = { -1.0f, 1.0f, -1.0f }; - *vtx++ = { 0.0f, 0.0f, -1.0f }; - - *vtx++ = { -1.0f, -1.0f, 1.0f }; - *vtx++ = { 0.0f, 0.0f, 1.0f }; - *vtx++ = { 1.0f, -1.0f, 1.0f }; - *vtx++ = { 0.0f, 0.0f, 1.0f }; - *vtx++ = { 1.0f, 1.0f, 1.0f }; - *vtx++ = { 0.0f, 0.0f, 1.0f }; - *vtx++ = { -1.0f, 1.0f, 1.0f }; - *vtx++ = { 0.0f, 0.0f, 1.0f }; - - *vtx++ = { -1.0f, 1.0f, 1.0f }; - *vtx++ = { -1.0f, 0.0f, 0.0f }; - *vtx++ = { -1.0f, 1.0f, -1.0f }; - *vtx++ = { -1.0f, 0.0f, 0.0f }; - *vtx++ = { -1.0f, -1.0f, -1.0f }; - *vtx++ = { -1.0f, 0.0f, 0.0f }; - *vtx++ = { -1.0f, -1.0f, 1.0f }; - *vtx++ = { -1.0f, 0.0f, 0.0f }; - - *vtx++ = { 1.0f, 1.0f, -1.0f }; - *vtx++ = { 1.0f, 0.0f, 0.0f }; - *vtx++ = { 1.0f, 1.0f, 1.0f }; - *vtx++ = { 1.0f, 0.0f, 0.0f }; - *vtx++ = { 1.0f, -1.0f, -1.0f }; - *vtx++ = { 1.0f, 0.0f, 0.0f }; - *vtx++ = { 1.0f, -1.0f, 1.0f }; - *vtx++ = { 1.0f, 0.0f, 0.0f }; - - *vtx++ = { -1.0f, -1.0f, -1.0f }; - *vtx++ = { 0.0f, -1.0f, 0.0f }; - *vtx++ = { 1.0f, -1.0f, -1.0f }; - *vtx++ = { 0.0f, -1.0f, 0.0f }; - *vtx++ = { 1.0f, -1.0f, 1.0f }; - *vtx++ = { 0.0f, -1.0f, 0.0f }; - *vtx++ = { -1.0f, -1.0f, 1.0f }; - *vtx++ = { 0.0f, -1.0f, 0.0f }; - - *vtx++ = { -1.0f, 1.0f, -1.0f }; - *vtx++ = { 0.0f, 1.0f, 0.0f }; - *vtx++ = { 1.0f, 1.0f, 1.0f }; - *vtx++ = { 0.0f, 1.0f, 0.0f }; - *vtx++ = { 1.0f, 1.0f, -1.0f }; - *vtx++ = { 0.0f, 1.0f, 0.0f }; - *vtx++ = { -1.0f, 1.0f, 1.0f }; - *vtx++ = { 0.0f, 1.0f, 0.0f }; - } - - static size_t gen_cube_indices(std::vector& indices) { - const uint32_t sides_indices[] = { - 0, 1, 2, 0, 3, 1, - 4, 5, 6, 6, 7, 4, - 8, 9, 10, 10, 11, 8, - 12, 13, 14, 15, 14, 13, - 16, 17, 18, 18, 19, 16, - 20, 21, 22, 20, 23, 21, - }; - - const uint32_t edges_indices[] = { - 0, 2, 1, 2, 0, 3, 1, 3, - 4, 5, 6, 5, 4, 7, 6, 7, - 0, 4, 1, 6, 2, 5, 3, 7, - }; - - indices.insert(indices.end(), sides_indices, - sides_indices + sizeof(sides_indices) / sizeof(uint32_t)); - - size_t wire_offset = indices.size(); - - indices.insert(indices.end(), edges_indices, - edges_indices + sizeof(edges_indices) / sizeof(uint32_t)); - - return wire_offset; - } - - static void gen_sphere_vertices(std::vector& data, - int32_t slices, int32_t stacks, float_t radius) { - if (slices < 2 || stacks < 2) - return; - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(radius); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(1.0f); - data.push_back(0.0f); - - double_t slice_step = (M_PI * 2.0) / (double_t)slices; - double_t stack_step = M_PI / (double_t)stacks; - - for (int32_t i = 1; i < stacks; i++) { - float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); - float_t xz = cosf(stack_angle); - float_t y = sinf(stack_angle); - - data.reserve(sizeof(vec3) * 2 * slices); - - for (int32_t j = 0; j < slices; j++) { - float_t slice_angle = (float_t)((double_t)j * slice_step); - - float_t x = xz * cosf(slice_angle); - float_t z = xz * sinf(slice_angle); - - data.push_back(x * radius); - data.push_back(y * radius); - data.push_back(z * radius); - - data.push_back(x); - data.push_back(y); - data.push_back(z); - } - } - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(-radius); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(-1.0f); - data.push_back(0.0f); - } - - static size_t gen_sphere_indices(std::vector& indices, - int32_t slices, int32_t stacks) { - if (slices < 2 || stacks < 2) - return 0; - - // Top stack vertices - { - int32_t m1 = 0; - int32_t m2 = 1; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Middle stacks vertices - for (int32_t i = 1; i < stacks - 1; i++) { - int32_t m1 = (i - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(6LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(j + m2); - - indices.push_back(k + m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Bottom stack vertices - { - int32_t m1 = (stacks - 2) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(m2); - - if (++k >= slices) - k = 0; - } - } - - size_t wire_offset = indices.size(); - - // Top stack wireframe - { - int32_t m1 = 0; - int32_t m2 = 1; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(m1); - indices.push_back(j + m2); - } - } - - // Middle stacks wireframe - for (int32_t i = 1; i < stacks - 1; i++) { - int32_t m1 = (i - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(j + m2); - } - } - - // Bottom stack wireframe - { - int32_t m1 = (stacks - 2) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(m2); - } - } - - // Slices wireframe - for (int32_t i = 1; i < stacks; i++) { - int32_t m = (i - 1) * slices + 1; - - indices.reserve(2LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m); - indices.push_back(k + m); - - if (k++ >= slices) - k = 0; - } - } - - return wire_offset; - } - - static void gen_capsule_vertices(std::vector& data, - int32_t slices, int32_t stacks, float_t length, float_t radius) { - if (slices < 2 || stacks < 2) - return; - - stacks = ((stacks + 1) >> 1) << 1; - - if (length < 0.00001f) { - gen_sphere_vertices(data, slices, stacks, radius); - return; - } - - length *= 0.5f; - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(radius + length); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(1.0f); - data.push_back(0.0f); - - double_t slice_step = (M_PI * 2.0) / (double_t)slices; - double_t stack_step = M_PI / (double_t)stacks; - - for (int32_t i = 1; i <= stacks / 2; i++) { - float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); - float_t xz = cosf(stack_angle); - float_t y = sinf(stack_angle); - - data.reserve(sizeof(vec3) * 2 * slices); - - for (int32_t j = 0; j < slices; j++) { - float_t slice_angle = (float_t)((double_t)j * slice_step); - - float_t x = xz * cosf(slice_angle); - float_t z = xz * sinf(slice_angle); - - data.push_back(x * radius); - data.push_back(y + length); - data.push_back(z * radius); - - data.push_back(x); - data.push_back(y); - data.push_back(z); - } - } - - for (int32_t i = stacks / 2; i < stacks; i++) { - float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); - float_t xz = cosf(stack_angle); - float_t y = sinf(stack_angle); - - data.reserve(sizeof(vec3) * 2 * slices); - - for (int32_t j = 0; j < slices; j++) { - float_t slice_angle = (float_t)((double_t)j * slice_step); - - float_t x = xz * cosf(slice_angle); - float_t z = xz * sinf(slice_angle); - - data.push_back(x * radius); - data.push_back(y - length); - data.push_back(z * radius); - - data.push_back(x); - data.push_back(y); - data.push_back(z); - } - } - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(-radius - length); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(-1.0f); - data.push_back(0.0f); - } - - static size_t gen_capsule_indices(std::vector& indices, - int32_t slices, int32_t stacks, float_t length) { - if (slices < 2 || stacks < 2) - return 0; - - stacks = ((stacks + 1) >> 1) << 1; - - if (length < 0.00001f) - return gen_sphere_indices(indices, slices, stacks); - - // Top stack vertices - { - int32_t m1 = 0; - int32_t m2 = 1; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Middle stacks vertices - for (int32_t i = 1; i < stacks; i++) { - int32_t m1 = (i - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(6LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(j + m2); - - indices.push_back(k + m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Bottom stack vertices - { - int32_t m1 = (stacks - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(m2); - - if (++k >= slices) - k = 0; - } - } - - size_t wire_offset = indices.size(); - - // Top stack wireframe - { - int32_t m1 = 0; - int32_t m2 = 1; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(m1); - indices.push_back(j + m2); - } - } - - // Middle stacks wireframe - for (int32_t i = 1; i < stacks; i++) { - int32_t m1 = (i - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(j + m2); - } - } - - // Bottom stack wireframe - { - int32_t m1 = (stacks - 1) * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(m2); - } - } - - // Slices wireframe - for (int32_t i = 1; i <= stacks; i++) { - int32_t m = (i - 1) * slices + 1; - - indices.reserve(2LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m); - indices.push_back(k + m); - - if (k++ >= slices) - k = 0; - } - } - - return wire_offset; - } - - static void gen_ellipse_vertices(std::vector& data, - int32_t slices, int32_t stacks, float_t length, float_t radius) { - if (slices < 2 || stacks < 2) - return; - - stacks = ((stacks + 1) >> 1) << 1; - - if (length < 0.00001f) { - gen_sphere_vertices(data, slices, stacks, radius); - return; - } - - length *= 0.5f; - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(radius + length); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(1.0f); - data.push_back(0.0f); - - double_t slice_step = (M_PI * 2.0) / (double_t)slices; - double_t stack_step = M_PI / (double_t)stacks; - - for (int32_t i = 1; i < stacks; i++) { - float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); - float_t xz = cosf(stack_angle); - float_t y = sinf(stack_angle); - float_t y_n = y; - y *= radius + length; - - data.reserve(sizeof(vec3) * 2 * slices); - - for (int32_t j = 0; j < slices; j++) { - float_t slice_angle = (float_t)((double_t)j * slice_step); - - float_t x = xz * cosf(slice_angle); - float_t z = xz * sinf(slice_angle); - - data.push_back(x * radius); - data.push_back(y); - data.push_back(z * radius); - - data.push_back(x); - data.push_back(y_n); - data.push_back(z); - } - } - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(-radius - length); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(-1.0f); - data.push_back(0.0f); - } - - static size_t gen_ellipse_indices(std::vector& indices, - int32_t slices, int32_t stacks, float_t length) { - stacks = ((stacks + 1) >> 1) << 1; - - return gen_sphere_indices(indices, slices, stacks); - } - - static void gen_cylinder_vertices(std::vector& data, - int32_t slices, int32_t stacks, float_t base, float_t top, float_t height) { - float_t half_height = height * 0.5f; - - if (slices < 2 || stacks < 0) - return; - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(half_height); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(1.0f); - data.push_back(0.0f); - - double_t slice_step = (M_PI * 2.0) / (double_t)slices; - double_t stack_step = M_PI / (double_t)stacks; - - for (int32_t i = 0; i <= stacks; i++) { - float_t y = lerp_def(half_height, -half_height, (float_t)i / (float_t)stacks); - float_t radius = lerp_def(top, base, (float_t)i / (float_t)stacks); - - data.reserve(sizeof(vec3) * 2 * slices); - - for (int32_t j = 0; j < slices; j++) { - float_t slice_angle = (float_t)((double_t)j * slice_step); - - float_t x = cosf(slice_angle); - float_t z = sinf(slice_angle); - - data.push_back(x * radius); - data.push_back(y); - data.push_back(z * radius); - - data.push_back(x); - data.push_back(0.0f); - data.push_back(z); - } - } - - data.reserve(sizeof(vec3) * 2); - - data.push_back(0.0f); - data.push_back(-half_height); - data.push_back(0.0f); - - data.push_back(0.0f); - data.push_back(-1.0f); - data.push_back(0.0f); - } - - static size_t gen_cylinder_indices(std::vector& indices, - int32_t slices, int32_t stacks) { - if (slices < 2 || stacks < 0) - return 0; - - // Top cap vertices - { - int32_t m1 = 0; - int32_t m2 = 1; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Stacks vertices - for (int32_t i = 0; i < stacks; i++) { - int32_t m1 = i * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(6LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(j + m2); - - indices.push_back(k + m1); - indices.push_back(k + m2); - indices.push_back(j + m2); - - if (++k >= slices) - k = 0; - } - } - - // Bottom cap vertices - { - int32_t m1 = stacks * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(3LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(k + m1); - indices.push_back(m2); - - if (++k >= slices) - k = 0; - } - } - - size_t wire_offset = indices.size(); - - // Stacks wireframe - for (int32_t i = 0; i < stacks; i++) { - int32_t m1 = i * slices + 1; - int32_t m2 = m1 + slices; - - indices.reserve(2LL * slices); - - for (int32_t j = 0; j < slices; j++) { - indices.push_back(j + m1); - indices.push_back(j + m2); - } - } - - // Slices wireframe - for (int32_t i = 0; i <= stacks; i++) { - int32_t m = i * slices + 1; - - indices.reserve(2LL * slices); - - for (int32_t j = 0, k = 1; j < slices; j++) { - indices.push_back(j + m); - indices.push_back(k + m); - - if (k++ >= slices) - k = 0; - } - } - - return wire_offset; - } - - - void DispManager::add_vertex_array(EtcObj* etc, mat4& mat) { - EtcObjType type = etc->type; - switch (type) { - case mdl::ETC_OBJ_TEAPOT: - case mdl::ETC_OBJ_GRID: - case mdl::ETC_OBJ_CUBE: - case mdl::ETC_OBJ_SPHERE: - case mdl::ETC_OBJ_PLANE: - case mdl::ETC_OBJ_CONE: - case mdl::ETC_OBJ_LINE: - case mdl::ETC_OBJ_CROSS: - case mdl::ETC_OBJ_CAPSULE: // Added - case mdl::ETC_OBJ_ELLIPSE: // Added - case mdl::ETC_OBJ_CYLINDER: // Added - break; - default: - return; - } - - bool indexed = false; - bool wire = false; - float_t length = 0.0f; - - switch (type) { - case mdl::ETC_OBJ_TEAPOT: { - EtcObjTeapot& teapot = etc->data.teapot; - - indexed = true; - } break; - case mdl::ETC_OBJ_GRID: { - EtcObjGrid& grid = etc->data.grid; - - } break; - case mdl::ETC_OBJ_CUBE: { - EtcObjCube& cube = etc->data.cube; - - vec3 size = cube.size * 0.5f; - mat4_scale_rot(&mat, &size, &mat); - - indexed = true; - wire = cube.wire; - } break; - case mdl::ETC_OBJ_SPHERE: { - EtcObjSphere& sphere = etc->data.sphere; - - indexed = true; - wire = sphere.wire; - } break; - case mdl::ETC_OBJ_PLANE: { - EtcObjPlane& plane = etc->data.plane; - - mat4_scale_rot(&mat, (float_t)plane.w * 0.5f, 1.0f, (float_t)plane.h * 0.5f, &mat); - } break; - case mdl::ETC_OBJ_CONE: { - EtcObjCone& cone = etc->data.cone; - - indexed = true; - wire = cone.wire; - } break; - case mdl::ETC_OBJ_LINE: { - EtcObjLine& line = etc->data.line; - - } break; - case mdl::ETC_OBJ_CROSS: { - EtcObjCross& cross = etc->data.cross; - - mat4_scale_rot(&mat, cross.size, &mat); - } break; - case mdl::ETC_OBJ_CAPSULE: { // Added - EtcObjCapsule& capsule = etc->data.capsule; - - vec3 origin = (capsule.pos[0] + capsule.pos[1]) * 0.5f; - mat4_add_translate(&mat, &origin, &mat); - - vec3 dir = vec3::normalize(capsule.pos[1] - capsule.pos[0]); - vec3 up = { 0.0f, 1.0f, 0.0f }; - vec3 axis; - float_t angle; - Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir); - - mat4 m = mat4_identity; - mat4_mul_rotation(&m, &axis, angle, &m); - mat4_mul(&m, &mat, &mat); - - indexed = true; - wire = capsule.wire; - length = vec3::distance(capsule.pos[0], capsule.pos[1]); - } break; - case mdl::ETC_OBJ_ELLIPSE: { // Added - EtcObjEllipse& ellipse = etc->data.ellipse; - - vec3 origin = (ellipse.pos[0] + ellipse.pos[1]) * 0.5f; - mat4_add_translate(&mat, &origin, &mat); - - vec3 dir = vec3::normalize(ellipse.pos[1] - ellipse.pos[0]); - vec3 up = { 0.0f, 1.0f, 0.0f }; - vec3 axis; - float_t angle; - Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir); - - mat4 m = mat4_identity; - mat4_mul_rotation(&m, &axis, angle, &m); - mat4_mul(&m, &mat, &mat); - - indexed = true; - wire = ellipse.wire; - length = vec3::distance(ellipse.pos[0], ellipse.pos[1]); - } break; - case mdl::ETC_OBJ_CYLINDER: { // Added - EtcObjCylinder& cylinder = etc->data.cylinder; - - indexed = true; - wire = cylinder.wire; - } break; - } - - DispManager::etc_vertex_array* etc_vertex_array = 0; - for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { - if (i.alive_time <= 0 || i.type != type || i.vertex_buffer.IsNull()) - continue; - - if (type == mdl::ETC_OBJ_TEAPOT - || type == mdl::ETC_OBJ_GRID - && !memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid)) - || type == mdl::ETC_OBJ_CUBE - || type == mdl::ETC_OBJ_SPHERE - && i.data.sphere.slices == etc->data.sphere.slices - && i.data.sphere.stacks == etc->data.sphere.stacks - && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f - || type == mdl::ETC_OBJ_PLANE - || type == mdl::ETC_OBJ_CONE - && i.data.cone.slices == etc->data.cone.slices - && i.data.cone.stacks == etc->data.cone.stacks - && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f - && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f - || type == mdl::ETC_OBJ_LINE - || type == mdl::ETC_OBJ_CROSS - || type == mdl::ETC_OBJ_CAPSULE // Added - && i.data.capsule.slices == etc->data.capsule.slices - && ((i.data.capsule.stacks + 1)) >> 1 == ((etc->data.capsule.stacks + 1) >> 1) - && fabsf(i.data.capsule.radius - etc->data.capsule.radius) < 0.00001f - && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f - || type == mdl::ETC_OBJ_ELLIPSE // Added - && i.data.ellipse.slices == etc->data.ellipse.slices - && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) - && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f - && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f - || type == mdl::ETC_OBJ_CYLINDER // Added - && i.data.cylinder.slices == etc->data.cylinder.slices - && i.data.cylinder.stacks == etc->data.cylinder.stacks - && fabsf(i.data.cylinder.base - etc->data.cylinder.base) < 0.00001f - && fabsf(i.data.cylinder.top - etc->data.cylinder.top) < 0.00001f - && fabsf(i.data.cylinder.height - etc->data.cylinder.height) < 0.00001f) - if (i.vertex_array) { - i.alive_time = 2; - if (!wire) { - etc->count = i.count; - etc->offset = i.offset; - } - else { - etc->count = i.wire_count; - etc->offset = i.wire_offset; - } - return; - } - else { - etc_vertex_array = &i; - break; - } - } - - if (!etc_vertex_array) - for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) - if (i.alive_time <= 0) { - etc_vertex_array = &i; - break; - } - - if (!etc_vertex_array) { - etc_vertex_array_cache.push_back({}); - etc_vertex_array = &etc_vertex_array_cache.back(); - } - - if (!etc_vertex_array->vertex_array) { - glGenVertexArrays(1, &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); - glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - 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); - } - - etc_vertex_array->alive_time = 2; - etc_vertex_array->data = etc->data; - etc_vertex_array->type = type; - - std::vector vtx_data; - std::vector vtx_indices; - switch (type) { - case mdl::ETC_OBJ_TEAPOT: { - EtcObjTeapot& teapot = etc->data.teapot; - - etc_vertex_array->count = (GLsizei)vtx_indices.size(); - } break; - case mdl::ETC_OBJ_GRID: { - EtcObjGrid& grid = etc->data.grid; - - etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); - } break; - case mdl::ETC_OBJ_CUBE: { - EtcObjCube& cube = etc->data.cube; - - gen_cube_vertices(vtx_data); - size_t wire_offset = gen_cube_indices(vtx_indices); - - etc_vertex_array->offset = 0; - etc_vertex_array->count = (GLsizei)wire_offset; - etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); - etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); - } break; - case mdl::ETC_OBJ_SPHERE: { - EtcObjSphere& sphere = etc->data.sphere; - - gen_sphere_vertices(vtx_data, sphere.slices, sphere.stacks, sphere.radius); - size_t wire_offset = gen_sphere_indices(vtx_indices, sphere.slices, sphere.stacks); - - etc_vertex_array->offset = 0; - etc_vertex_array->count = (GLsizei)wire_offset; - etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); - etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); - } break; - case mdl::ETC_OBJ_PLANE: { - EtcObjPlane& plane = etc->data.plane; - - etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); - } break; - case mdl::ETC_OBJ_CONE: { - EtcObjCone& cone = etc->data.cone; - - etc_vertex_array->count = (GLsizei)vtx_indices.size(); - } break; - case mdl::ETC_OBJ_LINE: { - EtcObjLine& line = etc->data.line; - - etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); - } break; - case mdl::ETC_OBJ_CROSS: { - EtcObjCross& cross = etc->data.cross; - - etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); - } break; - case mdl::ETC_OBJ_CAPSULE: { // Added - EtcObjCapsule& capsule = etc->data.capsule; - - gen_capsule_vertices(vtx_data, capsule.slices, capsule.stacks, length, capsule.radius); - size_t wire_offset = gen_capsule_indices(vtx_indices, capsule.slices, capsule.stacks, length); - - etc_vertex_array->offset = 0; - etc_vertex_array->count = (GLsizei)wire_offset; - etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); - etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); - } break; - case mdl::ETC_OBJ_ELLIPSE: { // Added - EtcObjEllipse& ellipse = etc->data.ellipse; - - gen_ellipse_vertices(vtx_data, ellipse.slices, ellipse.stacks, length, ellipse.radius); - size_t wire_offset = gen_ellipse_indices(vtx_indices, ellipse.slices, ellipse.stacks, length); - - etc_vertex_array->offset = 0; - etc_vertex_array->count = (GLsizei)wire_offset; - etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); - etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); - } break; - case mdl::ETC_OBJ_CYLINDER: { // Added - EtcObjCylinder& cylinder = etc->data.cylinder; - - gen_cylinder_vertices(vtx_data, cylinder.slices, cylinder.stacks, - cylinder.base, cylinder.top, cylinder.height); - size_t wire_offset = gen_cylinder_indices(vtx_indices, cylinder.slices, cylinder.stacks); - - etc_vertex_array->offset = 0; - etc_vertex_array->count = (GLsizei)wire_offset; - etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); - etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); - } break; - } - - if (!wire) { - etc->count = etc_vertex_array->count; - etc->offset = etc_vertex_array->offset; - } - else { - etc->count = etc_vertex_array->wire_count; - etc->offset = etc_vertex_array->wire_offset; - } - - if (!etc_vertex_array->count) - return; - - if (etc_vertex_array->max_vtx < vtx_data.size()) { - etc_vertex_array->max_vtx = vtx_data.size(); - - etc_vertex_array->vertex_buffer.Destroy(); - } - - if (etc_vertex_array->max_idx < vtx_indices.size()) { - etc_vertex_array->max_idx = vtx_indices.size(); - - etc_vertex_array->index_buffer.Destroy(); - } - - GLsizei size_vertex = sizeof(vec3) * 2; - - gl_state_bind_vertex_array(etc_vertex_array->vertex_array); - - if (etc_vertex_array->vertex_buffer.IsNull()) - etc_vertex_array->vertex_buffer.Create(sizeof(float_t) * vtx_data.size()); - - etc_vertex_array->vertex_buffer.Bind(); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float_t) - * 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.Bind(); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint32_t) - * vtx_indices.size(), vtx_indices.data()); - } - - glEnableVertexAttribArray(POSITION_INDEX); - glVertexAttribPointer(POSITION_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)0); - - glEnableVertexAttribArray(NORMAL_INDEX); - glVertexAttribPointer(NORMAL_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)sizeof(vec3)); - - gl_state_bind_array_buffer(0); - gl_state_bind_vertex_array(0); - if (indexed) - gl_state_bind_element_array_buffer(0); - } - - ObjData* DispManager::alloc_data(ObjKind kind) { - if (!buff) - return 0; - - int32_t size = (int32_t)align_val(sizeof(ObjKind) + sizeof(mat4) + sizeof(float_t) * 2, 0x08); - switch (kind) { - case OBJ_KIND_NORMAL: - size += sizeof(ObjSubMeshArgs); - break; - case OBJ_KIND_ETC: - size += sizeof(EtcObj); - break; - case OBJ_KIND_USER: - size += sizeof(UserArgs); - break; - case OBJ_KIND_TRANSLUCENT: - size += sizeof(ObjTranslucentArgs); - break; - default: - return 0; - } - - if (buff_offset + size > buff_size) - return 0; - - ObjData* data = (ObjData*)((size_t)buff + buff_offset); - buff_offset += size; - if (buff_max < buff_offset) - buff_max = buff_offset; - return data; - } - - mat4* DispManager::alloc_data(int32_t count) { - if (!buff) - return 0; - - int32_t size = sizeof(mat4) * count; - if (buff_offset + size > buff_size) - return 0; - - mat4* mats = (mat4*)((size_t)buff + buff_offset); - buff_offset += size; - if (buff_max < buff_offset) - buff_max = buff_offset; - return mats; - } - - void DispManager::buffer_reset() { - buff_offset = 0; - } - - void DispManager::check_vertex_arrays() { - for (DispManager::vertex_array& i : vertex_array_cache) - if (i.alive_time > 0 && --i.alive_time <= 0) { - i.vertex_buffer = 0; - i.morph_vertex_buffer = 0; - } - - for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) - if (i.alive_time > 0 && --i.alive_time <= 0) { - gl_state_bind_vertex_array(i.vertex_array); - glDisableVertexAttribArray(POSITION_INDEX); - glDisableVertexAttribArray( NORMAL_INDEX); - gl_state_bind_array_buffer(0, true); - gl_state_bind_element_array_buffer(0, true); - gl_state_bind_vertex_array(0); - } - } - - void DispManager::draw(ObjType type, int32_t depth_mask, bool a4) { - if (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_value[U_REFLECT] == 1; - void(*func)(render_context * rctx, const ObjSubMeshArgs * args) = draw_sub_mesh_default; - - for (int32_t i = 0; i < 5; i++) - gl_state_active_bind_texture_2d(i, rctx_ptr->empty_texture_2d); - gl_state_active_bind_texture_cube_map(5, rctx_ptr->empty_texture_cube_map); - gl_state_active_texture(0); - gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_state_get(); - - rctx_ptr->obj_scene_ubo.Bind(0); - rctx_ptr->obj_batch_ubo.Bind(1); - rctx_ptr->obj_skinning_ubo.Bind(3); - - switch (type) { - case OBJ_TYPE_TRANSLUCENT: - case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: - case OBJ_TYPE_TRANSLUCENT_LOCAL: - if (depth_mask) - func = draw_sub_mesh_translucent; - else - gl_state_set_depth_mask(GL_FALSE); - alpha_test = 1; - min_alpha = 0.0f; - alpha_threshold = 0.0f; - break; - case OBJ_TYPE_TRANSPARENT: - case OBJ_TYPE_TRANSPARENT_LOCAL: - alpha_test = 1; - min_alpha = 0.1f; - alpha_threshold = 0.5f; - break; - case OBJ_TYPE_SHADOW_CHARA: - case OBJ_TYPE_SHADOW_STAGE: - case OBJ_TYPE_SHADOW_OBJECT_CHARA: - case OBJ_TYPE_SHADOW_OBJECT_STAGE: - func = draw_sub_mesh_shadow; - break; - case OBJ_TYPE_TYPE_6: - func = draw_sub_mesh_translucent; - gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - rctx_ptr->draw_state.shader_index = SHADER_FT_SIL; - break; - case OBJ_TYPE_TYPE_7: - func = draw_sub_mesh_translucent; - gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - rctx_ptr->draw_state.shader_index = SHADER_FT_SIL; - alpha_test = 1; - min_alpha = 0.0f; - alpha_threshold = 0.99999994f; - break; - case OBJ_TYPE_REFLECT_CHARA_OPAQUE: - gl_state_set_cull_face_mode(GL_FRONT); - if (reflect) - func = draw_sub_mesh_reflect; - else if (rctx_ptr->render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; - break; - case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: - gl_state_set_cull_face_mode(GL_FRONT); - if (reflect) - func = draw_sub_mesh_reflect; - else if (rctx_ptr->render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; - min_alpha = 0.0f; - break; - case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: - gl_state_set_cull_face_mode(GL_FRONT); - if (reflect) - func = draw_sub_mesh_reflect; - else if (rctx_ptr->render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) - func = draw_sub_mesh_reflect_reflect_map; - alpha_test = 1; - min_alpha = 0.1f; - alpha_threshold = 0.5f; - break; - case OBJ_TYPE_REFLECT_OPAQUE: - alpha_test = 1; - if (!a4) - func = draw_sub_mesh_reflect_reflect_map; - break; - case OBJ_TYPE_REFLECT_TRANSLUCENT: - case OBJ_TYPE_REFRACT_TRANSLUCENT: - gl_state_set_depth_mask(GL_FALSE); - min_alpha = 0.0f; - alpha_threshold = 0.0f; - break; - case OBJ_TYPE_REFLECT_TRANSPARENT: - case OBJ_TYPE_REFRACT_TRANSPARENT: - alpha_test = 1; - min_alpha = 0.1f; - alpha_threshold = 0.0f; - break; - case OBJ_TYPE_SSS: - func = draw_sub_mesh_sss; - break; - case OBJ_TYPE_USER: - func = draw_sub_mesh_translucent; - break; - default: - break; - } - rctx_ptr->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; - uniform_value[U_ALPHA_TEST] = alpha_test; - - for (ObjData*& i : obj[type]) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - draw_sub_mesh(rctx_ptr, &i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_ETC: { - draw_object_model_mat_load(rctx_ptr, i->mat); - draw_etc_obj(rctx_ptr, &i->args.etc); - } break; - case OBJ_KIND_USER: { - draw_object_model_mat_load(rctx_ptr, i->mat); - i->args.user.func(rctx_ptr, i->args.user.data); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (uint32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(rctx_ptr, i->args.translucent.sub_mesh[j], &i->mat, func); - } break; - } - } - - switch (type) { - case OBJ_TYPE_TRANSLUCENT: - case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: - case OBJ_TYPE_REFLECT_TRANSLUCENT: - case OBJ_TYPE_REFRACT_TRANSLUCENT: - if (!depth_mask) - gl_state_set_depth_mask(GL_TRUE); - break; - case OBJ_TYPE_TYPE_6: - case OBJ_TYPE_TYPE_7: - rctx_ptr->draw_state.shader_index = -1; - gl_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_state_set_cull_face_mode(GL_BACK); - break; - } - - uniform_value_reset(); - gl_state_bind_vertex_array(0); - shader::unbind(); - gl_state_set_blend_func(GL_ONE, GL_ZERO); - for (int32_t i = 0; i < 5; i++) - gl_state_bind_sampler(i, 0); - } - - void DispManager::draw_translucent(ObjType type, int32_t alpha) { - if (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_value[U_REFLECT] == 1; - void(*func)(render_context * rctx, const ObjSubMeshArgs * args) = draw_sub_mesh_default; - - for (int32_t i = 0; i < 5; i++) - gl_state_active_bind_texture_2d(i, rctx_ptr->empty_texture_2d); - gl_state_active_bind_texture_cube_map(5, rctx_ptr->empty_texture_cube_map); - gl_state_active_texture(0); - gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_state_get(); - - rctx_ptr->obj_scene_ubo.Bind(0); - rctx_ptr->obj_batch_ubo.Bind(1); - rctx_ptr->obj_skinning_ubo.Bind(3); - - switch (type) { - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL: - gl_state_set_depth_mask(GL_FALSE); - alpha_test = 1; - min_alpha = 0.0f; - alpha_threshold = 0.0f; - break; - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL: - alpha_test = 1; - min_alpha = 0.1f; - alpha_threshold = 0.5f; - break; - } - rctx_ptr->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; - uniform_value[U_ALPHA_TEST] = alpha_test; - - for (ObjData*& i : obj[type]) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - 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(rctx_ptr, &i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (uint32_t j = 0; j < i->args.translucent.count; j++) { - ObjSubMeshArgs* args = i->args.translucent.sub_mesh[j]; - int32_t a = (int32_t)(args->blend_color.w * 255.0f); - a = clamp_def(a, 0, 255); - if (a == alpha) - draw_sub_mesh(rctx_ptr, args, &i->mat, func); - } - } break; - } - } - - switch (type) { - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: - gl_state_set_depth_mask(GL_TRUE); - break; - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: - gl_state_set_cull_face_mode(GL_BACK); - break; - } - - uniform_value_reset(); - shader::unbind(); - gl_state_set_blend_func(GL_ONE, GL_ZERO); - } - - /*void DispManager::draw_show_vector(ObjType type, int32_t show_vector) { - if (get_obj_count(type) < 1) - return; - - for (int32_t i = 0; i < 5; i++) - gl_state_active_bind_texture_2d(i, rctx_ptr->empty_texture_2d); - gl_state_active_bind_texture_cube_map(5, rctx_ptr->empty_texture_cube_map); - gl_state_active_texture(0); - gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_state_get(); - - for (ObjData*& i : obj[type]) { - switch (i->type) { - case OBJ_KIND_NORMAL: { - draw_sub_mesh_show_vector(rctx_ptr, &i->args.sub_mesh, - &i->mat, show_vector); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (uint32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh_show_vector(rctx_ptr, i->args.translucent.sub_mesh[j], - &i->mat, show_vector); - } break; - } - } - gl_state_set_blend_func(GL_ONE, GL_ZERO); - }*/ - - void DispManager::entry_list(ObjType type, ObjData* data) { - obj[type].push_back(data); - } - - static int32_t obj_axis_aligned_bounding_box_check_visibility( - obj_axis_aligned_bounding_box* aabb, camera* cam, const mat4* mat) { - vec3 points[8]; - points[0] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, 0.0f)); - points[1] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, -0.0f)); - points[2] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, 0.0f)); - points[3] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, -0.0f)); - points[4] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, 0.0f)); - points[5] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, -0.0f)); - points[6] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, -0.0f)); - points[7] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, 0.0f)); - - mat4 view_mat; - mat4_mul(mat, &cam->view, &view_mat); - for (int32_t i = 0; i < 8; i++) - mat4_transform_point(&view_mat, &points[i], &points[i]); - - vec4 v2[6]; - *(vec3*)&v2[0] = { 0.0f, 0.0f, -1.0f }; - v2[0].w = (float_t)-cam->min_distance; - *(vec3*)&v2[1] = cam->field_1E4; - v2[1].w = 0.0f; - *(vec3*)&v2[2] = cam->field_1F0; - v2[2].w = 0.0f; - *(vec3*)&v2[3] = cam->field_1FC; - v2[3].w = 0.0f; - *(vec3*)&v2[4] = cam->field_208; - v2[4].w = 0.0f; - *(vec3*)&v2[5] = { 0.0f, 0.0f, 1.0f }; - v2[5].w = (float_t)cam->max_distance; - - for (int32_t i = 0; i < 6; i++) - for (int32_t j = 0; j < 8; j++) { - float_t v34 = vec3::dot(*(vec3*)&v2[i], points[j]) + v2[i].w; - if (v34 > 0.0f) - break; - - if (j == 7) - return 0; - } - return 1; - } - - static int32_t obj_bounding_sphere_check_visibility(obj_bounding_sphere* sphere, - CullingCheck* culling, camera* cam, const mat4* mat) { - if (culling->func) - return culling->func(sphere, &cam->view); - - vec3 center; - mat4_transform_point(mat, &sphere->center, ¢er); - mat4_transform_point(&cam->view, ¢er, ¢er); - float_t radius = mat4_get_max_scale(mat) * sphere->radius; - - double_t min_depth = (double_t)center.z - (double_t)radius; - double_t max_depth = (double_t)center.z + (double_t)radius; - if (-cam->min_distance < min_depth || -cam->max_distance > max_depth) - return 0; - - float_t v5 = vec3::dot(cam->field_1E4, center); - if (v5 < -radius) - return 0; - - float_t v6 = vec3::dot(cam->field_1F0, center); - if (v6 < -radius) - return 0; - - float_t v7 = vec3::dot(cam->field_1FC, center); - if (v7 < -radius) - return 0; - - float_t v8 = vec3::dot(cam->field_208, center); - if (v8 < -radius) - return 0; - - if (-cam->min_distance >= max_depth && -cam->max_distance <= min_depth - && v5 >= radius && v6 >= radius && v7 >= radius && v8 >= radius) - return 1; - return 2; - } - - bool DispManager::entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, - obj_mesh_index_buffer* obj_index_buf, const mat4* mat, - std::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, - obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, - mat4* instances_mat, void(*func)(const ObjSubMeshArgs*), bool enable_bone_mat, bool local) { - if (!obj_vertex_buf || !obj_index_buf) { - printf_debug("mdl::DispManager::entry_obj: no vertex or index object buffer to draw;\n"); - printf_debug(" Object: %s\n", object->name); - return false; - } - - ::camera* cam = rctx_ptr->camera; - cam->update_data(); - - if (!local && object_culling && !instances_count && !bone_mat && (!object - || !obj_bounding_sphere_check_visibility( - &object->bounding_sphere, &culling, cam, mat))) { - culling.culled.objects++; - return false; - } - culling.passed.objects++; - - for (uint32_t i = 0; i < object->num_mesh; i++) { - obj_mesh* mesh = &object->mesh_array[i]; - obj_mesh* mesh_morph = 0; - if (obj_vertex_buf && obj_morph_vertex_buf) { - if (obj_vertex_buf[i].get_size() != obj_morph_vertex_buf[i].get_size()) - continue; - - if (object_morph && i < object_morph->num_mesh) - mesh_morph = &object_morph->mesh_array[i]; - } - - if (!local && object_culling && !instances_count && !bone_mat - && !obj_bounding_sphere_check_visibility( - &mesh->bounding_sphere, &culling, cam, mat) - && (!mesh_morph || !obj_bounding_sphere_check_visibility( - &mesh_morph->bounding_sphere, &culling, cam, mat))) { - culling.culled.meshes++; - continue; - } - culling.passed.meshes++; - - ObjSubMeshArgs* translucent_priority[40]; - int32_t translucent_priority_count = 0; - - for (uint32_t j = 0; j < mesh->num_submesh; j++) { - obj_sub_mesh* sub_mesh = &mesh->submesh_array[j]; - obj_sub_mesh* sub_mesh_morph = 0; - if (sub_mesh->attrib.m.cloth) - continue; - - if (!local && object_culling && !instances_count && !bone_mat) { - int32_t v32 = obj_bounding_sphere_check_visibility( - &sub_mesh->bounding_sphere, &culling, cam, mat); - if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis)) { - if (v32 == 2) { - if (culling.func) - v32 = 1; - else - v32 = obj_axis_aligned_bounding_box_check_visibility( - &sub_mesh->axis_aligned_bounding_box, cam, mat); - } - - if (!v32) { - if (!mesh_morph || j >= mesh_morph->num_submesh) { - culling.culled.submesh_array++; - continue; - } - - sub_mesh_morph = &mesh_morph->submesh_array[j]; - if (!sub_mesh_morph) { - culling.culled.submesh_array++; - continue; - } - - v32 = obj_bounding_sphere_check_visibility( - &sub_mesh_morph->bounding_sphere, &culling, cam, mat); - if (v32 == 2) { - if (culling.func) - v32 = 1; - else - v32 = obj_axis_aligned_bounding_box_check_visibility( - &sub_mesh_morph->axis_aligned_bounding_box, cam, mat); - } - - if (!v32) { - culling.culled.submesh_array++; - continue; - } - } - } - } - culling.passed.submesh_array++; - - int32_t num_bone_index = sub_mesh->num_bone_index; - uint16_t* bone_index = sub_mesh->bone_index_array; - - mat4* mats; - if (num_bone_index && enable_bone_mat) { - mats = alloc_data(num_bone_index); - if (bone_mat) - for (int32_t k = 0; k < num_bone_index; k++, bone_index++) - mats[k] = bone_mat[*bone_index]; - else - for (int32_t k = 0; k < num_bone_index; k++) - mats[k] = mat4_identity; - } - else { - mats = 0; - num_bone_index = 0; - } - - obj_material_data* material = &object->material_array[sub_mesh->material_index]; - ObjData* data = alloc_data(OBJ_KIND_NORMAL); - if (!data) - continue; - - //GLuint morph_vertex_buffer = 0; - //if (obj_morph_vertex_buf) - // morph_vertex_buffer = obj_morph_vertex_buf[i].get_buffer(); - obj_mesh_vertex_buffer* morph_vertex_buffer - = obj_morph_vertex_buf ? &obj_morph_vertex_buf[i] : 0; - - //GLuint index_buffer = 0; - //if (obj_index_buf) - // index_buffer = obj_index_buf[i].buffer; - obj_mesh_index_buffer* index_buffer = &obj_index_buf[i]; - - //GLuint vertex_buffer = 0; - //if (obj_vertex_buf) - // vertex_buffer = obj_vertex_buf[i].get_buffer(); - obj_mesh_vertex_buffer* vertex_buffer = &obj_vertex_buf[i]; - - if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer) { - printf_debug("mdl::DispManager::entry_obj: no vertex or index mesh buffer to draw;\n"); - printf_debug(" Object: %s; Mesh: %s; Sub Mesh: %d\n", object->name, mesh->name, j); - continue; - } - - uint32_t material_hash = hash_utf8_murmurhash(material->material.name); - - material_list_struct* mat_list = 0; - for (int32_t k = 0; k < material_list_count; k++) - if (material_list_array[k].hash == material_hash) { - mat_list = &material_list_array[k]; - break; - } - - vec4 _blend_color = 1.0f; - vec4 _emission = 0.0f; - - if (mat_list) { - bool has_blend_color = false; - if (mat_list->has_blend_color.x) { - _blend_color.x = mat_list->blend_color.x; - has_blend_color = true; - } - - if (mat_list->has_blend_color.y) { - _blend_color.y = mat_list->blend_color.y; - has_blend_color = true; - } - - if (mat_list->has_blend_color.z) { - _blend_color.z = mat_list->blend_color.z; - has_blend_color = true; - } - - if (mat_list->has_blend_color.w) { - _blend_color.w = mat_list->blend_color.w; - has_blend_color = true; - } - - if (blend_color) { - if (!has_blend_color) - _blend_color = *blend_color; - else - _blend_color *= *blend_color; - } - - bool has_emission = false; - if (mat_list->has_emission.x) { - _emission.x = mat_list->emission.x; - has_emission = true; - } - - if (mat_list->has_emission.y) { - _emission.y = mat_list->emission.y; - has_emission = true; - } - - if (mat_list->has_emission.z) { - _emission.z = mat_list->emission.z; - has_emission = true; - } - - if (mat_list->has_emission.w) { - _emission.w = mat_list->emission.w; - has_emission = true; - } - - if (!has_emission) - _emission = material->material.color.emission; - } - else { - if (blend_color) - _blend_color = *blend_color; - _emission = material->material.color.emission; - } - - data->init_sub_mesh(this, mat, object->bounding_sphere.radius, sub_mesh, - mesh, material, textures, num_bone_index, mats, vertex_buffer, index_buffer, - &_blend_color, &_emission, morph_vertex_buffer, instances_count, instances_mat, func); - - if (obj_flags & mdl::OBJ_SHADOW_OBJECT) { - entry_list((ObjType)(OBJ_TYPE_SHADOW_OBJECT_CHARA - + shadow_type), data); - if (obj_flags & mdl::OBJ_USER) - entry_list(OBJ_TYPE_USER, data); - continue; - } - - obj_material_attrib_member attrib = material->material.attrib.m; - if (obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3) - && data->args.sub_mesh.blend_color.w < 1.0f) { - if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { - if (attrib.flag_28 || (attrib.punch_through - || !(attrib.alpha_texture | attrib.alpha_material)) - && !sub_mesh->attrib.m.transparent) { - if (!attrib.punch_through) { - if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) - entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, data); - else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) - entry_list(local ? OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL - : OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, data); - else - entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, data); - } - else { - if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) - entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, data); - else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) - entry_list(local ? OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL - : OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, data); - else - entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, data); - } - - if (obj_flags & mdl::OBJ_SSS) - entry_list(OBJ_TYPE_SSS, data); - } - - if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) - entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); - else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) - entry_list(local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL - : OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); - else - entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); - } - } - else { - if (attrib.flag_28 || data->args.sub_mesh.blend_color.w >= 1.0f - && (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material)) - && !sub_mesh->attrib.m.transparent) { - if (obj_flags & mdl::OBJ_SHADOW) - entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); - - if (obj_flags & mdl::OBJ_SSS) - entry_list(OBJ_TYPE_SSS, data); - - if (attrib.punch_through) { - if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) - entry_list(local ? OBJ_TYPE_TRANSPARENT_LOCAL - : OBJ_TYPE_TRANSPARENT, data); - - if (obj_flags & mdl::OBJ_CHARA_REFLECT) - entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); - - if (obj_flags & mdl::OBJ_REFLECT) - entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); - - if (obj_flags & mdl::OBJ_REFRACT) - entry_list(OBJ_TYPE_REFRACT_TRANSPARENT, data); - } - else { - if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) - entry_list(local ? OBJ_TYPE_OPAQUE_LOCAL - : OBJ_TYPE_OPAQUE, data); - - if (obj_flags & mdl::OBJ_20) - entry_list(OBJ_TYPE_TYPE_6, data); - - if (obj_flags & mdl::OBJ_CHARA_REFLECT) - entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); - - if (obj_flags & mdl::OBJ_REFLECT) - entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); - - if (obj_flags & mdl::OBJ_REFRACT) - entry_list(OBJ_TYPE_REFRACT_OPAQUE, data); - } - - if (obj_flags & mdl::OBJ_USER) - entry_list(OBJ_TYPE_USER, data); - continue; - } - else if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { - if (!attrib.translucent_priority) - if (local) - entry_list(OBJ_TYPE_TRANSLUCENT_LOCAL, data); - else if (mesh->attrib.m.translucent_no_shadow - || obj_flags & mdl::OBJ_TRANSLUCENT_NO_SHADOW) { - entry_list(OBJ_TYPE_TRANSLUCENT_NO_SHADOW, data); - } - else - entry_list(OBJ_TYPE_TRANSLUCENT, data); - else if (translucent_priority_count < 40) - translucent_priority[translucent_priority_count++] = &data->args.sub_mesh; - } - } - - if (obj_flags & mdl::OBJ_SHADOW) - entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA - + shadow_type), data); - if (obj_flags & mdl::OBJ_40) - entry_list(OBJ_TYPE_TYPE_7, data); - if (obj_flags & mdl::OBJ_CHARA_REFLECT) - entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); - if (obj_flags & mdl::OBJ_REFLECT) { - if (rctx_ptr->render_manager.reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP) - entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); - else - entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT, data); - } - if (obj_flags & mdl::OBJ_REFRACT) - entry_list(OBJ_TYPE_REFRACT_TRANSLUCENT, data); - if (obj_flags & mdl::OBJ_USER) - entry_list(OBJ_TYPE_USER, data); - } - - if (!translucent_priority_count) - continue; - - ObjTranslucentArgs translucent_args; - translucent_args.count = 0; - for (int32_t j = 62; j; j--) - for (int32_t k = 0; k < translucent_priority_count; k++) { - ObjSubMeshArgs* sub_mesh = translucent_priority[k]; - if (sub_mesh->material->material.attrib.m.translucent_priority != j) - continue; - - translucent_args.sub_mesh[translucent_args.count] = sub_mesh; - translucent_args.count++; - } - - ObjData* data = alloc_data(OBJ_KIND_TRANSLUCENT); - if (!data) - continue; - - data->init_translucent(mat, &translucent_args); - if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) - entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); - else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) - entry_list(local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL - : OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); - else if (obj_flags & mdl::OBJ_ALPHA_ORDER_3) - entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); - else - entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL - : OBJ_TYPE_TRANSLUCENT, data); - } - return true; - } - - void DispManager::entry_obj_by_obj(const mat4* mat, - ::obj* obj, std::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, - obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) { - if (!obj) - return; - - vec4 blend_color = { 1.0f, 1.0f, 1.0f, alpha }; - vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0; - - entry_obj(obj, obj_vert_buf, obj_index_buf, mat, textures, blend_color_ptr, - bone_mat, 0, 0, 0, 0, 0, !!bone_mat); - } - - bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat) { - vec4 blend_color = 1.0f; - return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true); - } - - bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, - vec4* blend_color, mat4* bone_mat, int32_t instances_count, - mat4* instances_mat, void(*func)(const ObjSubMeshArgs*), bool enable_bone_mat, bool local) { - if (obj_info.id == -1 && obj_info.set_id == -1) - return false; - - ::obj* object = object_storage_get_obj(obj_info); - if (!object) - return false; - - std::vector* textures = object_storage_get_obj_set_textures(obj_info.set_id); - obj_mesh_vertex_buffer* obj_vertex_buffer = object_storage_get_obj_mesh_vertex_buffer(obj_info); - obj_mesh_index_buffer* obj_index_buffer = object_storage_get_obj_mesh_index_buffer(obj_info); - - ::obj* obj_morph = 0; - obj_mesh_vertex_buffer* obj_morph_vertex_buffer = 0; - if (morph.object.set_id != -1) { - obj_morph = object_storage_get_obj(morph.object); - obj_morph_vertex_buffer = object_storage_get_obj_mesh_vertex_buffer(morph.object); - } - - return entry_obj(object, obj_vertex_buffer, obj_index_buffer, - mat, textures, blend_color, bone_mat, obj_morph, obj_morph_vertex_buffer, - instances_count, instances_mat, func, enable_bone_mat, local); - } - - bool DispManager::entry_obj_by_object_info(const mat4* mat, - object_info obj_info, float_t alpha, mat4* bone_mat) { - vec4 blend_color = 1.0f; - blend_color.w = alpha; - return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true); - } - - bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, - float_t r, float_t g, float_t b, float_t a, mat4* bone_mat, bool local) { - vec4 blend_color = { r, g, b, a }; - return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, true, local); - } - - bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, - vec4* blend_color, mat4* bone_mat, bool local) { - return entry_obj_by_object_info(mat, obj_info, blend_color, 0, 0, 0, 0, false, local); - } - - void DispManager::entry_obj_by_object_info_object_skin(object_info obj_info, - std::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, - mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat) { - obj_skin* skin = object_storage_get_obj_skin(obj_info); - if (!skin) - return; - - obj_skin_set_matrix_buffer(skin, matrices, ex_data_matrices, rctx_ptr->matrix_buffer, mat, global_mat); - - vec4 texture_color_coefficients; - vec4 texture_color_offset; - vec4 texture_specular_coefficients; - vec4 texture_specular_offset; - if (texture_data && !texture_data->field_0) { - vec4 value; - get_texture_color_coeff(texture_color_coefficients); - *(vec3*)&value = texture_data->texture_color_coefficients * *(vec3*)&texture_color_coefficients; - value.w = 0.0f; - set_texture_color_coefficients(value); - - get_texture_color_offset(texture_color_offset); - *(vec3*)&value = texture_data->texture_color_offset; - value.w = 0.0f; - set_texture_color_offset(value); - - get_texture_specular_coeff(texture_specular_coefficients); - *(vec3*)&value = texture_data->texture_specular_coefficients * *(vec3*)&texture_specular_coefficients; - value.w = 0.0f; - set_texture_specular_coefficients(value); - - get_texture_specular_offset(texture_specular_offset); - *(vec3*)&value = texture_data->texture_specular_offset; - value.w = 0.0f; - set_texture_specular_offset(value); - } - - size_t texture_pattern_count = texture_pattern ? texture_pattern->size() : 0; - if (texture_pattern && texture_pattern_count) - set_texture_pattern((int32_t)texture_pattern_count, texture_pattern->data()); - - if (fabsf(alpha - 1.0f) > 0.000001f) - entry_obj_by_object_info(global_mat, obj_info, alpha, rctx_ptr->matrix_buffer); - else - entry_obj_by_object_info(global_mat, obj_info, rctx_ptr->matrix_buffer); - - if (texture_pattern && texture_pattern_count) - set_texture_pattern(); - - if (texture_data && !texture_data->field_0) { - set_texture_color_coefficients(texture_color_coefficients); - set_texture_color_offset(texture_color_offset); - set_texture_specular_coefficients(texture_specular_coefficients); - set_texture_specular_offset(texture_specular_offset); - } - } - - void DispManager::entry_obj_etc(const mat4* mat, EtcObj* etc, bool local) { - ObjData* data = alloc_data(mdl::OBJ_KIND_ETC); - if (!data) - return; - - data->init_etc(this, mat, etc); - if (etc->color.a == 0xFF) { - if (!local && (obj_flags & OBJ_SHADOW)) - mdl::DispManager::entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); - mdl::DispManager::entry_list(local ? OBJ_TYPE_OPAQUE_LOCAL : OBJ_TYPE_OPAQUE, data); - } - else - mdl::DispManager::entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL : OBJ_TYPE_TRANSLUCENT, data); - } - - void DispManager::entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type) { - ObjData* _data = alloc_data(OBJ_KIND_USER); - if (_data) { - _data->init_user(mat, func, data); - entry_list(type, _data); - } - } - - GLuint DispManager::get_vertex_array(const ObjSubMeshArgs* args) { - const obj_mesh* mesh = args->mesh; - const obj_sub_mesh* sub_mesh = args->sub_mesh; - const obj_material_data* material = args->material; - - //GLuint vertex_buffer = args->vertex_buffer; - obj_mesh_vertex_buffer* vertex_buffer = args->vertex_buffer; - //GLuint morph_vertex_buffer = args->morph_vertex_buffer; - obj_mesh_vertex_buffer* morph_vertex_buffer = args->morph_vertex_buffer; - //GLuint index_buffer = args->index_buffer; - obj_mesh_index_buffer* index_buffer = args->index_buffer; - - int32_t texcoord_array[2] = { -1, -1 }; - int32_t color_tex_index = 0; - for (const obj_material_texture_data& i : material->material.texdata) { - if (i.tex_index == -1) - continue; - - int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( - i.shader_info.m.tex_type, color_tex_index); - if (texcoord_index < 0) - continue; - - texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; - - if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) - color_tex_index++; - } - - GLuint vertex_attrib_buffer_binding[16] = {}; - object_data_get_vertex_attrib_buffer_bindings(args, - texcoord_array, vertex_attrib_buffer_binding); - - bool compressed = mesh->attrib.m.compressed; - GLsizei size_vertex = (GLsizei)mesh->size_vertex; - obj_vertex_format vertex_format = mesh->vertex_format; - - for (DispManager::vertex_array& i : vertex_array_cache) - if (i.alive_time > 0 && i.vertex_buffer == vertex_buffer - && i.morph_vertex_buffer == morph_vertex_buffer - && i.index_buffer == index_buffer && i.vertex_format == vertex_format - && i.size_vertex == size_vertex && i.compressed == compressed - && !memcmp(i.vertex_attrib_buffer_binding, - vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) - && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) - return i.vertex_array; - return 0; - } - - GLuint DispManager::get_vertex_array(const EtcObj* etc) { - EtcObjType type = etc->type; - float_t length = 0; - switch (type) { - case mdl::ETC_OBJ_TEAPOT: - case mdl::ETC_OBJ_GRID: - case mdl::ETC_OBJ_CUBE: - case mdl::ETC_OBJ_SPHERE: - case mdl::ETC_OBJ_PLANE: - case mdl::ETC_OBJ_CONE: - case mdl::ETC_OBJ_LINE: - case mdl::ETC_OBJ_CROSS: - break; - case mdl::ETC_OBJ_CAPSULE: // Added - length = vec3::distance(etc->data.capsule.pos[0], etc->data.capsule.pos[1]); - break; - case mdl::ETC_OBJ_ELLIPSE: // Added - length = vec3::distance(etc->data.ellipse.pos[0], etc->data.ellipse.pos[1]); - break; - case mdl::ETC_OBJ_CYLINDER: // Added - break; - default: - return 0; - } - - for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { - if (i.alive_time <= 0 || i.type != type) - continue; - - switch (type) { - case mdl::ETC_OBJ_TEAPOT: - return i.vertex_array; - case mdl::ETC_OBJ_GRID: - if (!memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid))) - return i.vertex_array; - break; - case mdl::ETC_OBJ_CUBE: - return i.vertex_array; - case mdl::ETC_OBJ_SPHERE: - if (i.data.sphere.slices == etc->data.sphere.slices - && i.data.sphere.stacks == etc->data.sphere.stacks - && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f) - return i.vertex_array; - break; - case mdl::ETC_OBJ_PLANE: - return i.vertex_array; - case mdl::ETC_OBJ_CONE: - if (i.data.cone.slices == etc->data.cone.slices - && i.data.cone.stacks == etc->data.cone.stacks - && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f - && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f) - return i.vertex_array; - break; - case mdl::ETC_OBJ_LINE: - return i.vertex_array; - case mdl::ETC_OBJ_CROSS: - return i.vertex_array; - case mdl::ETC_OBJ_CAPSULE: // Added - if (i.data.capsule.slices == etc->data.capsule.slices - && ((i.data.capsule.stacks + 1)) >> 1 == ((etc->data.capsule.stacks + 1) >> 1) - && fabsf(i.data.capsule.radius - etc->data.capsule.radius) < 0.00001f - && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f) - return i.vertex_array; - break; - case mdl::ETC_OBJ_ELLIPSE: // Added - if (i.data.ellipse.slices == etc->data.ellipse.slices - && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) - && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f - && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f) - return i.vertex_array; - break; - case mdl::ETC_OBJ_CYLINDER: // Added - if (i.data.cylinder.slices == etc->data.cylinder.slices - && i.data.cylinder.stacks == etc->data.cylinder.stacks - && fabsf(i.data.cylinder.base - etc->data.cylinder.base) < 0.00001f - && fabsf(i.data.cylinder.top - etc->data.cylinder.top) < 0.00001f - && fabsf(i.data.cylinder.height - etc->data.cylinder.height) < 0.00001f) - return i.vertex_array; - break; - } - } - return 0; - } - - bool DispManager::get_chara_color() { - return chara_color; - } - - ObjFlags DispManager::get_obj_flags() { - return obj_flags; - } - - void DispManager::get_material_list(int32_t& count, material_list_struct*& value) { - count = material_list_count; - - for (int32_t i = 0; i < count; i++) - value[i] = material_list_array[i]; - } - - void DispManager::get_morph(object_info& object, float_t& weight) { - weight = morph.weight; - object = morph.object; - } - - int32_t DispManager::get_obj_count(ObjType type) { - return (int32_t)obj[type].size(); - } - - shadow_type_enum DispManager::get_shadow_type() { - return shadow_type; - } - - void DispManager::get_texture_color_coeff(vec4& value) { - value = texture_color_coefficients; - } - - void DispManager::get_texture_color_offset(vec4& value) { - value = texture_color_offset; - } - - void DispManager::get_texture_pattern(int32_t& count, texture_pattern_struct*& value) { - count = texture_pattern_count; - - for (int32_t i = 0; i < count; i++) - value[i] = texture_pattern_array[i]; - } - - void DispManager::get_texture_specular_coeff(vec4& value) { - value = texture_specular_coefficients; - } - - void DispManager::get_texture_specular_offset(vec4& value) { - value = texture_specular_offset; - } - - void DispManager::get_texture_transform(int32_t& count, texture_transform_struct*& value) { - count = texture_transform_count; - - for (int32_t i = 0; i < count; i++) - value[i] = texture_transform_array[i]; - } - - float_t DispManager::get_wet_param() { - return wet_param; - } - - static int mdl_obj_data_sort_quicksort_compare0(void const* src1, void const* src2) { - float_t d1 = (*(ObjData**)src1)->view_z; - float_t d2 = (*(ObjData**)src2)->view_z; - return d1 > d2 ? -1 : (d1 < d2 ? 1 : 0); - } - - static int mdl_obj_data_sort_quicksort_compare1(void const* src1, void const* src2) { - float_t d1 = (*(ObjData**)src1)->view_z; - float_t d2 = (*(ObjData**)src2)->view_z; - return d1 < d2 ? -1 : (d1 > d2 ? 1 : 0); - } - - static int mdl_obj_data_sort_quicksort_compare2(void const* src1, void const* src2) { - float_t r1 = (*(ObjData**)src1)->radius; - float_t r2 = (*(ObjData**)src2)->radius; - return r1 > r2 ? -1 : (r1 < r2 ? 1 : 0); - } - - void DispManager::obj_sort(mat4* view, ObjType type, int32_t compare_func) { - std::vector& vec = obj[type]; - if (vec.size() < 1) - return; - - for (ObjData*& i : vec) { - vec3 center; - mat4_get_translation(&i->mat, ¢er); - if (i->kind == OBJ_KIND_NORMAL) { - mat4 mat = i->mat; - if (i->args.sub_mesh.mesh->attrib.m.billboard) - model_mat_face_camera_view(view, &mat, &mat); - else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) - model_mat_face_camera_position(view, &mat, &mat); - - const obj_sub_mesh* sub_mesh = i->args.sub_mesh.sub_mesh; - if (i->args.sub_mesh.mat_count < 1 || !sub_mesh->num_bone_index) - mat4_transform_point(&mat, &sub_mesh->bounding_sphere.center, ¢er); - else { - vec3 center_sum = 0.0f; - for (uint32_t j = 0; j < sub_mesh->num_bone_index; j++) { - center = sub_mesh->bounding_sphere.center; - mat4_transform_point(&i->args.sub_mesh.mats[j], ¢er, ¢er); - center_sum += center; - } - center_sum *= 1.0f / (float_t)sub_mesh->num_bone_index; - } - i->radius = i->args.sub_mesh.mesh->bounding_sphere.radius; - } - - mat4_transform_point(view, ¢er, ¢er); - i->view_z = center.z; - } - - switch (compare_func) { - case 0: - quicksort_custom(vec.data(), vec.size(), - sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare0); - break; - case 1: - quicksort_custom(vec.data(), vec.size(), - sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare1); - break; - case 2: - quicksort_custom(vec.data(), vec.size(), - sizeof(ObjData*), mdl_obj_data_sort_quicksort_compare2); - break; - } - } - - void DispManager::refresh() { - culling.passed_prev = culling.passed; - culling.culled_prev = culling.culled; - culling.passed = {}; - culling.culled = {}; - - obj_flags = (::mdl::ObjFlags)0; - field_8 = 0; - field_C = 0; - - texture_pattern_count = 0; - memset(texture_pattern_array, 0, sizeof(texture_pattern_array)); - texture_transform_count = 0; - memset(texture_transform_array, 0, sizeof(texture_transform_array)); - texture_color_coefficients = 1.0f; - texture_color_offset = 0.0f; - texture_specular_coefficients = 1.0f; - texture_specular_offset = 0.0f; - - for (std::vector& i : obj) - i.clear(); - - buffer_reset(); - } - - void DispManager::set_chara_color(bool value) { - chara_color = value; - } - - void DispManager::set_obj_flags(ObjFlags flags) { - obj_flags = flags; - } - - void DispManager::set_material_list(int32_t count, material_list_struct* value) { - if (count > MATERIAL_LIST_COUNT) - return; - - material_list_count = count; - - if (count) - for (int32_t i = 0; i < count; i++) - material_list_array[i] = value[i]; - else - for (int32_t i = 0; i < MATERIAL_LIST_COUNT; i++) - material_list_array[i] = {}; - } - - void DispManager::set_morph(object_info object, float_t weight) { - morph.weight = weight; - morph.object = object; - } - - void DispManager::set_culling_finc(bool(*func)(obj_bounding_sphere*, mat4*)) { - culling.func = func; - } - - void DispManager::set_shadow_type(shadow_type_enum type) { - if (type == SHADOW_CHARA || type == SHADOW_STAGE) - shadow_type = type; - } - - void DispManager::set_texture_color_coefficients(vec4& value) { - texture_color_coefficients = value; - } - - void DispManager::set_texture_color_offset(vec4& value) { - texture_color_offset = value; - } - - void DispManager::set_texture_pattern(int32_t count, texture_pattern_struct* value) { - if (count > TEXTURE_PATTERN_COUNT) - return; - - texture_pattern_count = count; - - if (count) - for (int32_t i = 0; i < count; i++) - texture_pattern_array[i] = value[i]; - else - for (int32_t i = 0; i < TEXTURE_PATTERN_COUNT; i++) - texture_pattern_array[i] = {}; - } - - void DispManager::set_texture_specular_coefficients(vec4& value) { - texture_specular_coefficients = value; - } - - void DispManager::set_texture_specular_offset(vec4& value) { - texture_specular_offset = value; - } - - void DispManager::set_texture_transform(int32_t count, texture_transform_struct* value) { - if (count > TEXTURE_TRANSFORM_COUNT) - return; - - texture_transform_count = count; - - if (count) - for (int32_t i = 0; i < count; i++) - texture_transform_array[i] = value[i]; - else - for (int32_t i = count; i < TEXTURE_TRANSFORM_COUNT; i++) - texture_transform_array[i] = {}; - } - - void DispManager::set_wet_param(float_t value) { - wet_param = value; - } -} - -namespace rndr { - RenderManager::RenderManager() : pass_sw(), reflect_blur_num(), reflect_blur_filter(), sync_gpu(), - cpu_time(), gpu_time(), time(), draw_pass_3d(), show_ref_map(), reflect_type(), clear(), - tex_index(), multisample_framebuffer(), multisample_renderbuffer(), multisample(), - show_vector_flags(), show_vector_length(), show_vector_z_offset(), field_2F8(), effect_texture(), - npr_param(), field_31C(), field_31D(), field_31E(), field_31F(), field_320(), npr() { - for (bool& i : pass_sw) - i = true; - - set_pass_sw(RND_PASSID_2, false); - set_pass_sw(RND_PASSID_REFLECT, false); - set_pass_sw(RND_PASSID_REFRACT, false); - set_pass_sw(RND_PASSID_PRE_PROCESS, false); - set_pass_sw(RND_PASSID_SHOW_VECTOR, false); - - shadow = true; - opaque_z_sort = true; - alpha_z_sort = true; - - for (bool& i : draw_pass_3d) - i = true; - - shadow_ptr = new Shadow; - if (shadow_ptr) - shadow_ptr->InitData(); - - for (int32_t i = 0; i < 9; i++) { - const struc_189* v2 = &stru_140A24420[i]; - if (v2->type != GL_TEXTURE_2D) - continue; - - RenderTexture& rt = render_textures[i]; - rt.Init(v2->width, v2->height, v2->max_level, v2->color_format, v2->depth_format); - rt.Bind(); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - gl_state_bind_framebuffer(0); - - } - - RenderManager::~RenderManager() { - if (multisample_framebuffer) { - glDeleteFramebuffers(1, &multisample_framebuffer); - multisample_framebuffer = 0; - } - - if (multisample_renderbuffer) { - glDeleteRenderbuffers(1, &multisample_renderbuffer); - multisample_renderbuffer = 0; - } - - delete shadow_ptr; - } - - void RenderManager::add_pre_process(int32_t type, void(*func)(void*), void* data) { - pre_process.push_back({ type, func, data }); - } - - void RenderManager::clear_pre_process(int32_t type) { - for (std::list::iterator i = pre_process.begin(); i != pre_process.end(); i++) - if (i->type == type) { - pre_process.erase(i); - break; - } - } - - RenderTexture& RenderManager::get_render_texture(int32_t index) { - return render_textures[stru_140A244E0[index][tex_index[index]]]; - } - - void RenderManager::resize(int32_t width, int32_t height) { - if (!multisample_framebuffer) - glGenFramebuffers(1, &multisample_framebuffer); - - if (!multisample_renderbuffer) - glGenRenderbuffers(1, &multisample_renderbuffer); - - glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); - glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisample_renderbuffer); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - } - - void RenderManager::set_effect_texture(texture* value) { - effect_texture = value; - } - - void RenderManager::set_multisample(bool value) { - multisample = value; - } - - void RenderManager::set_npr_param(int32_t value) { - npr_param = value; - } - - void RenderManager::set_pass_sw(RenderPassID id, bool value) { - pass_sw[id] = value; - } - - void RenderManager::set_reflect(bool value) { - reflect = value; - } - - void RenderManager::set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter) { - this->reflect_blur_num = reflect_blur_num; - this->reflect_blur_filter = reflect_blur_filter; - } - - void RenderManager::set_reflect_resolution_mode(reflect_refract_resolution_mode mode) { - tex_index[0] = mode; - } - - void RenderManager::set_reflect_type(stage_data_reflect_type type) { - reflect_type = type; - } - - void RenderManager::set_refract(bool value) { - refract = value; - } - - void RenderManager::set_refract_resolution_mode(reflect_refract_resolution_mode mode) { - tex_index[1] = mode; - } - - void RenderManager::set_shadow_false() { - shadow = false; - } - - void RenderManager::set_shadow_true() { - shadow = true; - } -} - -extern float_t rob_frame; -extern render_context* rctx_ptr; - void obj_scene_shader_data::set_g_irradiance_r_transforms(const mat4& mat) { mat4 temp; mat4_transpose(&mat, &temp); @@ -3619,9 +317,14 @@ void obj_batch_shader_data::set_transforms(const mat4& model, const mat4& view, g_transforms[3] = temp.row3; } -render_context::render_context() : litproj(), chara_reflect(), chara_refract(), view_mat(), matrix_buffer(), -box_vao(), box_vbo(), empty_texture_2d(), empty_texture_cube_map(), samplers(), sprite_samplers() { +render_context::render_context() : litproj(), chara_reflect(), chara_refract(), box_vao(), lens_ghost_vao(), +common_vao(), empty_texture_2d(), empty_texture_cube_map(), samplers(), render_samplers(), sprite_samplers(), +sprite_width(), sprite_height(), screen_x_offset(), screen_y_offset(), screen_width(), screen_height() { camera = new ::camera; + draw_state = new ::draw_state; + disp_manager = new mdl::DispManager; + render_manager = new rndr::RenderManager; + sss_data = new ::sss_data; static const float_t box_texcoords[] = { 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, @@ -3661,12 +364,8 @@ box_vao(), box_vbo(), empty_texture_2d(), empty_texture_cube_map(), samplers(), glGenVertexArrays(1, &box_vao); gl_state_bind_vertex_array(box_vao); - glGenBuffers(1, &box_vbo); - gl_state_bind_array_buffer(box_vbo, true); - if (GLAD_GL_VERSION_4_4) - glBufferStorage(GL_ARRAY_BUFFER, sizeof(box_texcoords), box_texcoords, 0); - else - glBufferData(GL_ARRAY_BUFFER, sizeof(box_texcoords), box_texcoords, GL_STATIC_DRAW); + box_vbo.Create(sizeof(box_texcoords), box_texcoords); + box_vbo.Bind(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)0); @@ -3676,18 +375,36 @@ box_vao(), box_vbo(), empty_texture_2d(), empty_texture_cube_map(), samplers(), glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 8)); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 12)); + + glGenVertexArrays(1, &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(); + + 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_state_bind_array_buffer(0); gl_state_bind_vertex_array(0); + glGenVertexArrays(1, &common_vao); + 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)); obj_scene = {}; @@ -3764,6 +481,26 @@ box_vao(), box_vbo(), empty_texture_2d(), empty_texture_cube_map(), samplers(), } GLuint sampler; + glGenSamplers(3, render_samplers); + sampler = render_samplers[0]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + sampler = render_samplers[1]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + sampler = render_samplers[2]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glGenSamplers(3, sprite_samplers); sampler = sprite_samplers[0]; glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); @@ -3790,6 +527,7 @@ box_vao(), box_vbo(), empty_texture_2d(), empty_texture_cube_map(), samplers(), render_context::~render_context() { glDeleteSamplers(3, sprite_samplers); + glDeleteSamplers(3, render_samplers); glDeleteSamplers(18, samplers); glDeleteTextures(1, &empty_texture_cube_map); @@ -3799,19 +537,60 @@ render_context::~render_context() { obj_batch_ubo.Destroy(); obj_scene_ubo.Destroy(); + tone_map_ubo.Destroy(); transparency_batch_ubo.Destroy(); + sun_quad_ubo.Destroy(); sss_filter_gaussian_coef_ubo.Destroy(); sprite_scene_ubo.Destroy(); quad_ubo.Destroy(); + glitter_batch_ubo.Destroy(); glass_eye_batch_ubo.Destroy(); + gaussian_coef_ubo.Destroy(); + exposure_measure_ubo.Destroy(); imgfilter_batch_ubo.Destroy(); esm_filter_batch_ubo.Destroy(); filter_scene_ubo.Destroy(); contour_params_ubo.Destroy(); contour_coef_ubo.Destroy(); - glDeleteBuffers(1, &box_vbo); - glDeleteVertexArrays(1, &box_vao); + if (common_vao) { + glDeleteVertexArrays(1, &common_vao); + common_vao = 0; + } + + if (lens_ghost_vao) { + glDeleteVertexArrays(1, &lens_ghost_vao); + lens_ghost_vao = 0; + } + + lens_ghost_vbo.Destroy(); + + if (box_vao) { + glDeleteVertexArrays(1, &box_vao); + box_vao = 0; + } + + box_vbo.Destroy(); + + if (sss_data) { + delete sss_data; + sss_data = 0; + } + + if (render_manager) { + delete render_manager; + render_manager = 0; + } + + if (disp_manager) { + delete disp_manager; + disp_manager = 0; + } + + if (draw_state) { + delete draw_state; + draw_state = 0; + } if (camera) { delete camera; @@ -3837,26 +616,50 @@ void render_context::ctrl() { void render_context::disp() { rctx_ptr = this; - disp_manager.refresh(); + disp_manager->refresh(); sprite_manager_reset_req_list(); - draw_state.stats_prev = draw_state.stats; - draw_state.stats.reset(); + draw_state->stats_prev = draw_state->stats; + draw_state->stats.reset(); app::TaskWork::Disp(); - render_manager.shadow_ptr->Ctrl(this); + shadow_ptr_get()->Ctrl(); int32_t sprite_index = sprite_manager_get_index(); //sprite_manager_set_index(3); sprite_manager_set_index(0); extern void dw_gui_ctrl_disp(); dw_gui_ctrl_disp(); sprite_manager_set_index(sprite_index); - post_process.ctrl(camera); - render_manager.render_all(this); - post_process.lens_flare_texture = 0; - post_process.aet_back = 0; - render_manager.field_31C = false; + render.ctrl(camera); + render_manager->render_all(); + render.lens_flare_texture = 0; + render.aet_back = 0; + render_manager->field_31C = false; app::TaskWork::Basic(); } +void render_context::free() { + shadow_buffer.Free(); + screen_buffer.Free(); + render_buffer.Free(); + reflect_buffer.Free(); +} + +void render_context::init() { + auto init_copy_buffer = [&](RenderTexture& src, RenderTexture& dst) { + dst.Init(src.GetWidth(), + src.GetHeight(), 0, src.color_texture->internal_format, + src.depth_texture ? src.depth_texture->internal_format : GL_ZERO); + }; + + RenderTexture& render_buffer = render.rend_texture[0]; + RenderTexture& reflect_buffer = render_manager->get_render_texture(1); + RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1]; + init_copy_buffer(reflect_buffer, this->reflect_buffer); + init_copy_buffer(render_buffer, this->render_buffer); + init_copy_buffer(shadow_buffer, this->shadow_buffer); + + screen_buffer.Init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F +} + void render_context::light_param_data_light_set(light_param_light * light) { for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) { light_param_light_group* group = &light->group[i]; @@ -3923,50 +726,47 @@ void render_context::light_param_data_fog_set(light_param_fog* f) { } void render_context::light_param_data_glow_set(light_param_glow* glow) { - post_process_blur* blur = post_process.blur; - post_process_tone_map* tone_map = post_process.tone_map; - - tone_map->set_auto_exposure(true); - tone_map->set_tone_map_method(TONE_MAP_YCC_EXPONENT); - tone_map->reset_saturate_coeff(0, false); - tone_map->reset_scene_fade(0); - tone_map->reset_tone_trans(0); + render.set_auto_exposure(true); + render.set_tone_map(TONE_MAP_YCC_EXPONENT); + render.reset_saturate_coeff(0, false); + render.reset_scene_fade(0); + render.reset_tone_trans(0); if (glow->has_exposure) - tone_map->set_exposure(glow->exposure); + render.set_exposure(glow->exposure); if (glow->has_gamma) - tone_map->set_gamma(glow->gamma); + render.set_gamma(glow->gamma); if (glow->has_saturate_power) - tone_map->set_saturate_power(glow->saturate_power); + render.set_saturate_power(glow->saturate_power); if (glow->has_saturate_coef) - tone_map->set_saturate_coeff(glow->saturate_coef, 0, false); + render.set_saturate_coeff(glow->saturate_coef, 0, false); if (glow->has_flare) - tone_map->set_lens(glow->flare); + render.set_lens(glow->flare); if (glow->has_sigma) - blur->set_radius(glow->sigma); + render.set_radius(glow->sigma); if (glow->has_intensity) - blur->set_intensity(glow->intensity); + render.set_intensity(glow->intensity); if (glow->has_auto_exposure) - tone_map->set_auto_exposure(glow->auto_exposure); + render.set_auto_exposure(glow->auto_exposure); if (glow->has_tone_map_method) - tone_map->set_tone_map_method(glow->tone_map_method); + render.set_tone_map(glow->tone_map_method); if (glow->has_fade_color) { vec4 fade_color = glow->fade_color; - tone_map->set_scene_fade(fade_color, 0); - tone_map->set_scene_fade_blend_func(glow->fade_color_blend_func, 0); + render.set_scene_fade(fade_color, 0); + render.set_scene_fade_blend_func(glow->fade_color_blend_func, 0); } if (glow->has_tone_transform) - tone_map->set_tone_trans(glow->tone_transform_start, glow->tone_transform_end, 0); + render.set_tone_trans(glow->tone_transform_start, glow->tone_transform_end, 0); } void render_context::light_param_data_ibl_set( @@ -4052,397 +852,39 @@ void render_context::light_param_data_face_set(light_param_face* face) { this->face.set_direction(face->direction); } -Shadow::Shadow() : curr_render_textures(), view_region(), range(), field_1C0(), field_1C8(), -field_200(), field_208(), near_blur(), blur_filter(), far_blur(), field_2BC(), distance(), -field_2C4(), z_near(), z_far(), field_2D0(), field_2D4(), field_2D8(), field_2DC(), field_2E0(), -ambient(), field_2E8(), field_2EC(), field_2F0(), self_shadow(), blur_filter_enable(), field_2F5() { - ResetData(); -} +void render_context::resize(int32_t render_width, int32_t render_height, + int32_t sprite_width, int32_t sprite_height, + int32_t screen_width, int32_t screen_height) { + bool render_res_change = render.inner_width != render_width || render.inner_height != render_height; + bool sprite_res_change = this->sprite_width != sprite_width || this->sprite_height != sprite_height; + bool screen_res_change = this->screen_width != screen_width || this->screen_height != screen_height; + if (!render_res_change && !sprite_res_change && !screen_res_change) + return; -Shadow::~Shadow() { - Reset(); -} + this->sprite_width = sprite_width; + this->sprite_height = sprite_height; -void Shadow::Ctrl(render_context* rctx) { - for (int32_t i = 0; i < 2; i++) - field_2F0[i] = false; + screen_x_offset = (screen_width - sprite_width) / 2 + (screen_width - sprite_width) % 2; + screen_y_offset = (screen_height - sprite_height) / 2 + (screen_height - sprite_height) % 2; - if (rctx->render_manager.shadow) { - view_mat[0] = rctx->camera->view; - view_mat[1] = rctx->camera->inv_view; + this->screen_width = screen_width; + this->screen_height = screen_height; - ::light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; - light_data* data = &set->lights[LIGHT_CHARA]; + if (render_res_change) + render.resize(render_width, render_height); - vec3 position; - data->get_position(position); - float_t length = vec3::length(position); - if (length < 0.000001f) - direction = { 0.0f, 1.0f, 0.0f }; - else - direction = -position * (1.0f / length); + if (sprite_res_change) + render_manager->resize(sprite_width, sprite_height); - for (int32_t i = 0; i < 2; i++) - if (rctx->disp_manager.get_obj_count((mdl::ObjType)((int32_t)mdl::OBJ_TYPE_SHADOW_CHARA + i))) - field_2F0[i] = true; - } + if (render_res_change) + litproj->resize(render_width, render_height); - int32_t count = 0; - field_2EC = 0; - for (int32_t i = 0; i < 2; i++) - if (field_2F0[i] && field_1D0[i].size() > 0) { - field_2EC++; - count += (int32_t)field_1D0[i].size(); - } - else - field_2F0[i] = false; + sprite_manager_set_res((double_t)sprite_width / (double_t)sprite_height, + sprite_width, sprite_height); - if (count < 3) { - for (int32_t i = 0; i < 2; i++) { - field_1A8[i] = 0.0f; - field_1C8[i] = 0.0f; - if (!field_2F0[i] || field_1D0[i].size() < 1) - continue; - - vec3 v7 = 0.0f; - for (vec3& j : field_1D0[i]) - v7 += j; - - float_t v14 = (float_t)(int64_t)field_1D0[i].size(); - if (v14 < 0.0f) - v14 += (float_t)UINT64_MAX; - v7 *= 1.0f / v14; - - float_t v15 = 0.0f; - for (vec3& j : field_1D0[i]) { - vec3 v22 = v7 - j; - vec3 v25 = direction * vec3::dot(v22, direction); - float_t v24 = vec3::distance(v25, v22); - v24 -= 0.25f; - if (v24 < 0.0f) - v24 = 0.0f; - if (v15 < v24) - v15 = v24; - } - field_1A8[i] = v7; - field_1C8[i] = v15; - } - - if (field_2EC > 0) { - vec3 view_point = 0.0f; - vec3 interest = 0.0f; - for (int32_t i = 0; i < 2; i++) { - if (!field_2F0[i]) - continue; - - vec3 v11 = field_1A8[i] - direction * field_208; - float_t v9 = vec3::distance(this->view_point[i], v11); - float_t v12 = vec3::distance(this->interest[i], field_1A8[i]); - if (v9 > 0.1f || v12 > 0.1f) { - this->view_point[i] = v11; - this->interest[i] = field_1A8[i]; - } - - view_point += this->view_point[i]; - interest += this->interest[i]; - } - - view_point_shared = view_point * (1.0f / (float_t)field_2EC); - interest_shared = interest * (1.0f / (float_t)field_2EC); - } - - float_t v2 = max_def(field_1C8[0], field_1C8[1]); - field_2F5 = false; - view_region = v2 + 1.2f; - field_200[0] = 0; - field_200[1] = 1; - if (field_2EC >= 2) { - vec3 v12 = field_1A8[0] - interest_shared; - vec3 v14 = field_1A8[1] - interest_shared; - - float_t v6 = vec3::length(direction * vec3::dot(v12, direction) - v12); - - float_t v16 = v6 - 0.25f; - if (v16 < 0.0f) - v16 = 0.0f; - - if (v16 > 1.2f) { - view_region = v2 + 2.4f; - field_2F5 = true; - } - else - view_region = v2 + 1.2f + v16; - - if (vec3::dot(v12, direction) < vec3::dot(v14, direction)) { - field_200[1] = 0; - field_200[0] = 1; - } - } - } - else { - vec3 v3; - vec3 v86; - if (direction.y * direction.y < 0.99f) { - v86 = vec3::cross(direction, vec3(0.0f, 1.0f, 0.0f)); - v3 = vec3::normalize(vec3::cross(v86, direction)); - v86 = vec3::normalize(v86); - } - else { - v3 = { 0.0f, 0.0f, 1.0f }; - v86 = { 1.0f, 0.0f, 0.0f }; - } - - for (int32_t i = 0; i < 2; i++) { - field_1A8[i] = 0.0f; - field_1C8[i] = 0.0; - if (!field_2F0[i] || field_1D0[i].size() < 1) - continue; - - vec3 v22 = 0.0f; - for (vec3& j : field_1D0[i]) - v22 += j; - - float_t v29 = (float_t)(int64_t)field_1D0[i].size(); - if (v29 < 0.0f) - v29 += (float_t)UINT64_MAX; - - float_t v30 = 0.0f; - vec3 v31 = v22 * (1.0f / v29); - - for (vec3& j : field_1D0[i]) { - vec3 v34 = v31 - j; - float_t v38 = fabsf(vec3::dot(v34, v3)); - float_t v39 = fabsf(vec3::dot(v34, v86)); - if (v39 >= v38) - v38 = v39; - if (v30 < v38) - v30 = v38; - } - field_1A8[i] = v31; - field_1C8[i] = v30; - } - - if (field_2EC > 0) { - for (int32_t i = 0; i < 2; i++) { - if (!field_2F0[i]) - continue; - - vec3 v53 = field_1A8[i] - direction * field_208; - float_t v51 = vec3::distance(view_point[i], v53); - float_t v54 = vec3::distance(interest[i], field_1A8[i]); - if (v51 > 0.1f || v54 > 0.1f) { - view_point[i] = v53; - interest[i] = field_1A8[i]; - } - } - - vec3 view_point = 0.0f; - vec3 interest = 0.0f; - int32_t count = 0; - for (int32_t i = 0; i < 2; i++) { - int32_t c = (int32_t)field_1D0[i].size(); - view_point += this->view_point[i] * (float_t)c; - interest += this->interest[i] * (float_t)c; - count += c; - } - - view_point_shared = view_point * (1.0f / (float_t)count); - interest_shared = interest * (1.0f / (float_t)count); - } - - float_t v2 = 0.0f; - float_t v67 = max_def(field_1C8[0], field_1C8[1]); - field_2F5 = false; - view_region = v67 + 1.2f; - field_200[0] = 0; - field_200[1] = 1; - if (field_2EC >= 2) { - float_t v68 = 0.0f; - float_t v69 = 0.0f; - float_t v70 = 0.0f; - for (int32_t i = 0; i < 2; i++) { - if (!field_2F0[i]) - continue; - - for (vec3& j : field_1D0[i]) { - vec3 v74 = j - interest_shared; - - float_t v77 = vec3::dot(v74, v86); - if (v2 > v77) - v2 = v77; - else if (v69 < v77) - v69 = v77; - - float_t v78 = vec3::dot(v74, v3); - if (v68 > v78) - v68 = v78; - else if (v70 < v78) - v70 = v78; - } - } - - float_t v79 = -v2; - if (v79 < v69) - v79 = v69; - if (v79 < -v68) - v79 = -v68; - if (v79 < v70) - v79 = v70; - - if (v79 > v67 + 1.2f) { - view_region = v67 + 2.4f; - field_2F5 = true; - } - else - view_region = v79 + 1.2f; - - if (vec3::dot(field_1A8[0] - interest_shared, direction) - < vec3::dot(field_1A8[1] - interest_shared, direction)) { - field_200[1] = 0; - field_200[0] = 1; - } - } - } - - for (std::vector& i : field_1D0) - i.clear(); -} - -int32_t Shadow::InitData() { - struct shadow_texture_init_params { - int32_t width; - int32_t height; - int32_t max_level; - GLenum color_format; - GLenum depth_format; - } init_params[] = { - { 0x800, 0x800, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F }, - { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, - { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, - { 0x800, 0x800, 0, GL_R32F , GL_ZERO }, - { 0x800, 0x800, 0, GL_R32F , GL_ZERO }, - { 0x200, 0x200, 0, GL_R32F , GL_ZERO }, - { 0x200, 0x200, 0, GL_R32F , GL_ZERO }, - { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, // Extra for buf - }; - - shadow_texture_init_params* v3 = init_params; - for (int32_t i = 0; i < 8; i++, v3++) - if (render_textures[i].Init(v3->width, v3->height, - v3->max_level, v3->color_format, v3->depth_format) < 0) - return -1; - - for (int32_t i = 0; i < 4; i++) { - gl_state_bind_texture_2d(render_textures[i == 3 ? 7 : i].GetColorTex()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - static const vec4 border_color = 1.0f; - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); - } - gl_state_bind_texture_2d(0); - gl_state_get_error(); - return 0; -} - -void Shadow::Reset() { - for (RenderTexture& i : render_textures) - i.Free(); - - ResetData(); -} - -void Shadow::ResetData() { - view_region = 1.2f; - range = 1.0f; - - for (int32_t i = 0; i < 2; i++) { - view_point[i] = 1.0f; - field_1C0[i] = 0.0f; - field_1C8[i] = 0.0f; - field_200[i] = i; - } - - for (RenderTexture*& i : curr_render_textures) - i = 0; - - view_mat[0] = mat4_identity; - view_mat[1] = mat4_identity; - blur_filter = BLUR_FILTER_9; - near_blur = 1; - field_2BC = 2; - far_blur = 1; - distance = 4.0f; - field_2C4 = 0.4f; - z_near = 0.1f; - z_far = 20.0f; - field_2D0 = 1.4f; - field_2D4 = 10000.0f; - field_2D8 = 80.0f; - field_2DC = 2.0f; - field_2E0 = 0.05f; - ambient = 0.4f; - field_2EC = 0; - direction = vec3(0.0f, -1.0f, -1.0f) * (1.0f / sqrtf(2.0f)); - field_2E8 = false; - self_shadow = true; - field_2F5 = false; - field_208 = (z_far - z_near) * 0.5f; -} - -static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, - int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]) { - const obj_mesh* mesh = args->mesh; - const obj_sub_mesh* sub_mesh = args->sub_mesh; - - //GLuint vertex_buffer = args->vertex_buffer; - GLuint vertex_buffer = args->vertex_buffer - ? args->vertex_buffer->get_buffer() : 0; - //GLuint morph_vertex_buffer = args->morph_vertex_buffer; - GLuint morph_vertex_buffer = args->morph_vertex_buffer - ? args->morph_vertex_buffer->get_buffer() : 0; - - bool compressed = mesh->attrib.m.compressed; - GLsizei size_vertex = (GLsizei)mesh->size_vertex; - obj_vertex_format vertex_format = mesh->vertex_format; - - if (vertex_format & OBJ_VERTEX_POSITION) - vertex_attrib_buffer_binding[POSITION_INDEX] = vertex_buffer; - if (vertex_format & OBJ_VERTEX_NORMAL) - vertex_attrib_buffer_binding[NORMAL_INDEX] = vertex_buffer; - if (vertex_format & OBJ_VERTEX_TANGENT) - vertex_attrib_buffer_binding[TANGENT_INDEX] = vertex_buffer; - - for (int32_t i = 0; i < 2; i++) { - int32_t texcoord_index = texcoord_array[i]; - if (texcoord_index >= 0) - if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) - vertex_attrib_buffer_binding[TEXCOORD0_INDEX + i] = vertex_buffer; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) - vertex_attrib_buffer_binding[COLOR0_INDEX] = vertex_buffer; - - if (vertex_format & OBJ_VERTEX_BONE_DATA) { - vertex_attrib_buffer_binding[BONE_WEIGHT_INDEX] = vertex_buffer; - vertex_attrib_buffer_binding[BONE_INDEX_INDEX] = vertex_buffer; - } - - if (!compressed && vertex_format & OBJ_VERTEX_UNKNOWN) - vertex_attrib_buffer_binding[UNKNOWN_INDEX] = vertex_buffer; - - if (args->morph_vertex_buffer) { - if (vertex_format & OBJ_VERTEX_POSITION) - vertex_attrib_buffer_binding[MORPH_POSITION_INDEX] = morph_vertex_buffer; - if (vertex_format & OBJ_VERTEX_NORMAL) - vertex_attrib_buffer_binding[MORPH_NORMAL_INDEX] = morph_vertex_buffer; - if (vertex_format & OBJ_VERTEX_TANGENT) - vertex_attrib_buffer_binding[MORPH_TANGENT_INDEX] = morph_vertex_buffer; - if (vertex_format & OBJ_VERTEX_TEXCOORD0) - vertex_attrib_buffer_binding[MORPH_TEXCOORD0_INDEX] = morph_vertex_buffer; - if (vertex_format & OBJ_VERTEX_TEXCOORD1) - vertex_attrib_buffer_binding[MORPH_TEXCOORD1_INDEX] = morph_vertex_buffer; - if (vertex_format & OBJ_VERTEX_COLOR0) - vertex_attrib_buffer_binding[MORPH_COLOR_INDEX] = morph_vertex_buffer; + if (render_res_change) { + free(); + init(); } } diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 415dbf3b..8b240dff 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -15,164 +15,14 @@ #include "light_param/fog.hpp" #include "light_param/light.hpp" #include "light_param/wind.hpp" -#include "light_param.hpp" +#include "mdl/disp_manager.hpp" #include "camera.hpp" -#include "color.hpp" -#include "gl_state.hpp" #include "light_param.hpp" -#include "object.hpp" -#include "post_process.hpp" +#include "render.hpp" +#include "render_manager.hpp" #include "render_texture.hpp" -#include "task.hpp" -#include "static_var.hpp" #define MATRIX_BUFFER_COUNT 320 -#define MATERIAL_LIST_COUNT 24 -#define TEXTURE_PATTERN_COUNT 24 -#define TEXTURE_TRANSFORM_COUNT 24 - -enum blur_filter_mode { - BLUR_FILTER_4 = 0, - BLUR_FILTER_9, - BLUR_FILTER_16, - BLUR_FILTER_32, - BLUR_FILTER_MAX, -}; - -enum reflect_refract_resolution_mode { - REFLECT_REFRACT_RESOLUTION_256x256 = 0, - REFLECT_REFRACT_RESOLUTION_512x256, - REFLECT_REFRACT_RESOLUTION_512x512, - REFLECT_REFRACT_RESOLUTION_MAX, -}; - -enum shadow_type_enum { - SHADOW_CHARA = 0, - SHADOW_STAGE, - SHADOW_MAX, -}; - -namespace mdl { - enum EtcObjType { - ETC_OBJ_TEAPOT = 0, - ETC_OBJ_GRID, - ETC_OBJ_CUBE, - ETC_OBJ_SPHERE, - ETC_OBJ_PLANE, - ETC_OBJ_CONE, - ETC_OBJ_LINE, - ETC_OBJ_CROSS, - ETC_OBJ_CAPSULE, // Added - ETC_OBJ_ELLIPSE, // Added - ETC_OBJ_CYLINDER, // Added - ETC_OBJ_MAX, - }; - - enum ObjKind { - OBJ_KIND_NORMAL = 0, - OBJ_KIND_ETC, - OBJ_KIND_USER, - OBJ_KIND_TRANSLUCENT, - OBJ_KIND_MAX, - }; - - enum ObjFlags : uint32_t { - OBJ_SHADOW = 0x00000001, - OBJ_2 = 0x00000002, - OBJ_4 = 0x00000004, - OBJ_8 = 0x00000008, - OBJ_10 = 0x00000010, - OBJ_20 = 0x00000020, - OBJ_40 = 0x00000040, - OBJ_SHADOW_OBJECT = 0x00000080, - OBJ_CHARA_REFLECT = 0x00000100, - OBJ_REFLECT = 0x00000200, - OBJ_REFRACT = 0x00000400, - OBJ_800 = 0x00000800, - OBJ_TRANSLUCENT_NO_SHADOW = 0x00001000, - OBJ_SSS = 0x00002000, - OBJ_4000 = 0x00004000, - OBJ_8000 = 0x00008000, - OBJ_ALPHA_ORDER_1 = 0x00010000, - OBJ_ALPHA_ORDER_2 = 0x00020000, - OBJ_ALPHA_ORDER_3 = 0x00040000, - OBJ_80000 = 0x00080000, - OBJ_100000 = 0x00100000, - OBJ_200000 = 0x00200000, - OBJ_400000 = 0x00400000, - OBJ_800000 = 0x00800000, - OBJ_USER = 0x01000000, - OBJ_2000000 = 0x02000000, - OBJ_4000000 = 0x04000000, - OBJ_8000000 = 0x08000000, - OBJ_10000000 = 0x10000000, - OBJ_20000000 = 0x20000000, - OBJ_40000000 = 0x40000000, - OBJ_NO_TRANSLUCENCY = 0x80000000, - }; - - enum ObjType { - OBJ_TYPE_OPAQUE = 0, - OBJ_TYPE_TRANSLUCENT, - OBJ_TYPE_TRANSLUCENT_NO_SHADOW, - OBJ_TYPE_TRANSPARENT, - OBJ_TYPE_SHADOW_CHARA, - OBJ_TYPE_SHADOW_STAGE, - OBJ_TYPE_TYPE_6, - OBJ_TYPE_TYPE_7, - OBJ_TYPE_SHADOW_OBJECT_CHARA, - OBJ_TYPE_SHADOW_OBJECT_STAGE, - OBJ_TYPE_REFLECT_CHARA_OPAQUE, - OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT, - OBJ_TYPE_REFLECT_CHARA_TRANSPARENT, - OBJ_TYPE_REFLECT_OPAQUE, - OBJ_TYPE_REFLECT_TRANSLUCENT, - OBJ_TYPE_REFLECT_TRANSPARENT, - OBJ_TYPE_REFRACT_OPAQUE, - OBJ_TYPE_REFRACT_TRANSLUCENT, - OBJ_TYPE_REFRACT_TRANSPARENT, - OBJ_TYPE_SSS, - OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, - OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, - OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, - OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, - OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, - OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, - OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, - OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, - OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, - OBJ_TYPE_USER, - OBJ_TYPE_OPAQUE_LOCAL, // X - OBJ_TYPE_TRANSLUCENT_LOCAL, - OBJ_TYPE_TRANSPARENT_LOCAL, - OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL, - OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL, - OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, - OBJ_TYPE_MAX, - }; -} - -namespace rndr { - enum RenderPassID { - RND_PASSID_SHADOW = 0, - RND_PASSID_SS_SSS, - RND_PASSID_2, - RND_PASSID_REFLECT, - RND_PASSID_REFRACT, - RND_PASSID_PRE_PROCESS, - RND_PASSID_CLEAR, - RND_PASSID_PRE_SPRITE, - RND_PASSID_3D, - RND_PASSID_SHOW_VECTOR, - RND_PASSID_POST_PROCESS, - RND_PASSID_SPRITE, - RND_PASSID_12, - RND_PASSID_NUM, - }; -} - -struct render_context; -struct Shadow; struct draw_state_stats { int32_t object_draw_count; @@ -189,17 +39,6 @@ struct draw_state_stats { void reset(); }; -struct sss_data { - bool init; - bool enable; - bool npr_contour; - RenderTexture textures[4]; - vec4 param; - - sss_data(); - ~sss_data(); -}; - struct draw_state { draw_state_stats stats; draw_state_stats stats_prev; @@ -227,235 +66,20 @@ struct draw_state { void set_fog_height(bool value); }; -struct draw_pre_process { - int32_t type; - void(*func)(void*); - void* data; +struct sss_data { + bool init_data; + bool enable; + bool npr_contour; + RenderTexture textures[4]; + vec4 param; + + sss_data(); + ~sss_data(); + + void free(); + void init(); }; -struct material_list_struct { - uint32_t hash; - vec4 blend_color; - vec4u8 has_blend_color; - vec4 emission; - vec4u8 has_emission; - - material_list_struct(); - material_list_struct(uint32_t hash, vec4& blend_color, - vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission); -}; - -struct texture_pattern_struct { - texture_id src; - texture_id dst; - - texture_pattern_struct(); - texture_pattern_struct(texture_id src, texture_id dst); -}; - -struct texture_transform_struct { - uint32_t id; - mat4 mat; - - texture_transform_struct(); - texture_transform_struct(uint32_t id, mat4& mat); -}; - -namespace mdl { - struct DispManager; - struct ObjSubMeshArgs; - - struct ObjSubMeshArgs { - const obj_sub_mesh* sub_mesh; - const obj_mesh* mesh; - const obj_material_data* material; - const std::vector* textures; - int32_t mat_count; - const mat4* mats; - //GLuint vertex_buffer; - obj_mesh_vertex_buffer* vertex_buffer; - //GLuint index_buffer; - obj_mesh_index_buffer* index_buffer; - bool set_blend_color; - bool chara_color; - vec4 blend_color; - vec4 emission; - bool self_shadow; - shadow_type_enum shadow; - //GLuint morph_vertex_buffer; - obj_mesh_vertex_buffer* morph_vertex_buffer; - float_t morph_weight; - int32_t texture_pattern_count; - texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; - vec4 texture_color_coefficients; - vec4 texture_color_offset; - vec4 texture_specular_coefficients; - vec4 texture_specular_offset; - int32_t texture_transform_count; - texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; - int32_t instances_count; - const mat4* instances_mat; - void(*func)(const mdl::ObjSubMeshArgs*); - }; - - struct EtcObjTeapot { - float_t size; - - EtcObjTeapot(); - }; - - struct EtcObjGrid { - int32_t w; - int32_t h; - int32_t ws; - int32_t hs; - - EtcObjGrid(); - }; - - struct EtcObjCube { - vec3 size; - bool wire; - - EtcObjCube(); - }; - - struct EtcObjSphere { - float_t radius; - int32_t slices; - int32_t stacks; - bool wire; - - EtcObjSphere(); - }; - - struct EtcObjPlane { - int32_t w; - int32_t h; - - EtcObjPlane(); - }; - - struct EtcObjCone { - float_t base; - float_t height; - int32_t slices; - int32_t stacks; - bool wire; - - EtcObjCone(); - }; - - struct EtcObjLine { - vec3 pos[2]; - - EtcObjLine(); - }; - - struct EtcObjCross { - float_t size; - - EtcObjCross(); - }; - - struct EtcObjCapsule { // Added - float_t radius; - int32_t slices; - int32_t stacks; - bool wire; - vec3 pos[2]; - - EtcObjCapsule(); - }; - - struct EtcObjEllipse { // Added - float_t radius; - int32_t slices; - int32_t stacks; - bool wire; - vec3 pos[2]; - - EtcObjEllipse(); - }; - - struct EtcObjCylinder { // Added - float_t base; - float_t top; - float_t height; - int32_t slices; - int32_t stacks; - bool wire; - - EtcObjCylinder(); - }; - - struct EtcObj { - union Data { - EtcObjTeapot teapot; - EtcObjGrid grid; - EtcObjCube cube; - EtcObjSphere sphere; - EtcObjPlane plane; - EtcObjCone cone; - EtcObjLine line; - EtcObjCross cross; - EtcObjCapsule capsule; // Added - EtcObjEllipse ellipse; // Added - EtcObjCylinder cylinder; // Added - - Data(); - }; - - EtcObjType type; - color4u8 color; - //bool fog; - bool constant; // Added - Data data; - GLsizei count; // Added - size_t offset; // Added - - EtcObj(); - void init(EtcObjType type); - }; - - typedef void(*UserArgsFunc)(render_context* rctx, void* data); - - struct UserArgs { - UserArgsFunc func; - void* data; - }; - - struct ObjTranslucentArgs { - uint32_t count; - ObjSubMeshArgs* sub_mesh[40]; - }; - - struct ObjData { - union Args { - ObjSubMeshArgs sub_mesh; - EtcObj etc; - UserArgs user; - ObjTranslucentArgs translucent; - }; - - ObjKind kind; - mat4 mat; - float_t view_z; - float_t radius; - Args args; - - void init_etc(DispManager* disp_manager, const mat4* mat, mdl::EtcObj* etc); - void init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, - obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, - int32_t mat_count, mat4* mats, /*GLuint vertex_buffer, GLuint index_buffer,*/ - obj_mesh_vertex_buffer* vertex_buffer, obj_mesh_index_buffer* index_buffer, vec4* blend_color, - vec4* emission, /*GLuint morph_vertex_buffer,*/ obj_mesh_vertex_buffer* morph_vertex_buffer, - int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)); - void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent); - void init_user(const mat4* mat, UserArgsFunc func, void* data); - }; -} - struct light_proj { bool enable; RenderTexture shadow_texture[2]; @@ -466,259 +90,11 @@ struct light_proj { ~light_proj(); void resize(int32_t width, int32_t height); - bool set(render_context* rctx); + bool set(); - static bool set_mat(render_context* rctx, bool set_mat); + static bool set_mat(bool set_mat); }; -struct morph_struct { - object_info object; - float_t weight; - - morph_struct(); -}; - -struct texture_data_struct { - int32_t field_0; - vec3 texture_color_coefficients; - vec3 texture_color_offset; - vec3 texture_specular_coefficients; - vec3 texture_specular_offset; - - texture_data_struct(); -}; - -namespace mdl { - struct CullingCheck { - struct Info { - int32_t objects; - int32_t meshes; - int32_t submesh_array; - }; - - Info passed; - Info culled; - Info passed_prev; - Info culled_prev; - - bool(*func)(obj_bounding_sphere*, mat4*); - }; - - struct DispManager { - struct vertex_array { - //GLuint vertex_buffer; - obj_mesh_vertex_buffer* vertex_buffer; - //GLuint morph_vertex_buffer; - obj_mesh_vertex_buffer* morph_vertex_buffer; - //GLuint index_buffer; - obj_mesh_index_buffer* index_buffer; - int32_t alive_time; - GLuint vertex_array; - bool vertex_attrib_array[16]; - obj_vertex_format vertex_format; - GLsizei size_vertex; - bool compressed; - GLuint vertex_attrib_buffer_binding[16]; - int32_t texcoord_array[2]; - }; - - struct etc_vertex_array { - GL::ArrayBuffer vertex_buffer; - GL::ElementArrayBuffer index_buffer; - int32_t alive_time; - GLuint vertex_array; - EtcObj::Data data; - EtcObjType type; - GLsizei count; - size_t offset; - GLsizei wire_count; - size_t wire_offset; - size_t max_vtx; - size_t max_idx; - }; - - mdl::ObjFlags obj_flags; - shadow_type_enum shadow_type; - int32_t field_8; - int32_t field_C; - std::vector obj[mdl::OBJ_TYPE_MAX]; - mdl::CullingCheck culling; - int32_t put_index; - bool show_alpha_center; - bool show_mat_center; - bool object_culling; - bool object_sort; - bool chara_color; - int32_t buff_offset; - int32_t buff_max; - int32_t buff_size; - void* buff; - morph_struct morph; - int32_t texture_pattern_count; - texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; - vec4 texture_color_coefficients; - vec4 texture_color_offset; - vec4 texture_specular_coefficients; - vec4 texture_specular_offset; - float_t wet_param; - int32_t texture_transform_count; - texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; - int32_t material_list_count; - material_list_struct material_list_array[MATERIAL_LIST_COUNT]; - std::vector vertex_array_cache; - std::vector etc_vertex_array_cache; - - DispManager(); - ~DispManager(); - - void add_vertex_array(ObjSubMeshArgs* args); - void add_vertex_array(EtcObj* etc, mat4& mat); - ObjData* alloc_data(ObjKind kind); - mat4* alloc_data(int32_t count); - void buffer_reset(); - void check_vertex_arrays(); - void draw(mdl::ObjType type, int32_t depth_mask = 0, bool a4 = true); - void draw_translucent(mdl::ObjType type, int32_t alpha); - /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ - void entry_list(ObjType type, ObjData* data); - bool entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, - obj_mesh_index_buffer* obj_index_buf, const mat4* mat, - std::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, - obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, - mat4* instances_mat, void(*func)(const mdl::ObjSubMeshArgs*), bool enable_bone_mat, bool local = false); - void entry_obj_by_obj(const mat4* mat, - ::obj* obj, std::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, - obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha); - bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat = 0); - bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, - vec4* blend_color, mat4* bone_mat, int32_t instances_count, - mat4* instances_mat, void(*func)(const mdl::ObjSubMeshArgs*), bool enable_bone_mat, bool local = false); - bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, float_t alpha, mat4* bone_mat = 0); - bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, - float_t r, float_t g, float_t b, float_t a, mat4* bone_mat = 0, bool local = false); - bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, - vec4* blend_color, mat4* bone_mat = 0, bool local = false); - void entry_obj_by_object_info_object_skin(object_info obj_info, - std::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, - mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat); - void entry_obj_etc(const mat4* mat, EtcObj* etc, bool local = false); - void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type); - GLuint get_vertex_array(const ObjSubMeshArgs* args); - GLuint get_vertex_array(const EtcObj* etc); - bool get_chara_color(); - ObjFlags get_obj_flags(); - void get_material_list(int32_t& count, material_list_struct*& value); - void get_morph(object_info& object, float_t& weight); - int32_t get_obj_count(ObjType type); - shadow_type_enum get_shadow_type(); - void get_texture_color_coeff(vec4& value); - void get_texture_color_offset(vec4& value); - void get_texture_pattern(int32_t& count, texture_pattern_struct*& value); - void get_texture_specular_coeff(vec4& value); - 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); - void refresh(); - void set_chara_color(bool value = false); - void set_obj_flags(ObjFlags flags = (ObjFlags)0); - void set_material_list(int32_t count = 0, material_list_struct* value = 0); - void set_morph(object_info object = {}, float_t weight = 0.0f); - void set_culling_finc(bool(*func)(obj_bounding_sphere*, mat4*) = 0); - void set_shadow_type(shadow_type_enum type = SHADOW_CHARA); - void set_texture_color_coefficients(vec4& value); - void set_texture_color_offset(vec4& value); - void set_texture_pattern(int32_t count = 0, texture_pattern_struct* value = 0); - void set_texture_specular_coefficients(vec4& value); - void set_texture_specular_offset(vec4& value); - void set_texture_transform(int32_t count = 0, texture_transform_struct* value = 0); - void set_wet_param(float_t value = 0.0f); - }; -} - -namespace rndr { - struct RenderManager { - bool pass_sw[rndr::RND_PASSID_NUM]; - Shadow* shadow_ptr; - bool reflect; - bool refract; - int32_t reflect_blur_num; - blur_filter_mode reflect_blur_filter; - bool sync_gpu; - double_t cpu_time[rndr::RND_PASSID_NUM]; - double_t gpu_time[rndr::RND_PASSID_NUM]; - time_struct time; - bool shadow; - bool opaque_z_sort; - bool alpha_z_sort; - bool draw_pass_3d[DRAW_PASS_3D_MAX]; - bool show_ref_map; - stage_data_reflect_type reflect_type; - bool clear; - int32_t tex_index[12]; // Extra for buf - RenderTexture render_textures[9]; // Extra for buf - GLuint multisample_framebuffer; - GLuint multisample_renderbuffer; - bool multisample; - int32_t show_vector_flags; - float_t show_vector_length; - float_t show_vector_z_offset; - bool field_2F8; - std::list pre_process; - texture* effect_texture; - int32_t npr_param; - bool field_31C; - bool field_31D; - bool field_31E; - bool field_31F; - bool field_320; - bool npr; - sss_data sss_data; - - RenderManager(); - ~RenderManager(); - - void add_pre_process(int32_t type, void(*func)(void*), void* data); - void clear_pre_process(int32_t type); - RenderTexture& get_render_texture(int32_t index); - void resize(int32_t width, int32_t height); - void set_effect_texture(texture* value); - void set_multisample(bool value); - void set_npr_param(int32_t value); - void set_pass_sw(rndr::RenderPassID id, bool value); - void set_reflect(bool value); - void set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter); - void set_reflect_resolution_mode(reflect_refract_resolution_mode mode); - void set_reflect_type(stage_data_reflect_type type); - void set_refract(bool value); - void set_refract_resolution_mode(reflect_refract_resolution_mode mode); - void set_shadow_false(); - void set_shadow_true(); - - void render_all(render_context* rctx); - - void render_single_pass(rndr::RenderPassID id, render_context* rctx); - - void render_pass_begin(); - void render_pass_end(rndr::RenderPassID id); - - void pass_shadow(render_context* rctx); - void pass_ss_sss(render_context* rctx); - void pass_reflect(render_context* rctx); - void pass_refract(render_context* rctx); - void pass_pre_process(render_context* rctx); - void pass_clear(render_context* rctx); - void pass_pre_sprite(render_context* rctx); - void pass_3d(render_context* rctx); - void pass_show_vector(render_context* rctx); - void pass_post_process(render_context* rctx); - void pass_sprite(render_context* rctx); - - void pass_3d_contour(render_context* rctx); - void pass_sprite_surf(render_context* rctx); - }; -} - struct contour_coef_shader_data { vec4 g_contour; vec4 g_near_far; @@ -733,6 +109,15 @@ struct filter_scene_shader_data { vec4 g_texcoord; }; +struct exposure_measure_shader_data { + vec4 g_spot_weight; + vec4 g_spot_coefficients[32]; +}; + +struct gaussian_coef_shader_data { + vec4 g_coef[8]; +}; + struct esm_filter_batch_shader_data { vec4 g_params; vec4 g_gauss[2]; @@ -760,6 +145,13 @@ struct glass_eye_batch_shader_data { vec4 g_tex_scale; }; +struct glitter_batch_shader_data { + vec4 g_mvp[4]; + vec4 g_glitter_blend_color; + vec4 g_state_material_diffuse; + vec4 g_state_material_emission; +}; + struct obj_scene_shader_data { vec4 g_irradiance_r_transforms[4]; vec4 g_irradiance_g_transforms[4]; @@ -876,22 +268,37 @@ struct sss_filter_gaussian_coef_shader_data { vec4 g_coef[64]; }; +struct sun_quad_shader_data { + vec4 g_transform[4]; + vec4 g_emission; +}; + +struct tone_map_shader_data { + vec4 g_exposure; + vec4 g_flare_coef; + vec4 g_fade_color; + vec4 g_tone_scale; //xyz=tone_scale, w=fade_func + vec4 g_tone_offset; //xyz=tone_offset, w=inv_tone + vec4 g_texcoord_transforms[8]; +}; + struct transparency_batch_shader_data { vec4 g_opacity; }; struct render_context { ::camera* camera; - draw_state draw_state; - mdl::DispManager disp_manager; - rndr::RenderManager render_manager; + draw_state* draw_state; + mdl::DispManager* disp_manager; + rndr::RenderManager* render_manager; + sss_data* sss_data; face face; fog fog[FOG_MAX]; light_proj* litproj; light_set light_set[LIGHT_SET_MAX]; - post_process post_process; + rndr::Render render; bool chara_reflect; bool chara_refract; @@ -903,18 +310,33 @@ struct render_context { mat4 matrix_buffer[MATRIX_BUFFER_COUNT]; GLuint box_vao; - GLuint box_vbo; + GL::ArrayBuffer box_vbo; + + GLuint lens_ghost_vao; + GL::ArrayBuffer lens_ghost_vbo; + + GLuint common_vao; + + RenderTexture reflect_buffer; + RenderTexture render_buffer; + RenderTexture screen_buffer; + RenderTexture shadow_buffer; GL::UniformBuffer contour_coef_ubo; GL::UniformBuffer contour_params_ubo; GL::UniformBuffer filter_scene_ubo; GL::UniformBuffer esm_filter_batch_ubo; GL::UniformBuffer imgfilter_batch_ubo; + GL::UniformBuffer exposure_measure_ubo; + GL::UniformBuffer gaussian_coef_ubo; GL::UniformBuffer glass_eye_batch_ubo; + GL::UniformBuffer glitter_batch_ubo; GL::UniformBuffer quad_ubo; GL::UniformBuffer sprite_scene_ubo; GL::UniformBuffer sss_filter_gaussian_coef_ubo; + GL::UniformBuffer sun_quad_ubo; GL::UniformBuffer transparency_batch_ubo; + GL::UniformBuffer tone_map_ubo; obj_scene_shader_data obj_scene; obj_batch_shader_data obj_batch; @@ -927,64 +349,30 @@ struct render_context { GLuint empty_texture_cube_map; GLuint samplers[18]; + GLuint render_samplers[3]; GLuint sprite_samplers[3]; + int32_t sprite_width; + int32_t sprite_height; + int32_t screen_x_offset; + int32_t screen_y_offset; + int32_t screen_width; + int32_t screen_height; + render_context(); ~render_context(); void ctrl(); void disp(); + void free(); + void init(); void light_param_data_light_set(light_param_light* light); void light_param_data_fog_set(light_param_fog* f); void light_param_data_glow_set(light_param_glow* glow); void light_param_data_ibl_set(light_param_ibl* ibl, light_param_data_storage* storage); void light_param_data_wind_set(light_param_wind* w); void light_param_data_face_set(light_param_face* face); -}; - -struct Shadow { - RenderTexture render_textures[8]; // Extra for buf - RenderTexture* curr_render_textures[4]; // Extra for buf - float_t view_region; - float_t range; - vec3 view_point[2]; - vec3 interest[2]; - vec3 field_1A8[2]; - float_t field_1C0[2]; - float_t field_1C8[2]; - std::vector field_1D0[2]; - int32_t field_200[2]; - float_t field_208; - vec3 direction; - vec3 view_point_shared; - vec3 interest_shared; - mat4 view_mat[2]; - int32_t near_blur; - blur_filter_mode blur_filter; - int32_t far_blur; - int32_t field_2BC; - float_t distance; - float_t field_2C4; - float_t z_near; - float_t z_far; - float_t field_2D0; - float_t field_2D4; - float_t field_2D8; - float_t field_2DC; - float_t field_2E0; - float_t ambient; - bool field_2E8; - int32_t field_2EC; - bool field_2F0[2]; - bool self_shadow; - bool blur_filter_enable[2]; - bool field_2F5; - - Shadow(); - ~Shadow(); - - void Ctrl(render_context* rctx); - int32_t InitData(); - void Reset(); - void ResetData(); + void resize(int32_t render_width, int32_t render_height, + int32_t sprite_width, int32_t sprite_height, + int32_t screen_width, int32_t screen_height); }; diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index 868512a8..6ec45438 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -11,7 +11,8 @@ #include "rob/rob.hpp" #include "clear_color.hpp" #include "gl_state.hpp" -#include "post_process.hpp" +#include "render.hpp" +#include "render_context.hpp" #include "render_texture.hpp" #include "shader_ft.hpp" #include "sprite.hpp" @@ -19,16 +20,13 @@ #include "task_effect.hpp" #include "texture.hpp" -static void draw_pass_shadow_begin_make_shadowmap(render_context* rctx, - Shadow* shad, int32_t index, int32_t a3); -static void draw_pass_shadow_end_make_shadowmap(render_context* rctx, - Shadow* shad, int32_t index, int32_t a3); -static void draw_pass_shadow_filter(render_context* rctx, RenderTexture* a1, RenderTexture* a2, +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(render_context* rctx, - RenderTexture* dst, RenderTexture* buf, RenderTexture* src); -static bool draw_pass_shadow_litproj(render_context* rctx, light_proj* litproj); -static void draw_pass_sss_contour(render_context* rctx, post_process* pp); +static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src); +static bool draw_pass_shadow_litproj(light_proj* litproj); +static void draw_pass_sss_contour(render_context* rctx, rndr::Render* rend); static void draw_pass_sss_filter(render_context* rctx, sss_data* sss); static int32_t draw_pass_3d_get_translucent_count(render_context* rctx); static void draw_pass_3d_shadow_reset(render_context* rctx); @@ -41,17 +39,230 @@ static int32_t draw_pass_3d_translucent_count_layers(render_context* rctx, mdl::ObjType transparent, mdl::ObjType translucent); static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr, mdl::ObjType type); -static void blur_filter_apply(render_context* rctx, GLuint tex_0, GLuint tex_1, +static void blur_filter_apply(render_context* rctx, RenderTexture* dst, RenderTexture* src, blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset); +static void render_manager_free_render_textures(); +static void render_manager_init_render_textures(int32_t multisample); + extern light_param_data_storage* light_param_data_storage_data; +extern render_context* rctx_ptr; namespace rndr { - void RenderManager::render_all(render_context* rctx) { + struct RenderTextureData { + GLenum type; + int32_t width; + int32_t height; + int32_t max_level; + GLenum color_format; + GLenum depth_format; + }; + + static const RenderTextureData render_manager_render_texture_data_array[] = { + { GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA8 , GL_DEPTH_COMPONENT24 }, + { GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA16F, GL_DEPTH_COMPONENT24 }, + { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, + { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, + { GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO }, + { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO }, + { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA32F, GL_ZERO }, + { GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO }, + }; + + static const int32_t render_manager_render_texture_index_array[][3] = { + { 1, 1, 1 }, + { 0, 0, 0 }, + { 6, 6, 6 }, + { 6, 6, 6 }, + { 6, 6, 6 }, + { 2, 2, 2 }, + { 3, 3, 3 }, + { 4, 4, 4 }, + { 5, 5, 5 }, + { 6, 6, 6 }, + { 7, 7, 7 }, + }; + + RenderManager::RenderManager() : pass_sw(), reflect_blur_num(), reflect_blur_filter(), + render(), sync_gpu(), cpu_time(), gpu_time(), draw_pass_3d(), field_11E(), field_11F(), + field_120(), show_ref_map(), reflect_type(), clear(), tex_index(), width(), height(), + multisample_framebuffer(), multisample_renderbuffer(), multisample(), check_state(), + show_vector_flags(), show_vector_length(), show_vector_z_offset(), field_2F8(), effect_texture(), + npr_param(), field_31C(), field_31D(), field_31E(), field_31F(), field_320(), npr() { + for (bool& i : pass_sw) + i = true; + + set_pass_sw(RND_PASSID_2, false); + set_pass_sw(RND_PASSID_REFLECT, false); + set_pass_sw(RND_PASSID_REFRACT, false); + set_pass_sw(RND_PASSID_PRE_PROCESS, false); + set_pass_sw(RND_PASSID_SHOW_VECTOR, false); + + shadow = true; + opaque_z_sort = true; + alpha_z_sort = true; + + for (bool& i : draw_pass_3d) + i = true; + } + + RenderManager::~RenderManager() { + + } + + void RenderManager::add_pre_process(int32_t type, void(*func)(void*), void* data) { + pre_process.push_back({ type, func, data }); + } + + void RenderManager::clear_pre_process(int32_t type) { + for (std::list::iterator i = pre_process.begin(); i != pre_process.end(); i++) + if (i->type == type) { + pre_process.erase(i); + break; + } + } + + RenderTexture& RenderManager::get_render_texture(int32_t index) { + return render_textures[render_manager_render_texture_index_array[index][tex_index[index]]]; + } + + void RenderManager::reset() { + for (int32_t i = 0; i < RND_PASSID_NUM; i++) { + pass_sw[i] = true; + cpu_time[i] = 0.0; + gpu_time[i] = 0.0; + } + + set_pass_sw(RND_PASSID_2, 0); + set_pass_sw(RND_PASSID_REFLECT, 0); + set_pass_sw(RND_PASSID_REFRACT, 0); + set_pass_sw(RND_PASSID_PRE_PROCESS, 0); + set_pass_sw(RND_PASSID_SHOW_VECTOR, 0); + + shadow_ptr = 0; + sync_gpu = 0; + time.get_timestamp(); + + shadow = true; + opaque_z_sort = true; + alpha_z_sort = true; + field_11F = false; + field_120 = false; + + reflect_blur_num = 1; + reflect_blur_filter = BLUR_FILTER_4; + show_ref_map = false; + + reflect_type = STAGE_DATA_REFLECT_DISABLE; + check_state = false; + show_vector_flags = 0; + show_vector_length = 0.05f; + show_vector_z_offset = 0.0f; + field_2F8 = false; + effect_texture = 0; + + reflect = false; + refract = false; + npr_param = 0; + field_31C = false; + field_31D = false; + field_31E = false; + field_31F = false; + field_320 = false; + + for (bool& i : draw_pass_3d) + i = true; + + field_11E = false; + clear = false; + + width = 0; + height = 0; + multisample_framebuffer = 0; + multisample_renderbuffer = 0; + multisample = false;//true; + + npr = false; + } + + void RenderManager::resize(int32_t width, int32_t height) { + if (this->width == width && this->height == height) + return; + + this->width = width; + this->height = height; + + if (!multisample_framebuffer) + glGenFramebuffers(1, &multisample_framebuffer); + + if (!multisample_renderbuffer) + glGenRenderbuffers(1, &multisample_renderbuffer); + + glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisample_renderbuffer); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + void RenderManager::set_effect_texture(texture* value) { + effect_texture = value; + } + + void RenderManager::set_multisample(bool value) { + multisample = value; + } + + void RenderManager::set_npr_param(int32_t value) { + npr_param = value; + } + + void RenderManager::set_pass_sw(RenderPassID id, bool value) { + pass_sw[id] = value; + } + + void RenderManager::set_reflect(bool value) { + reflect = value; + } + + void RenderManager::set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter) { + this->reflect_blur_num = reflect_blur_num; + this->reflect_blur_filter = reflect_blur_filter; + } + + void RenderManager::set_reflect_resolution_mode(reflect_refract_resolution_mode mode) { + tex_index[0] = mode; + } + + void RenderManager::set_reflect_type(int32_t type) { + reflect_type = type; + } + + void RenderManager::set_refract(bool value) { + refract = value; + } + + void RenderManager::set_refract_resolution_mode(reflect_refract_resolution_mode mode) { + tex_index[1] = mode; + } + + void RenderManager::set_shadow_false() { + shadow = false; + } + + void RenderManager::set_shadow_true() { + shadow = true; + } + + void RenderManager::render_all() { static const int32_t ibl_texture_index[] = { 9, 10, 11, 12, 13 }; + render_context* rctx = rctx_ptr; camera* cam = rctx->camera; for (int32_t i = 0; i < 5; i++) @@ -59,10 +270,10 @@ namespace rndr { light_param_data_storage_data->textures[i]); rctx->obj_scene.g_framebuffer_size = { - 1.0f / (float_t)rctx->post_process.render_width, - 1.0f / (float_t)rctx->post_process.render_height, - (float_t)rctx->post_process.render_width, - (float_t)rctx->post_process.render_height + 1.0f / (float_t)render->render_width[0], + 1.0f / (float_t)render->render_height[0], + (float_t)render->render_width[0], + (float_t)render->render_height[0] }; gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -72,20 +283,20 @@ namespace rndr { gl_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, rctx); + RenderManager::render_single_pass((RenderPassID)i); gl_state_end_event(); gl_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, rctx); + RenderManager::render_single_pass((RenderPassID)i); gl_state_end_event(); gl_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, rctx); + RenderManager::render_single_pass((RenderPassID)i); gl_state_end_event(); - rctx->disp_manager.check_vertex_arrays(); + rctx->disp_manager->check_vertex_arrays(); gl_state_bind_vertex_array(0); gl_state_disable_primitive_restart(); gl_state_bind_uniform_buffer_base(0, 0); @@ -95,7 +306,7 @@ namespace rndr { gl_state_bind_uniform_buffer_base(4, 0); } - void RenderManager::render_single_pass(RenderPassID id, render_context* rctx) { + void RenderManager::render_single_pass(RenderPassID id) { cpu_time[id] = 0.0; gpu_time[id] = 0.0; if (!pass_sw[id]) { @@ -106,37 +317,37 @@ namespace rndr { render_pass_begin(); switch (id) { case RND_PASSID_SHADOW: - pass_shadow(rctx); + pass_shadow(); break; case RND_PASSID_SS_SSS: - pass_ss_sss(rctx); + pass_ss_sss(); break; case RND_PASSID_REFLECT: - pass_reflect(rctx); + pass_reflect(); break; case RND_PASSID_REFRACT: - pass_refract(rctx); + pass_refract(); break; case RND_PASSID_PRE_PROCESS: - pass_pre_process(rctx); + pass_pre_process(); break; case RND_PASSID_CLEAR: - pass_clear(rctx); + pass_clear(); break; case RND_PASSID_PRE_SPRITE: - pass_pre_sprite(rctx); + pass_pre_sprite(); break; case RND_PASSID_3D: - pass_3d(rctx); + pass_3d(); break; case RND_PASSID_SHOW_VECTOR: - pass_show_vector(rctx); + pass_show_vector(); break; case RND_PASSID_POST_PROCESS: - pass_post_process(rctx); + pass_post_process(); break; case RND_PASSID_SPRITE: - pass_sprite(rctx); + pass_sprite(); break; } render_pass_end(id); @@ -160,37 +371,38 @@ namespace rndr { gpu_time[id] = 0; } - void RenderManager::pass_shadow(render_context* rctx) { + void RenderManager::pass_shadow() { + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_shadow"); rctx->camera->update_data(); - if (rctx->litproj->set(rctx)) { + if (rctx->litproj->set()) { rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager.draw(mdl::OBJ_TYPE_OPAQUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSPARENT); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSLUCENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; uniform_value[U0A] = 0; - draw_pass_shadow_filter(rctx, &rctx->litproj->shadow_texture[0], + draw_pass_shadow_filter(&rctx->litproj->shadow_texture[0], &rctx->litproj->shadow_texture[1], 0, 1.5f, 0.01f, true); - if (draw_pass_shadow_litproj(rctx, rctx->litproj)) { - draw_pass_set_camera(rctx); + if (draw_pass_shadow_litproj(rctx->litproj)) { + draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rctx->face, (light_set_id)i); rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager.draw(mdl::OBJ_TYPE_OPAQUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSPARENT); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_state_enable_blend(); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSLUCENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); gl_state_disable_blend(); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; gl_state_bind_framebuffer(0); } } @@ -200,7 +412,7 @@ namespace rndr { bool v3 = false; int32_t v10[2]; for (int32_t i = 0; i < 2; i++) { - v10[i] = rctx->disp_manager.get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + i)); + v10[i] = rctx->disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + i)); if (v10[i]) v3 = true; } @@ -213,20 +425,19 @@ 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]; - shad->curr_render_textures[3] = &shad->render_textures[7]; // Extra for buf for (int32_t i = 0, j = 0; i < 2; i++) { if (!v10[i]) continue; - draw_pass_shadow_begin_make_shadowmap(rctx, shad, v11[i], j); - rctx->disp_manager.draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + v11[i])); - if (rctx->disp_manager.get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + v11[i])) > 0) { + draw_pass_shadow_begin_make_shadowmap(shad, v11[i], j); + rctx->disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + v11[i])); + if (rctx->disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + v11[i])) > 0) { gl_state_set_color_mask(field_2F8 ? GL_TRUE : GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - rctx->disp_manager.draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + i)); + rctx->disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + i)); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } - draw_pass_shadow_end_make_shadowmap(rctx, shad, v11[i], j); + draw_pass_shadow_end_make_shadowmap(shad, v11[i], j); j++; } } @@ -234,7 +445,6 @@ 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]; - shad->curr_render_textures[3] = &shad->render_textures[7]; // Extra for buf for (int32_t i = 1; i < 3; i++) for (int32_t j = 0; j < 4; j++) { @@ -243,24 +453,26 @@ namespace rndr { glClear(GL_COLOR_BUFFER_BIT); } } + shader::unbind(); gl_state_bind_framebuffer(0); gl_state_end_event(); } - void RenderManager::pass_ss_sss(render_context* rctx) { - ::sss_data* sss = &sss_data; - if (!sss->init || !sss->enable) + void RenderManager::pass_ss_sss() { + render_context* rctx = rctx_ptr; + ::sss_data* sss = rctx->sss_data; + if (!sss->init_data || !sss->enable) return; gl_state_begin_event("pass_ss_sss"); rctx->camera->update_data(); - post_process* pp = &rctx->post_process; - //if (pp->render_width > 1280.0) + rndr::Render* rend = render; + //if (rend->render_width > 1280.0) // sss->npr_contour = false; //if (sss->npr_contour) { - pp->rend_texture.Bind(); - pp->rend_texture.SetViewport(); + rend->rend_texture[0].Bind(); + rend->rend_texture[0].SetViewport(); //} //else { // sss->textures[0].Bind(); @@ -270,7 +482,7 @@ namespace rndr { glClearColor(sss->param.x, sss->param.y, sss->param.z, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_pass_set_camera(rctx); + draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rctx->face, (light_set_id)i); @@ -281,36 +493,36 @@ namespace rndr { rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->draw_state.shader_index = SHADER_FT_SSS_SKIN; + rctx->draw_state->shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_SSS); + rctx->disp_manager->draw(mdl::OBJ_TYPE_SSS); gl_state_disable_depth_test(); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; draw_pass_3d_shadow_reset(rctx); uniform_value[U_NPR] = 0; if (npr_param == 1) { if (sss->enable && sss->npr_contour) { uniform_value[U_NPR] = 1; - draw_pass_sss_contour(rctx, pp); + draw_pass_sss_contour(rctx, rend); } else if (npr) { rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - pp->rend_texture.Bind(); - pp->rend_texture.SetViewport(); + rend->rend_texture[0].Bind(); + rend->rend_texture[0].SetViewport(); glClear(GL_DEPTH_BUFFER_BIT); - rctx->draw_state.shader_index = SHADER_FT_SSS_SKIN; + rctx->draw_state->shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_SSS); + rctx->disp_manager->draw(mdl::OBJ_TYPE_SSS); gl_state_disable_depth_test(); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; gl_state_bind_framebuffer(0); uniform_value[U_NPR] = 1; - draw_pass_sss_contour(rctx, pp); + draw_pass_sss_contour(rctx, rend); } } @@ -333,8 +545,9 @@ namespace rndr { shaders_ft.set(SHADER_FT_IMGFILT); rctx->filter_scene_ubo.Bind(0); rctx->imgfilter_batch_ubo.Bind(1); - gl_state_active_bind_texture_2d(0, pp->rend_texture.GetColorTex()); - RenderTexture::DrawCustom(); + gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); } draw_pass_sss_filter(rctx, sss); @@ -342,20 +555,21 @@ namespace rndr { gl_state_end_event(); } - void RenderManager::pass_reflect(render_context* rctx) { + void RenderManager::pass_reflect() { + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_reflect"); - RenderTexture& refl_tex = rctx->render_manager.get_render_texture(0); - RenderTexture& refl_buf_tex = rctx->render_manager.get_render_texture(11); + RenderTexture& refl_tex = rctx->render_manager->get_render_texture(0); + RenderTexture& refl_buf_tex = rctx->reflect_buffer; refl_tex.Bind(); - if (rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSPARENT) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT)) { + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSPARENT) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT)) { refl_tex.SetViewport(); - draw_pass_set_camera(rctx); + draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rctx->face, (light_set_id)i); @@ -367,7 +581,7 @@ namespace rndr { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - rctx->draw_state.shader_index = SHADER_FT_S_REFL; + rctx->draw_state->shader_index = SHADER_FT_S_REFL; light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; light_clip_plane clip_plane; @@ -378,41 +592,30 @@ namespace rndr { gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFLECT_OPAQUE, 0, field_31D); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE, 0, field_31D); if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { gl_state_enable_blend(); gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_state_set_blend_equation(GL_FUNC_ADD); - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); gl_state_disable_blend(); } if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { uniform_value[U_REFLECT] = field_31E; uniform_value[U_CLIP_PLANE] = clip_plane.data[0]; - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE); } gl_state_disable_depth_test(); uniform_value[U_REFLECT] = 0; - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; - for (int32_t i = reflect_blur_num, j = 0; i > 0; i--, j++) - if (j % 2) { - refl_tex.Bind(); - blur_filter_apply(rctx, refl_tex.GetColorTex(), - refl_buf_tex.GetColorTex(), reflect_blur_filter, 1.0f, 1.0f, 0.0f); - } - else { - refl_buf_tex.Bind(); - blur_filter_apply(rctx, refl_buf_tex.GetColorTex(), - refl_tex.GetColorTex(), reflect_blur_filter, 1.0f, 1.0f, 0.0f); - } - - if (reflect_blur_num % 2) - fbo::blit(refl_buf_tex.fbos[0], refl_tex.fbos[0], - 0, 0, refl_buf_tex.GetWidth(), refl_buf_tex.GetHeight(), - 0, 0, refl_tex.GetWidth(), refl_tex.GetHeight(), - GL_COLOR_BUFFER_BIT, GL_LINEAR); + refl_buf_tex.Bind(); + for (int32_t i = reflect_blur_num, j = 0; i > 0; i--, j++) { + blur_filter_apply(rctx, &refl_buf_tex, &refl_tex, + reflect_blur_filter, 1.0f, 1.0f, 0.0f); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, refl_tex.GetWidth(), refl_tex.GetHeight()); + } } else { vec4 clear_color; @@ -421,21 +624,23 @@ namespace rndr { glClear(GL_COLOR_BUFFER_BIT); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } + shader::unbind(); gl_state_bind_framebuffer(0); gl_state_end_event(); } - void RenderManager::pass_refract(render_context* rctx) { + void RenderManager::pass_refract() { + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_refract"); - RenderTexture& refract_texture = rctx->render_manager.get_render_texture(1); + RenderTexture& refract_texture = rctx->render_manager->get_render_texture(1); refract_texture.Bind(); - if (rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFRACT_OPAQUE) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSPARENT) - || rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT)) { + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_OPAQUE) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSPARENT) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT)) { texture* refr_tex = refract_texture.color_texture; glViewport(0, 0, refr_tex->width, refr_tex->height); - draw_pass_set_camera(rctx); + draw_pass_set_camera(); for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rctx->face, (light_set_id)i); @@ -450,15 +655,15 @@ namespace rndr { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - rctx->draw_state.shader_index = SHADER_FT_S_REFR; + rctx->draw_state->shader_index = SHADER_FT_S_REFR; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFRACT_OPAQUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFRACT_TRANSPARENT); - rctx->disp_manager.draw(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFRACT_OPAQUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSPARENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT); gl_state_disable_depth_test(); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; } else { vec4 clear_color; @@ -467,30 +672,35 @@ namespace rndr { glClear(GL_COLOR_BUFFER_BIT); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); } + shader::unbind(); gl_state_bind_framebuffer(0); gl_state_end_event(); } - void RenderManager::pass_pre_process(render_context* rctx) { + void RenderManager::pass_pre_process() { gl_state_begin_event("pass_pre_process"); for (draw_pre_process& i : pre_process) if (i.func) i.func(i.data); + shader::unbind(); + gl_state_bind_framebuffer(0); gl_state_end_event(); } - void RenderManager::pass_clear(render_context* rctx) { + void RenderManager::pass_clear() { + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_clear"); - if (clear) { - vec4 clear_color = get_clear_color(); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rctx->screen_buffer.Bind(); + clear_color_set_gl(); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); + gl_state_bind_framebuffer(0); } - post_process* pp = &rctx->post_process; - if (!sss_data.enable || !sss_data.npr_contour) { - pp->set_render_texture(); + rndr::Render* rend = render; + if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour) { + rend->bind_render_texture(); if (sprite_manager_get_reqlist_count(2)) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepthf(1.0f); @@ -498,8 +708,7 @@ namespace rndr { gl_state_bind_framebuffer(0); } else { - vec4 clear_color = get_clear_color(); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + clear_color_set_gl(); glClearDepthf(1.0f); if (clear) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -509,15 +718,15 @@ namespace rndr { } } else { - pp->set_render_texture(); if (sprite_manager_get_reqlist_count(2)) { + rend->bind_render_texture(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); gl_state_bind_framebuffer(0); } else if (clear) { - vec4 clear_color = get_clear_color(); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + rend->bind_render_texture(); + clear_color_set_gl(); glClear(GL_COLOR_BUFFER_BIT); gl_state_bind_framebuffer(0); } @@ -527,36 +736,41 @@ namespace rndr { gl_state_end_event(); } - void RenderManager::pass_pre_sprite(render_context* rctx) { + void RenderManager::pass_pre_sprite() { if (!sprite_manager_get_reqlist_count(2)) return; + render_context* rctx = rctx_ptr; + gl_state_begin_event("pass_pre_sprite"); - post_process* pp = &rctx->post_process; - pp->set_render_texture(true); + rndr::Render* rend = render; + rend->bind_render_texture(true); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); gl_state_set_depth_mask(GL_FALSE); gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - sprite_manager_draw(rctx, 2, true, - pp->temp_buffer.color_texture, + sprite_manager_draw(2, true, + rend->temp_buffer.color_texture, rctx->camera->view_projection_aet_3d); gl_state_enable_cull_face(); gl_state_disable_blend(); gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); + shader::unbind(); gl_state_bind_framebuffer(0); gl_state_get_error(); gl_state_end_event(); } - void RenderManager::pass_3d(render_context* rctx) { + void RenderManager::pass_3d() { + render_context* rctx = rctx_ptr; rctx->camera->update_data(); - rctx->post_process.set_render_texture(); - draw_pass_set_camera(rctx); - if (!sss_data.enable || !sss_data.npr_contour || draw_pass_3d_get_translucent_count(rctx)) + render->bind_render_texture(); + draw_pass_set_camera(); + if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour + || draw_pass_3d_get_translucent_count(rctx)) glClear(GL_DEPTH_BUFFER_BIT); gl_state_set_depth_func(GL_LEQUAL); @@ -590,25 +804,25 @@ namespace rndr { else gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d); - gl_state_active_bind_texture_2d(16, sss_data.textures[1].GetColorTex()); + gl_state_active_bind_texture_2d(16, rctx->sss_data->textures[1].GetColorTex()); gl_state_active_texture(0); if (alpha_z_sort) { - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, 1); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, 1); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, 1); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, 1); } if (opaque_z_sort) - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); if (draw_pass_3d[DRAW_PASS_3D_OPAQUE]) { gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_OPAQUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); gl_state_disable_depth_test(); } @@ -623,16 +837,16 @@ namespace rndr { gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSPARENT); - /*if (rctx->render_manager.field_120) - rctx->disp_manager.draw(mdl::OBJ_TYPE_TYPE_7);*/ + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + if (rctx->render_manager->field_120) + rctx->disp_manager->draw(mdl::OBJ_TYPE_TYPE_7); - rctx->post_process.exposure->get_exposure_chara_data(&rctx->post_process, rctx->camera); + render->get_exposure_chara_data(rctx->camera); if (npr_param == 1) - pass_3d_contour(rctx); + pass_3d_contour(); - rctx->post_process.draw_lens_flare(rctx->camera); + render->draw_lens_flare(rctx->camera); star_catalog_draw(); draw_pass_3d_translucent(rctx, @@ -666,8 +880,8 @@ namespace rndr { gl_state_enable_blend(); gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_state_set_depth_mask(GL_FALSE); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSLUCENT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); gl_state_disable_blend(); } @@ -704,14 +918,14 @@ namespace rndr { camera* cam = rctx->camera; double_t fov = cam->get_fov(); cam->set_fov(32.2673416137695); - draw_pass_set_camera(rctx); + draw_pass_set_camera(); rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager.draw(mdl::OBJ_TYPE_OPAQUE_LOCAL); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSPARENT_LOCAL); + rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE_LOCAL); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT_LOCAL); gl_state_enable_blend(); - rctx->disp_manager.draw(mdl::OBJ_TYPE_TRANSLUCENT_LOCAL); + rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT_LOCAL); gl_state_disable_blend(); draw_pass_3d_translucent(rctx, @@ -726,7 +940,7 @@ namespace rndr { Glitter::glt_particle_manager->DispScenes(Glitter::DISP_LOCAL); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); cam->set_fov(fov); - draw_pass_set_camera(rctx); + draw_pass_set_camera(); } #endif @@ -737,32 +951,33 @@ namespace rndr { if (shadow) draw_pass_3d_shadow_reset(rctx); + pass_sprite_surf(); shader::unbind(); - pass_sprite_surf(rctx); gl_state_bind_framebuffer(0); } - void RenderManager::pass_show_vector(render_context* rctx) { + void RenderManager::pass_show_vector() { return; /*if (!show_vector_flags) return; + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_show_vector"); rctx->camera->update_data(); rctx->view_mat = rctx->camera->view; - rctx->post_process.set_render_texture(); - draw_pass_set_camera(rctx); + render->bind_render_texture(); + draw_pass_set_camera(); rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); if (alpha_z_sort) { - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); } if (opaque_z_sort) - rctx->disp_manager.obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); //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++) { @@ -778,10 +993,13 @@ namespace rndr { draw_task_draw_objects_by_type_show_vector(rctx, mdl::OBJ_TYPE_TRANSLUCENT, i); } } + shader::unbind(); + gl_state_bind_framebuffer(0); gl_state_end_event();*/ } - void RenderManager::pass_post_process(render_context* rctx) { + void RenderManager::pass_post_process() { + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_post_process"); rctx->camera->update_data(); @@ -794,17 +1012,18 @@ namespace rndr { light_proj_tex = litproj->draw_texture.color_texture; } - rctx->post_process.apply(rctx->camera, light_proj_tex, npr_param); + render->apply_post_process(rctx->camera, light_proj_tex, npr_param); gl_state_end_event(); } - void RenderManager::pass_sprite(render_context* rctx) { + void RenderManager::pass_sprite() { + render_context* rctx = rctx_ptr; if (!sprite_manager_get_reqlist_count(0)) return; gl_state_begin_event("pass_sprite"); - post_process* pp = &rctx->post_process; - glViewport(0, 0, pp->sprite_width, pp->sprite_height); + rndr::Render* rend = render; + glViewport(0, 0, width, height); if (multisample && multisample_framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); @@ -813,13 +1032,13 @@ namespace rndr { glClear(GL_COLOR_BUFFER_BIT); } else - rctx->post_process.screen_texture.Bind(); + rctx->screen_buffer.Bind(); gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - sprite_manager_draw(rctx, 0, true, - pp->temp_buffer.color_texture, + sprite_manager_draw(0, true, + rend->temp_buffer.color_texture, rctx->camera->view_projection_aet_2d); gl_state_enable_cull_face(); gl_state_disable_blend(); @@ -829,17 +1048,19 @@ namespace rndr { glBindFramebuffer(GL_FRAMEBUFFER, 0); gl_state_disable_multisample(); gl_state_bind_read_framebuffer(multisample_framebuffer); - glBlitFramebuffer(0, 0, pp->sprite_width, pp->sprite_height, - 0, 0, pp->sprite_width, pp->sprite_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, width, height, + 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); gl_state_bind_read_framebuffer(0); } gl_state_get_error(); + gl_state_bind_framebuffer(0); gl_state_end_event(); } - void RenderManager::pass_3d_contour(render_context* rctx) { - RenderTexture* rt = &rctx->post_process.rend_texture; - RenderTexture* contour_rt = rctx->post_process.sss_contour_texture; + void RenderManager::pass_3d_contour() { + render_context* rctx = rctx_ptr; + RenderTexture* rt = &render->rend_texture[0]; + RenderTexture* contour_rt = render->sss_contour_texture; gl_state_enable_blend(); gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -856,14 +1077,15 @@ namespace rndr { shaders_ft.set(SHADER_FT_CONTOUR_NPR); gl_state_active_bind_texture_2d(16, contour_rt->GetColorTex()); - gl_state_bind_sampler(16, rctx->post_process.samplers[1]); + gl_state_bind_sampler(16, rctx->render_samplers[1]); gl_state_active_bind_texture_2d(17, contour_rt->GetDepthTex()); - gl_state_bind_sampler(17, rctx->post_process.samplers[1]); + gl_state_bind_sampler(17, rctx->render_samplers[1]); gl_state_active_bind_texture_2d(14, rt->GetDepthTex()); - gl_state_bind_sampler(14, rctx->post_process.samplers[1]); + gl_state_bind_sampler(14, rctx->render_samplers[1]); rctx->quad_ubo.Bind(0); rctx->contour_params_ubo.Bind(2); - RenderTexture::Draw(&shaders_ft); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); if (effect_texture) gl_state_active_bind_texture_2d(14, effect_texture->tex); @@ -873,27 +1095,29 @@ namespace rndr { gl_state_disable_blend(); } - void RenderManager::pass_sprite_surf(render_context* rctx) { + void RenderManager::pass_sprite_surf() { if (!sprite_manager_get_reqlist_count(1)) return; - post_process* pp = &rctx->post_process; + render_context* rctx = rctx_ptr; + rndr::Render* rend = render; gl_state_set_depth_mask(GL_FALSE); gl_state_disable_depth_test(); - gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - sprite_manager_draw(rctx, 1, true, - pp->temp_buffer.color_texture, + sprite_manager_draw(1, true, + rend->temp_buffer.color_texture, rctx->camera->view_projection_aet_2d); } } -void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4 scale) { +void image_filter_scale(GLuint dst, GLuint src, const vec4 scale) { if (!dst || !src) return; + render_context* rctx = rctx_ptr; + texture_param tex_params[2]; texture_params_get(dst, &tex_params[0], src, &tex_params[1]); @@ -913,12 +1137,14 @@ void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4 rctx->filter_scene_ubo.Bind(0); rctx->imgfilter_batch_ubo.Bind(1); gl_state_active_bind_texture_2d(0, src); - RenderTexture::DrawCustom(); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); texture_params_restore(&tex_params[0], &tex_params[1]); } -void draw_pass_set_camera(render_context* rctx) { +void draw_pass_set_camera() { + render_context* rctx = rctx_ptr; camera* cam = rctx->camera; cam->update_data(); rctx->view_mat = cam->view; @@ -934,8 +1160,44 @@ void draw_pass_set_camera(render_context* rctx) { }; } -static void draw_pass_shadow_begin_make_shadowmap(render_context* rctx, - Shadow* shad, int32_t index, int32_t a3) { +void render_manager_init_data(int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask, bool npr) { + rndr::RenderManager& render_manager = *rctx_ptr->render_manager; + + render_manager.reset(); + render_manager.npr = npr; + render_texture_counter_reset(); + + resolution_struct* res_wind = res_window_get(); + resolution_struct* res_wind_int = res_window_internal_get(); + render_manager.render = &rctx_ptr->render; + render_manager.render->init_render_buffers(res_wind_int->width, + res_wind_int->height, ssaa, hd_res, ss_alpha_mask); + render_manager.render->set_screen_res(res_wind_int->x_offset, + res_wind_int->y_offset, res_wind_int->width, res_wind_int->height); + 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(); + + shadow_ptr_init(); + render_manager.shadow_ptr = shadow_ptr_get(); + render_manager.shadow_ptr->Init(); + + rctx_ptr->sss_data->init(); + gl_state_get_error(); +} + +void render_manager_free_data() { + rndr::RenderManager& render_manager = *rctx_ptr->render_manager; + + render_manager_free_render_textures(); + render_manager.render->free(); + shadow_ptr_free(); + rctx_ptr->sss_data->free(); +} + +static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { + render_context* rctx = rctx_ptr; shad->curr_render_textures[0]->Bind(); shad->curr_render_textures[0]->SetViewport(); texture* tex = shad->curr_render_textures[0]->color_texture; @@ -974,50 +1236,40 @@ static void draw_pass_shadow_begin_make_shadowmap(render_context* rctx, mat4_mul(&proj, &temp, &rctx->proj_mat); mat4_look_at(view_point, interest, &rctx->view_mat); - rctx->draw_state.shader_index = SHADER_FT_SIL; + rctx->draw_state->shader_index = SHADER_FT_SIL; uniform_value[U0A] = 0; } -static void draw_pass_shadow_end_make_shadowmap(render_context* rctx, - Shadow* shad, int32_t index, int32_t a3) { +static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { + render_context* rctx = rctx_ptr; gl_state_disable_depth_test(); gl_state_disable_scissor_test(); - rctx->draw_state.shader_index = -1; + rctx->draw_state->shader_index = -1; if (a3 == shad->field_2EC - 1) { - draw_pass_shadow_filter(rctx, &shad->render_textures[3], + draw_pass_shadow_filter(&shad->render_textures[3], &shad->render_textures[4], shad->curr_render_textures[0], shad->field_2DC, shad->field_2E0 / (shad->field_208 * 2.0f), false); - draw_pass_shadow_esm_filter(rctx, &shad->render_textures[5], + draw_pass_shadow_esm_filter(&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 = shad->curr_render_textures[3]; + RenderTexture& rend_buf_tex = rctx_ptr->shadow_buffer; rend_tex->Bind(); - image_filter_scale(rctx, rend_tex->GetColorTex(), + image_filter_scale(rend_tex->GetColorTex(), shad->curr_render_textures[0]->GetColorTex(), 1.0f); + rend_buf_tex.Bind(); if (shad->blur_filter_enable[index]) { - for (int32_t i = shad->near_blur, j = 0; i > 0; i--, j++) - if (j % 2) { - rend_tex->Bind(); - blur_filter_apply(rctx, rend_tex->GetColorTex(), - rend_buf_tex->GetColorTex(), shad->blur_filter, 1.0f, 1.0f, 0.0f); - } - else { - rend_buf_tex->Bind(); - blur_filter_apply(rctx, rend_buf_tex->GetColorTex(), - rend_tex->GetColorTex(), shad->blur_filter, 1.0f, 1.0f, 0.0f); - } - - if (shad->near_blur % 2) - image_filter_scale(rctx, rend_buf_tex->GetColorTex(), - rend_tex->GetColorTex(), 1.0f); + for (int32_t i = shad->near_blur, j = 0; i > 0; i--, j++) { + blur_filter_apply(rctx, &rend_buf_tex, rend_tex, + shad->blur_filter, 1.0f, 1.0f, 0.0f); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, rend_buf_tex.GetWidth(), rend_buf_tex.GetHeight()); + } } else { - rend_tex->Bind(); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); } @@ -1028,7 +1280,7 @@ static void draw_pass_shadow_end_make_shadowmap(render_context* rctx, gl_state_bind_texture_2d(0); } -static void draw_pass_shadow_filter(render_context* rctx, RenderTexture* a1, RenderTexture* a2, +static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, RenderTexture* a3, float_t sigma, float_t far_texel_offset, bool enable_lit_proj) { GLuint v7 = a1->GetColorTex(); GLuint v9 = a2->GetColorTex(); @@ -1045,6 +1297,8 @@ static void draw_pass_shadow_filter(render_context* rctx, RenderTexture* a1, Ren || tex_params[0].height != tex_params[1].height) return; + render_context* rctx = rctx_ptr; + filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = 0.0f; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; @@ -1075,7 +1329,8 @@ static void draw_pass_shadow_filter(render_context* rctx, RenderTexture* a1, Ren GLint swizzle[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); } - RenderTexture::DrawCustom(); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); a1->Bind(); @@ -1083,20 +1338,22 @@ static void draw_pass_shadow_filter(render_context* rctx, RenderTexture* a1, Ren rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); gl_state_active_bind_texture_2d(0, v9); - RenderTexture::DrawCustom(); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); shader::unbind(); texture_params_restore(&tex_params[0], &tex_params[1]); } -static void draw_pass_shadow_esm_filter(render_context* rctx, - RenderTexture* dst, RenderTexture* buf, RenderTexture* src) { +static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src) { GLuint dst_tex = dst->GetColorTex(); GLuint buf_tex = buf->GetColorTex(); GLuint src_tex = src->GetColorTex(); if (!dst_tex || !buf_tex || !src_tex) return; + render_context* rctx = rctx_ptr; + filter_scene_shader_data filter_scene = {}; filter_scene.g_transform = 0.0f; filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; @@ -1120,7 +1377,8 @@ static void draw_pass_shadow_esm_filter(render_context* rctx, uniform_value[U_ESM_FILTER] = 0; shaders_ft.set(SHADER_FT_ESMFILT); gl_state_active_bind_texture_2d(0, src_tex); - RenderTexture::Draw(&shaders_ft); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); dst->Bind(); esm_filter_batch.g_params = { 0.75f / (float_t)tex_params[2].width, @@ -1130,12 +1388,13 @@ static void draw_pass_shadow_esm_filter(render_context* rctx, uniform_value[U_ESM_FILTER] = 1; shaders_ft.set(SHADER_FT_ESMFILT); gl_state_active_bind_texture_2d(0, buf_tex); - RenderTexture::Draw(&shaders_ft); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); texture_params_restore(&tex_params[0], &tex_params[1], &tex_params[2]); } -static bool draw_pass_shadow_litproj(render_context* rctx, light_proj* litproj) { +static bool draw_pass_shadow_litproj(light_proj* litproj) { if (!litproj) return false; @@ -1150,31 +1409,32 @@ static bool draw_pass_shadow_litproj(render_context* rctx, light_proj* litproj) glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (!light_proj::set_mat(rctx, 0)) { + if (!light_proj::set_mat(false)) { gl_state_bind_framebuffer(0); return false; } - rctx->draw_state.shader_index = SHADER_FT_LITPROJ; + render_context* rctx = rctx_ptr; + rctx->draw_state->shader_index = SHADER_FT_LITPROJ; gl_state_active_bind_texture_2d(17, tex->tex); - gl_state_bind_sampler(17, rctx->post_process.samplers[2]); + gl_state_bind_sampler(17, rctx->render_samplers[2]); gl_state_active_bind_texture_2d(18, litproj->shadow_texture[0].GetColorTex()); - gl_state_bind_sampler(18, rctx->post_process.samplers[2]); + gl_state_bind_sampler(18, rctx->render_samplers[2]); gl_state_active_texture(0); return true; } -static void draw_pass_sss_contour(render_context* rctx, post_process* pp) { - pp->sss_contour_texture->Bind(); - pp->sss_contour_texture->SetViewport(); +static void draw_pass_sss_contour(render_context* rctx, rndr::Render* rend) { + rend->sss_contour_texture->Bind(); + rend->sss_contour_texture->SetViewport(); gl_state_enable_depth_test(); gl_state_set_depth_func(GL_ALWAYS); gl_state_set_depth_mask(GL_TRUE); - glViewport(0, 0, pp->render_width, pp->render_height); - gl_state_active_bind_texture_2d(0, pp->rend_texture.GetColorTex()); - gl_state_bind_sampler(0, rctx->post_process.samplers[1]); - gl_state_active_bind_texture_2d(1, pp->rend_texture.GetDepthTex()); - gl_state_bind_sampler(1, rctx->post_process.samplers[1]); + glViewport(0, 0, rend->render_width[0], rend->render_height[0]); + gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + gl_state_active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex()); + gl_state_bind_sampler(1, rctx->render_samplers[1]); gl_state_active_texture(0); camera* cam = rctx->camera; @@ -1197,8 +1457,10 @@ static void draw_pass_sss_contour(render_context* rctx, post_process* pp) { shaders_ft.set(SHADER_FT_CONTOUR); rctx->contour_coef_ubo.Bind(2); - RenderTexture::DrawQuad(&shaders_ft, pp->render_width, pp->render_height, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + rctx->render.draw_quad( + 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); } static void draw_pass_sss_filter_calc_coef(double_t a1, size_t a2, double_t a3, size_t a4, @@ -1302,20 +1564,20 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss) { if (sss->npr_contour) { sss->textures[0].Bind(); glViewport(0, 0, 640, 360); - post_process* pp = &rctx->post_process; + rndr::Render* rend = &rctx->render; uniform_value[U_REDUCE] = 0; shaders_ft.set(SHADER_FT_REDUCE); - gl_state_bind_texture_2d(pp->rend_texture.GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, 640, 360, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); + gl_state_bind_texture_2d(rend->rend_texture[0].GetColorTex()); + rctx->render.draw_quad(640, 360, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); } sss->textures[2].Bind(); glViewport(0, 0, 320, 180); uniform_value[U_SSS_FILTER] = 0; shaders_ft.set(SHADER_FT_SSS_FILT); gl_state_bind_texture_2d(sss->textures[0].GetColorTex()); - RenderTexture::DrawQuad(&shaders_ft, 640, 360, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); + rctx->render.draw_quad(640, 360, 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 = {}; shader_data.g_param = { (float_t)(sss_count - 1), 0.0f, 1.0f, 1.0f }; @@ -1333,25 +1595,25 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss) { shaders_ft.set(SHADER_FT_SSS_FILT); gl_state_bind_texture_2d(sss->textures[2].GetColorTex()); rctx->sss_filter_gaussian_coef_ubo.Bind(1); - RenderTexture::DrawQuad(&shaders_ft, 320, 180, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.96f, 1.0f, 0.0f); + rctx->render.draw_quad(320, 180, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.96f, 1.0f, 0.0f); gl_state_bind_texture_2d(0); } static int32_t draw_pass_3d_get_translucent_count(render_context* rctx) { int32_t count = 0; - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_3); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL); - count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_3); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL); + count += rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL); return count; } @@ -1360,8 +1622,8 @@ static void draw_pass_3d_shadow_reset(render_context* rctx) { gl_state_active_bind_texture_2d(7, 0); rctx->obj_scene.set_g_self_shadow_receivers(0, mat4_identity); rctx->obj_scene.set_g_self_shadow_receivers(1, mat4_identity); - rctx->draw_state.self_shadow = false; - rctx->draw_state.light = false; + rctx->draw_state->self_shadow = false; + rctx->draw_state->light = false; } static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { @@ -1371,17 +1633,17 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { gl_state_active_texture(0); float_t esm_param = (shad->field_2D8 * shad->field_208 * 2.0f) * 1.442695f; rctx->obj_scene.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f }; - rctx->draw_state.self_shadow = true; + rctx->draw_state->self_shadow = true; } else { gl_state_active_bind_texture_2d(19, rctx->empty_texture_2d); gl_state_active_bind_texture_2d(20, rctx->empty_texture_2d); gl_state_active_texture(0); - rctx->draw_state.self_shadow = false; + rctx->draw_state->self_shadow = false; } if (shad->field_2EC > 0) { - rctx->draw_state.light = true; + rctx->draw_state->light = true; uniform_value[U_LIGHT_1] = shad->field_2EC > 1 ? 1 : 0; float_t range = shad->view_region * shad->range; @@ -1443,7 +1705,7 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { rctx->obj_scene.g_shadow_ambient1 = { 1.0f - ambient.x, 1.0f - ambient.y, 1.0f - ambient.z, 0.0f }; } else { - rctx->draw_state.light = false; + rctx->draw_state->light = false; for (int32_t i = 0; i < 2; i++) gl_state_active_bind_texture_2d(6 + i, shad->curr_render_textures[1 + i]->GetColorTex()); @@ -1457,30 +1719,29 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { static void draw_pass_3d_translucent(render_context* rctx, bool opaque_enable, bool transparent_enable, bool translucent_enable, mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent) { - if (rctx->disp_manager.get_obj_count(opaque) < 1 - && rctx->disp_manager.get_obj_count(transparent) < 1 - && rctx->disp_manager.get_obj_count(translucent) < 1) + if (rctx->disp_manager->get_obj_count(opaque) < 1 + && rctx->disp_manager->get_obj_count(transparent) < 1 + && rctx->disp_manager->get_obj_count(translucent) < 1) return; - post_process* pp = &rctx->post_process; + rndr::Render* rend = &rctx->render; int32_t alpha_array[256]; int32_t count = draw_pass_3d_translucent_count_layers(rctx, alpha_array, opaque, transparent, translucent); for (int32_t i = 0; i < count; i++) { int32_t alpha = alpha_array[i]; - pp->transparency->copy(&pp->rend_texture); - if (opaque_enable && rctx->disp_manager.get_obj_count(opaque)) - rctx->disp_manager.draw_translucent(opaque, alpha); - if (transparent_enable && rctx->disp_manager.get_obj_count(transparent)) - rctx->disp_manager.draw_translucent(transparent, alpha); - if (translucent_enable && rctx->disp_manager.get_obj_count(translucent)) { + rend->transparency_copy(); + if (opaque_enable && rctx->disp_manager->get_obj_count(opaque)) + rctx->disp_manager->draw_translucent(opaque, alpha); + if (transparent_enable && rctx->disp_manager->get_obj_count(transparent)) + rctx->disp_manager->draw_translucent(transparent, alpha); + if (translucent_enable && rctx->disp_manager->get_obj_count(translucent)) { gl_state_enable_blend(); - rctx->disp_manager.draw_translucent(translucent, alpha); + rctx->disp_manager->draw_translucent(translucent, alpha); gl_state_disable_blend(); } - pp->transparency->combine(&pp->rend_texture, &pp->buf_texture, - (float_t)alpha * (float_t)(1.0 / 255.0), rctx); + rend->transparency_combine((float_t)alpha * (float_t)(1.0 / 255.0)); } } @@ -1503,7 +1764,7 @@ static int32_t draw_pass_3d_translucent_count_layers(render_context* rctx, } static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr, mdl::ObjType type) { - std::vector& vec = rctx->disp_manager.obj[type]; + std::vector& vec = rctx->disp_manager->obj[type]; for (mdl::ObjData*& i : vec) switch (i->kind) { case mdl::OBJ_KIND_NORMAL: { @@ -1521,17 +1782,14 @@ static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr } } -static void blur_filter_apply(render_context* rctx, GLuint dst, GLuint src, +static void blur_filter_apply(render_context* rctx, RenderTexture* dst, RenderTexture* src, blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset) { if (!dst || !src) return; - texture_param tex_params[2]; - texture_params_get(dst, &tex_params[0], src, &tex_params[1]); - filter_scene_shader_data filter_scene = {}; - float_t w = res_scale.x / (float_t)tex_params[1].width; - float_t h = res_scale.y / (float_t)tex_params[1].height; + 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); @@ -1550,8 +1808,64 @@ static void blur_filter_apply(render_context* rctx, GLuint dst, GLuint src, shaders_ft.set(SHADER_FT_IMGFILT); rctx->filter_scene_ubo.Bind(0); rctx->imgfilter_batch_ubo.Bind(1); - gl_state_active_bind_texture_2d(0, src); - glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4); + gl_state_active_bind_texture_2d(0, src->GetColorTex()); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4); +} - texture_params_restore(&tex_params[0], &tex_params[1]); +static void render_manager_free_render_textures() { + rndr::RenderManager& render_manager = *rctx_ptr->render_manager; + + if (render_manager.multisample_renderbuffer) { + glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer); + render_manager.multisample_renderbuffer = 0; + } + + if (render_manager.multisample_framebuffer) { + glDeleteFramebuffers(1, &render_manager.multisample_framebuffer); + render_manager.multisample_framebuffer = 0; + } + + for (RenderTexture& i : render_manager.render_textures) + i.Free(); +} + +static void render_manager_init_render_textures(int32_t multisample) { + rndr::RenderManager& render_manager = *rctx_ptr->render_manager; + + if (multisample) { + glGenFramebuffers(1, &render_manager.multisample_framebuffer); + glGenRenderbuffers(1, &render_manager.multisample_renderbuffer); + + 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); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, render_manager.multisample_renderbuffer); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + gl_state_bind_framebuffer(0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + if (glGetError()) { + glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer); + render_manager.multisample_renderbuffer = 0; + glDeleteFramebuffers(1, &render_manager.multisample_framebuffer); + render_manager.multisample_framebuffer = 0; + } + } + + for (int32_t i = 0; i < 9; i++) { + const rndr::RenderTextureData* tex_data = &rndr::render_manager_render_texture_data_array[i]; + if (tex_data->type != GL_TEXTURE_2D) + continue; + + 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(); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + gl_state_bind_framebuffer(0); } diff --git a/src/CRE/render_manager.hpp b/src/CRE/render_manager.hpp index 5caa55f6..ce91d502 100644 --- a/src/CRE/render_manager.hpp +++ b/src/CRE/render_manager.hpp @@ -7,9 +7,134 @@ #include "../KKdLib/default.hpp" #include "../KKdLib/vec.hpp" +#include "render.hpp" +#include "shadow.hpp" #include -#include "render_context.hpp" +#include -extern void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4 scale); +enum reflect_refract_resolution_mode { + REFLECT_REFRACT_RESOLUTION_256x256 = 0, + REFLECT_REFRACT_RESOLUTION_512x256, + REFLECT_REFRACT_RESOLUTION_512x512, + REFLECT_REFRACT_RESOLUTION_MAX, +}; -extern void draw_pass_set_camera(render_context* rctx); +struct draw_pre_process { + int32_t type; + void(*func)(void*); + void* data; +}; + +namespace rndr { + enum RenderPassID { + RND_PASSID_SHADOW = 0, + RND_PASSID_SS_SSS, + RND_PASSID_2, + RND_PASSID_REFLECT, + RND_PASSID_REFRACT, + RND_PASSID_PRE_PROCESS, + RND_PASSID_CLEAR, + RND_PASSID_PRE_SPRITE, + RND_PASSID_3D, + RND_PASSID_SHOW_VECTOR, + RND_PASSID_POST_PROCESS, + RND_PASSID_SPRITE, + RND_PASSID_12, + RND_PASSID_NUM, + }; + + struct RenderManager { + bool pass_sw[RND_PASSID_NUM]; + Shadow* shadow_ptr; + bool reflect; + bool refract; + int32_t reflect_blur_num; + blur_filter_mode reflect_blur_filter; + rndr::Render* render; + bool sync_gpu; + double_t cpu_time[RND_PASSID_NUM]; + double_t gpu_time[RND_PASSID_NUM]; + time_struct time; + bool shadow; + bool opaque_z_sort; + bool alpha_z_sort; + bool draw_pass_3d[DRAW_PASS_3D_MAX]; + bool field_11E; + bool field_11F; + bool field_120; + bool show_ref_map; + int32_t reflect_type; // stage_data_reflect_type + bool clear; + int32_t tex_index[11]; + RenderTexture render_textures[8]; + int32_t width; + int32_t height; + GLuint multisample_framebuffer; + GLuint multisample_renderbuffer; + bool multisample; + bool check_state; + int32_t show_vector_flags; + float_t show_vector_length; + float_t show_vector_z_offset; + bool field_2F8; + std::list pre_process; + texture* effect_texture; + int32_t npr_param; + bool field_31C; + bool field_31D; + bool field_31E; + bool field_31F; + bool field_320; + bool npr; + + RenderManager(); + ~RenderManager(); + + void add_pre_process(int32_t type, void(*func)(void*), void* data); + void clear_pre_process(int32_t type); + RenderTexture& get_render_texture(int32_t index); + void reset(); + void resize(int32_t width, int32_t height); + void set_effect_texture(texture* value); + void set_multisample(bool value); + void set_npr_param(int32_t value); + void set_pass_sw(rndr::RenderPassID id, bool value); + void set_reflect(bool value); + void set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter); + void set_reflect_resolution_mode(reflect_refract_resolution_mode mode); + void set_reflect_type(int32_t type); + void set_refract(bool value); + void set_refract_resolution_mode(reflect_refract_resolution_mode mode); + void set_shadow_false(); + void set_shadow_true(); + + void render_all(); + + void render_single_pass(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_3d_contour(); + void pass_sprite_surf(); + }; +} + +extern void image_filter_scale(GLuint dst, GLuint src, const vec4 scale); + +extern void draw_pass_set_camera(); + +extern void render_manager_init_data(int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask, bool npr); +extern void render_manager_free_data(); diff --git a/src/CRE/render_texture.cpp b/src/CRE/render_texture.cpp index 1baeac51..faeccc18 100644 --- a/src/CRE/render_texture.cpp +++ b/src/CRE/render_texture.cpp @@ -8,9 +8,8 @@ #include "render_context.hpp" #include "texture.hpp" -static GLuint render_texture_vao; +extern render_context* rctx_ptr; -static bool render_texture_data_initialized; static uint32_t render_texture_counter; static int32_t render_texture_init_framebuffer(RenderTexture* rt, int32_t max_level); @@ -59,9 +58,10 @@ void RenderTexture::Free() { field_2C = 0; } - if (fbos[0]) { + if (fbos) { glDeleteFramebuffers(max_level + 1, fbos); - memset(fbos, 0, sizeof(fbos)); + free(fbos); + fbos = 0; } max_level = 0; } @@ -129,63 +129,18 @@ int32_t RenderTexture::SetColorDepthTextures(GLuint color_texture, int32_t max_level, GLuint depth_texture, bool stencil) { int32_t error = 0; this->max_level = max_level; - if (!fbos[0]) + if (!fbos) error = render_texture_init_framebuffer(this, max_level); render_texture_set_framebuffer_texture(this, color_texture, max_level, depth_texture, stencil); return error; } -void RenderTexture::Draw(shader_set_data* set) { - gl_state_bind_vertex_array(render_texture_vao); - set->draw_arrays(GL_TRIANGLE_STRIP, 0, 4); -} - -void RenderTexture::DrawCustom() { - gl_state_bind_vertex_array(render_texture_vao); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); -} - -void RenderTexture::DrawQuad(shader_set_data* set, 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) { - extern render_context* rctx_ptr; - - s0 -= s1; - t0 -= t1; - - float_t w = (float_t)max_def(width, 1); - float_t h = (float_t)max_def(height, 1); - quad_shader_data quad = {}; - quad.g_texcoord_modifier = { 0.5f * s0, 0.5f * t0, 0.5f * s0 + s1, 0.5f * t0 + t1 }; // x * 0.5 * y0 + 0.5 * y0 + y1 - quad.g_texel_size = { scale / w, scale / h, w, h }; - quad.g_color = { param_x, param_y, param_z, param_w }; - quad.g_texture_lod = 0.0f; - - rctx_ptr->quad_ubo.WriteMemory(quad); - rctx_ptr->quad_ubo.Bind(0); - gl_state_bind_vertex_array(render_texture_vao); - set->draw_arrays(GL_TRIANGLE_STRIP, 0, 4); -} - -void render_texture_data_init() { - if (render_texture_data_initialized) - return; - - glGenVertexArrays(1, &render_texture_vao); - - render_texture_data_initialized = true; -} - -void render_texture_data_free() { - if (!render_texture_data_initialized) - return; - - glDeleteVertexArrays(1, &render_texture_vao); - - render_texture_data_initialized = false; +void render_texture_counter_reset() { + render_texture_counter = 0; } static int32_t render_texture_init_framebuffer(RenderTexture* rt, int32_t max_level) { + rt->fbos = force_malloc(max_level + 1LL); glGenFramebuffers(max_level + 1, rt->fbos); return -(gl_state_get_error() != GL_ZERO); } diff --git a/src/CRE/render_texture.hpp b/src/CRE/render_texture.hpp index e0fb034b..1d79bf72 100644 --- a/src/CRE/render_texture.hpp +++ b/src/CRE/render_texture.hpp @@ -6,7 +6,6 @@ #pragma once #include "shared.hpp" -#include "shader.hpp" #include "texture.hpp" struct RenderTexture { @@ -14,12 +13,12 @@ struct RenderTexture { texture* depth_texture; int32_t binding; int32_t max_level; - GLuint fbos[16]; + GLuint* fbos; GLuint rbo; GLuint field_2C; RenderTexture(); - ~RenderTexture(); + virtual ~RenderTexture(); int32_t Bind(int32_t index = 0); void Free(); @@ -28,24 +27,18 @@ struct RenderTexture { int32_t SetColorDepthTextures(GLuint color_texture, int32_t max_level = 0, GLuint depth_texture = 0, bool stencil = false); - static void Draw(shader_set_data* set); - static void DrawCustom(); - static void DrawQuad(shader_set_data* set, 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); - inline GLuint GetColorTex() { return color_texture->tex; }; - + inline GLuint GetDepthTex() { return depth_texture->tex; }; - + inline int32_t GetHeight() { return color_texture->height; }; - + inline int32_t GetWidth() { return color_texture->width; }; @@ -55,5 +48,4 @@ struct RenderTexture { }; }; -extern void render_texture_data_init(); -extern void render_texture_data_free(); +extern void render_texture_counter_reset(); diff --git a/src/CRE/renderer/dof.cpp b/src/CRE/renderer/dof.cpp new file mode 100644 index 00000000..e1ce445e --- /dev/null +++ b/src/CRE/renderer/dof.cpp @@ -0,0 +1,436 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "dof.hpp" +#include "../rob/rob.hpp" +#include "../gl_state.hpp" +#include "../shader_ft.hpp" + +struct dof_common_shader_data { + vec4 g_depth_params; //x=(n-f)/(nf), y=1/n, z=coc_from_z_scale, w=coc_from_z_offset + vec4 g_spread_scale; //x=scale_from_meter_to_pixel, y=scale_from_meter_to_sample, + // z=scale_from_pixel_to_sample, w=scale_from_sample_to_pixel + vec4 g_depth_params2; //x=distance_to_focus_m, y=focus_range, + // z=k/(fuzzing_range*fuzzing_range), w=max_coc_radius_in_pixel //yzw=for_f2 +}; + +static const dof_debug dof_debug_default = { + (dof_debug_flags)0, + 10.0f, + 0.04f, + 1.4f, + { + 10.0f, + 1.0f, + 0.5f, + 1.0f, + }, +}; + +static const dof_pv dof_pv_default = { + false, + { + 10.0f, + 1.0f, + 0.5f, + 1.0f, + }, +}; + +dof_debug dof_debug_data; +dof_pv dof_pv_data; + +extern render_context* rctx_ptr; + +namespace renderer { + DOF3::DOF3(int32_t width, int32_t height) + : textures(), samplers(), vao() { + this->width = width; + this->height = height; + + init(width, height); + } + + DOF3::~DOF3() { + + } + + void DOF3::apply(RenderTexture* rt) { + camera* cam = rctx_ptr->camera; + bool use_dof_f2 = false; + 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) { + float_t focus = dof_debug_data.focus; + if (dof_debug_data.flags & DOF_DEBUG_AUTO_FOCUS) { + rob_chara* rob_chr = 0; + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + rob_chara* rob_chr = rob_chara_array_get(i); + if (!rob_chr || !rob_chr->is_visible()) + continue; + + mat4 mat = mat4_identity; + rob_chr->sub_1405163C0(4, mat); + + vec3 chara_trans = 0.0f; + mat4_get_translation(&mat, &chara_trans); + + mat4 view_transpose; + mat4_transpose(&cam->view, &view_transpose); + focus = -vec3::dot(*(vec3*)&view_transpose.row2, chara_trans) + - view_transpose.row2.w - 0.1f; + break; + } + } + + focus = max_def(focus, (float_t)cam->min_distance); + apply_physical(rt, rt->GetColorTex(), rt->GetDepthTex(), + (float_t)cam->min_distance, (float_t)cam->max_distance, focus, + dof_debug_data.focal_length, (float_t)cam->fov_rad, dof_debug_data.f_number); + } + else { + float_t fuzzing_range = max_def(dof_debug_data.f2.fuzzing_range, 0.01f); + apply_f2(rt, rt->GetColorTex(), rt->GetDepthTex(), + (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, + dof_debug_data.f2.focus, dof_debug_data.f2.focus_range, + fuzzing_range, dof_debug_data.f2.ratio); + use_dof_f2 = true; + } + } + } + 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, rt->GetColorTex(), rt->GetDepthTex(), + (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, + dof_pv_data.f2.focus, dof_pv_data.f2.focus_range, + fuzzing_range, dof_pv_data.f2.ratio); + enum_or(dof_debug_data.flags, DOF_DEBUG_ENABLE_DOF); + dof_debug_data.f2 = dof_pv_data.f2; + use_dof_f2 = true; + } + else + enum_and(dof_debug_data.flags, ~DOF_DEBUG_ENABLE_DOF); + } + + void DOF3::resize(int32_t width, int32_t height) { + if (textures[0]) { + glDeleteTextures(6, textures); + textures[0] = 0; + } + + this->width = width; + this->height = height; + int32_t w20 = max_def(width / 20, 1); + int32_t h20 = max_def(height / 20, 1); + int32_t w2 = max_def(width / 2, 1); + int32_t h2 = max_def(height / 2, 1); + glGenTextures(6, textures); + gl_state_bind_texture_2d(textures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + fbo[0].init(w20, h20, &textures[0], 1, 0); + gl_state_bind_texture_2d(textures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + fbo[1].init(w20, h20, &textures[1], 1, 0); + gl_state_bind_texture_2d(textures[2]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[3]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + fbo[2].init(w2, h2, &textures[2], 2, 0); + gl_state_bind_texture_2d(textures[4]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[5]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w2, h2); + fbo[3].init(w2, h2, &textures[4], 2, 0); + } + + void DOF3::free() { + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + + if (samplers[0]) { + glDeleteSamplers(2, samplers); + samplers[0] = 0; + } + + texcoords_ubo.Destroy(); + common_ubo.Destroy(); + + if (textures[0]) { + glDeleteTextures(6, textures); + textures[0] = 0; + } + } + + void DOF3::init(int32_t width, int32_t height) { + int32_t w20 = max_def(width / 20, 1); + int32_t h20 = max_def(height / 20, 1); + int32_t w2 = max_def(width / 2, 1); + int32_t h2 = max_def(height / 2, 1); + glGenTextures(6, textures); + gl_state_bind_texture_2d(textures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + fbo[0].init(w20, h20, &textures[0], 1, 0); + gl_state_bind_texture_2d(textures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + fbo[1].init(w20, h20, &textures[1], 1, 0); + gl_state_bind_texture_2d(textures[2]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[3]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + fbo[2].init(w2, h2, &textures[2], 2, 0); + gl_state_bind_texture_2d(textures[4]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[5]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w2, h2); + fbo[3].init(w2, h2, &textures[4], 2, 0); + + vec2 data[50] = {}; + calculate_texcoords(data, 3.0f); + common_ubo.Create(sizeof(dof_common_shader_data)); + texcoords_ubo.Create(sizeof(data), data); + + glGenSamplers(2, samplers); + glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glGenVertexArrays(1, &vao); + } + + void DOF3::apply_f2(RenderTexture* 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_state_begin_event("renderer::DOF3::apply_f2"); + gl_state_disable_blend(); + gl_state_set_depth_mask(GL_FALSE); + gl_state_set_depth_func(GL_ALWAYS); + update_data(min_distance, max_distance, + fov, focus, 0.0f, 1.0f, focus_range, fuzzing_range, ratio); + + uniform_value[U_DOF] = 1; + + gl_state_bind_vertex_array(vao); + render_tiles(depth_texture, true); + downsample(color_texture, depth_texture, true); + main_filter(true); + upsample(rt, color_texture, depth_texture, true); + + shader::unbind(); + for (int32_t i = 0; i < 8; i++) { + gl_state_bind_sampler(i, 0); + gl_state_active_bind_texture_2d(i, 0); + } + gl_state_bind_vertex_array(0); + gl_state_end_event(); + } + + void DOF3::apply_physical(RenderTexture* 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_state_begin_event("renderer::DOF3::apply_physical"); + gl_state_disable_blend(); + gl_state_set_depth_mask(GL_FALSE); + gl_state_set_depth_func(GL_ALWAYS); + update_data(min_distance, max_distance, + fov, focus, focal_length, f_number, 0.0f, 0.1f, 0.0f); + + uniform_value[U_DOF] = 0; + + gl_state_bind_vertex_array(vao); + render_tiles(depth_texture, false); + downsample(color_texture, depth_texture, false); + main_filter(false); + upsample(rt, color_texture, depth_texture, false); + + shader::unbind(); + for (int32_t i = 0; i < 8; i++) { + gl_state_bind_sampler(i, 0); + gl_state_active_bind_texture_2d(i, 0); + } + gl_state_bind_vertex_array(0); + gl_state_end_event(); + } + + void DOF3::render_tiles(GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::render_tiles"); + gl_state_bind_framebuffer(fbo[0].buffer); + glViewport(0, 0, fbo[0].width, fbo[0].height); + uniform_value[U_DOF_STAGE] = 0; + shaders_ft.set(SHADER_FT_DOF); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, depth_texture); + gl_state_bind_sampler(0, samplers[1]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + gl_state_bind_framebuffer(fbo[1].buffer); + glViewport(0, 0, fbo[1].width, fbo[1].height); + uniform_value[U_DOF_STAGE] = 1; + shaders_ft.set(SHADER_FT_DOF); + gl_state_active_bind_texture_2d(0, textures[0]); + gl_state_bind_sampler(0, samplers[1]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + + } + + void DOF3::downsample(GLuint color_texture, GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::downsample"); + gl_state_bind_framebuffer(fbo[2].buffer); + glViewport(0, 0, fbo[2].width, fbo[2].height); + uniform_value[U_DOF_STAGE] = 2; + shaders_ft.set(SHADER_FT_DOF); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, depth_texture); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, color_texture); + gl_state_bind_sampler(1, samplers[0]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + } + + void DOF3::main_filter(bool f2) { + gl_state_begin_event("renderer::DOF3::main_filter"); + gl_state_bind_framebuffer(fbo[3].buffer); + glViewport(0, 0, fbo[3].width, fbo[3].height); + uniform_value[U_DOF_STAGE] = 3; + shaders_ft.set(SHADER_FT_DOF); + common_ubo.Bind(0); + texcoords_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, textures[3]); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, textures[2]); + gl_state_bind_sampler(1, samplers[1]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + } + + void DOF3::upsample(RenderTexture* rt, GLuint color_texture, GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::upsample"); + rctx_ptr->render_buffer.Bind(); + glViewport(0, 0, width, height); + uniform_value[U_DOF_STAGE] = 4; + shaders_ft.set(SHADER_FT_DOF); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, textures[4]); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, textures[5]); + gl_state_bind_sampler(1, samplers[1]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + gl_state_active_bind_texture_2d(3, color_texture); + gl_state_bind_sampler(3, samplers[1]); + gl_state_active_bind_texture_2d(4, depth_texture); + gl_state_bind_sampler(4, samplers[1]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glCopyImageSubData(rctx_ptr->render_buffer.GetColorTex(), + GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), + GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); + gl_state_end_event(); + } + + void DOF3::update_data(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) + fl = dist + 0.1f; + fl = fl / (dist - fl) * fl / f_number; + + dof_common_shader_data shader_data = {}; + shader_data.g_depth_params.x = 1.0f / (min_dist * max_dist) * (min_dist - max_dist); + shader_data.g_depth_params.y = 1.0f / min_dist; + shader_data.g_depth_params.z = -((fl * dist * (min_dist - max_dist)) * (1.0f / (min_dist * max_dist))); + shader_data.g_depth_params.w = (1.0f - 1.0f / min_dist * dist) * fl; + shader_data.g_spread_scale.x = 720.0f / (tanf(fov * 0.5f) * (min_dist * 2.0f)); + shader_data.g_spread_scale.y = shader_data.g_spread_scale.x * (float_t)(1.0 / 3.0); + shader_data.g_spread_scale.z = (float_t)(1.0 / 3.0); + shader_data.g_spread_scale.w = 3.0f; + shader_data.g_depth_params2.x = dist; + 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); + } + + void DOF3::calculate_texcoords(vec2* data, float_t size) { + size_t i; + size_t j; + float_t v6; + float_t v7; + float_t v8; + float_t v9; + float_t v11; + + const float_t t = (float_t)(1.0 / 3.0); + size *= 3.0f; + for (i = 0; i < 7; i++) { + v6 = (float_t)i * t - 1.0f; + for (j = 0; j < 7; j++) { + v7 = (float_t)j * t - 1.0f; + if (-v6 >= v7) { + if (v7 < v6) { + v8 = -v7; + v9 = (v6 / v7) + 4.0f; + } + else if (v6 == 0.0f) { + v8 = 0.0f; + v9 = 0.0f; + } + else { + v8 = -v6; + v9 = 6.0f - (v7 / v6); + } + } + else if (v6 < v7) { + v8 = (float_t)j * t - 1.0f; + v9 = v6 / v7; + } + else { + v8 = (float_t)i * t - 1.0f; + v9 = 2.0f - (v7 / v6); + } + v8 *= size; + v11 = v9 * (float_t)(M_PI * 0.25); + + *data++ = vec2(cosf(v11), sinf(v11)) * v8; + } + } + } +} + +void dof_debug_get(dof_debug* debug) { + if (debug) + *debug = dof_debug_data; +} + +void dof_debug_set(dof_debug* debug) { + if (debug) + dof_debug_data = *debug; + else + dof_debug_data = dof_debug_default; +} + +void dof_pv_get(dof_pv* pv) { + if (pv) + *pv = dof_pv_data; +} + +void dof_pv_set(dof_pv* pv) { + if (pv) + dof_pv_data = *pv; + else + dof_pv_data = dof_pv_default; +} diff --git a/src/CRE/renderer/dof.hpp b/src/CRE/renderer/dof.hpp new file mode 100644 index 00000000..5c676d67 --- /dev/null +++ b/src/CRE/renderer/dof.hpp @@ -0,0 +1,89 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../GL/uniform_buffer.hpp" +#include "../camera.hpp" +#include "../render_texture.hpp" +#include "fbo.hpp" + +enum dof_debug_flags { + DOF_DEBUG_USE_UI_PARAMS = 0x01, + DOF_DEBUG_ENABLE_DOF = 0x02, + DOF_DEBUG_ENABLE_PHYS_DOF = 0x04, + DOF_DEBUG_AUTO_FOCUS = 0x08, +}; + +struct dof_f2 { + float_t focus; + float_t focus_range; + float_t fuzzing_range; + float_t ratio; +}; + +struct dof_debug { + dof_debug_flags flags; + float_t focus; + float_t focal_length; + float_t f_number; + dof_f2 f2; +}; + +struct dof_pv { + bool enable; + dof_f2 f2; +}; + +namespace renderer { + struct DOF3 { + private: + int32_t width; + int32_t height; + GLuint textures[6]; + FBO fbo[4]; + GLuint samplers[2]; + GLuint vao; + GL::UniformBuffer common_ubo; + GL::UniformBuffer texcoords_ubo; + + public: + DOF3(int32_t width, int32_t height); + ~DOF3(); + + void apply(RenderTexture* 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, 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, 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 main_filter(bool f2); + void upsample(RenderTexture* rt, GLuint color_texture, GLuint depth_texture, bool f2); + + void update_data(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); + }; +} + +extern dof_debug dof_debug_data; +extern dof_pv dof_pv_data; + +extern void dof_debug_get(dof_debug* debug); +extern void dof_debug_set(dof_debug* debug = 0); +extern void dof_pv_get(dof_pv* pv); +extern void dof_pv_set(dof_pv* pv = 0); diff --git a/src/CRE/renderer/fbo.cpp b/src/CRE/renderer/fbo.cpp new file mode 100644 index 00000000..11c4b9eb --- /dev/null +++ b/src/CRE/renderer/fbo.cpp @@ -0,0 +1,70 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "fbo.hpp" +#include "../gl_state.hpp" + +namespace renderer { + FBO::FBO() : flags(), width(), height(), buffer(), count(), textures() { + + } + + FBO::~FBO() { + free(); + } + +#pragma warning(push) +#pragma warning(disable: 6385) +#pragma warning(disable: 6386) + void FBO::init(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture) { + free(); + + count = min_def(count, 8); + + this->width = width; + this->height = height; + this->count = count; + flags = (Flags)0; + if (depth_texture) { + this->flags = DEPTH_ATTACHMENT; + this->count++; + } + + textures = new GLuint[this->count]; + for (int32_t i = 0; i < count; i++) + textures[i] = color_textures[i]; + + if (flags & DEPTH_ATTACHMENT) + textures[count] = depth_texture; + + glGenFramebuffers(1, &buffer); + glBindFramebuffer(GL_FRAMEBUFFER, buffer); + for (int32_t i = 0; i < count; i++) + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); + + if (flags & DEPTH_ATTACHMENT) + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textures[count], 0); + + GLenum color_attachments[8]; + for (int32_t i = 0; i < count; i++) + color_attachments[i] = GL_COLOR_ATTACHMENT0 + i; + glDrawBuffers(count, color_attachments); + glCheckFramebufferStatus(GL_FRAMEBUFFER); + } +#pragma warning(pop) + + void FBO::free() { + if (buffer) { + glDeleteFramebuffers(1, &buffer); + buffer = 0; + } + + if (textures) { + delete[] textures; + textures = 0; + } + } +} diff --git a/src/CRE/renderer/fbo.hpp b/src/CRE/renderer/fbo.hpp new file mode 100644 index 00000000..c2cf19dd --- /dev/null +++ b/src/CRE/renderer/fbo.hpp @@ -0,0 +1,30 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../shared.hpp" + +namespace renderer { + struct FBO { + enum Flags { + DEPTH_ATTACHMENT = 0x01, + }; + + Flags flags; + int32_t width; + int32_t height; + GLuint buffer; + int32_t count; + GLuint* textures; + + FBO(); + ~FBO(); + + void init(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture); + void free(); + }; +} diff --git a/src/CRE/renderer/transparency.cpp b/src/CRE/renderer/transparency.cpp new file mode 100644 index 00000000..b7d7a9b8 --- /dev/null +++ b/src/CRE/renderer/transparency.cpp @@ -0,0 +1,76 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "transparency.hpp" +#include "../../KKdLib/str_utils.hpp" +#include "../render_context.hpp" +#include "../gl_state.hpp" +#include "../shader_ft.hpp" + +extern render_context* rctx_ptr; + +namespace renderer { + Transparency::Transparency(GLuint color_texture, GLuint depth_texture, + int32_t width, int32_t height) : sampler(), vao() { + GLuint color_textures[1]; + color_textures[0] = color_texture; + fbo.init(width, height, color_textures, 1, depth_texture); + + glGenSamplers(1, &sampler); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glGenVertexArrays(1, &vao); + } + + Transparency::~Transparency() { + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + + if (sampler) { + glDeleteSamplers(1, &sampler); + sampler = 0; + } + } + + void Transparency::combine(RenderTexture* rt, float_t alpha) { + transparency_batch_shader_data shader_data = {}; + shader_data.g_opacity = { alpha, 0.0f, 0.0f, 0.0f }; + rctx_ptr->transparency_batch_ubo.WriteMemory(shader_data); + + gl_state_disable_blend(); + gl_state_disable_depth_test(); + rctx_ptr->render_buffer.Bind(); + shaders_ft.set(SHADER_FT_TRANSPARENCY); + rctx_ptr->transparency_batch_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, fbo.textures[0]); + gl_state_active_bind_texture_2d(1, rt->GetColorTex()); + gl_state_bind_vertex_array(vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_enable_depth_test(); + + glCopyImageSubData(rctx_ptr->render_buffer.GetColorTex(), + GL_TEXTURE_2D, 0, 0, 0, 0, rt->GetColorTex(), + GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); + } + + void Transparency::copy(GLuint texture) { + glCopyImageSubData(texture, + GL_TEXTURE_2D, 0, 0, 0, 0, fbo.textures[0], + GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); + gl_state_bind_framebuffer(fbo.buffer); + glViewport(0, 0, fbo.width, fbo.height); + } + + void Transparency::resize(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height) { + GLuint color_textures[1]; + color_textures[0] = color_texture; + fbo.init(width, height, color_textures, 1, depth_texture); + } +} diff --git a/src/CRE/renderer/transparency.hpp b/src/CRE/renderer/transparency.hpp new file mode 100644 index 00000000..7258d35d --- /dev/null +++ b/src/CRE/renderer/transparency.hpp @@ -0,0 +1,29 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/vec.hpp" +#include "../render_texture.hpp" +#include "fbo.hpp" + +namespace renderer { + struct Transparency { + private: + FBO fbo; + GLuint sampler; + GLuint vao; + + public: + 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 resize(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height); + }; +}; diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index 41d0895f..494794fc 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -995,9 +995,9 @@ void RobCloth::Disp(const mat4* mat, render_context* rctx) { } } - rctx->disp_manager.set_texture_pattern((int32_t)itm_eq_obj->texture_pattern.size(), itm_eq_obj->texture_pattern.data()); - rctx->disp_manager.entry_obj_by_obj(mat, &o, tex, vertex_buffer, index_buffer, 0, itm_eq_obj->alpha); - rctx->disp_manager.set_texture_pattern(); + rctx->disp_manager->set_texture_pattern((int32_t)itm_eq_obj->texture_pattern.size(), itm_eq_obj->texture_pattern.data()); + rctx->disp_manager->entry_obj_by_obj(mat, &o, tex, vertex_buffer, index_buffer, 0, itm_eq_obj->alpha); + rctx->disp_manager->set_texture_pattern(); } void RobCloth::InitData(size_t root_count, size_t nodes_count, obj_skin_block_cloth_root* root, diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index a0c54ded..bc638f05 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -17,8 +17,9 @@ #include "../hand_item.hpp" #include "../mdata_manager.hpp" #include "../pv_db.hpp" -#include "../random.hpp" #include "../pv_expression.hpp" +#include "../random.hpp" +#include "../resolution_mode.hpp" #include "../stage.hpp" #include "motion.hpp" #include "skin_param.hpp" @@ -9727,7 +9728,7 @@ static void rob_chara_age_age_ctrl(rob_chara_age_age* arr, static void rob_chara_age_age_disp(rob_chara_age_age* arr, render_context* rctx, int32_t chara_id, bool reflect, bool chara_color) { - bool npr = !!rctx->render_manager.npr_param; + bool npr = !!rctx->render_manager->npr_param; mat4& view = rctx->camera->view; vec3 v11 = { view.row0.z, view.row1.z, view.row2.z }; arr[chara_id * 3 + 0].disp(rctx, chara_id, npr, reflect, v11, chara_color); @@ -11203,9 +11204,9 @@ void rob_chara_age_age_array_ctrl(int32_t chara_id, int32_t part_id, mat4& mat) void rob_chara_age_age_array_disp(render_context* rctx, int32_t chara_id, bool reflect, bool chara_color) { - mdl::ObjFlags obj_flags = rctx->disp_manager.get_obj_flags(); + mdl::ObjFlags obj_flags = rctx->disp_manager->get_obj_flags(); rob_chara_age_age_disp(rob_chara_age_age_array, rctx, chara_id, reflect, chara_color); - rctx->disp_manager.set_obj_flags(obj_flags); + rctx->disp_manager->set_obj_flags(obj_flags); } void rob_chara_age_age_array_load(int32_t chara_id, int32_t part_id) { @@ -12835,21 +12836,21 @@ void rob_chara_item_equip_object::disp(const mat4* mat, render_context* rctx) { if (obj_info.is_null()) return; - mdl::ObjFlags flags = rctx->disp_manager.get_obj_flags(); + mdl::ObjFlags flags = rctx->disp_manager->get_obj_flags(); mdl::ObjFlags chara_flags = flags; if (fabsf(alpha - 1.0f) > 0.000001f) enum_or(chara_flags, obj_flags); else enum_and(chara_flags, ~(mdl::OBJ_ALPHA_ORDER_3 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_1)); - rctx->disp_manager.set_obj_flags(chara_flags); + rctx->disp_manager->set_obj_flags(chara_flags); if (can_disp) { - rctx->disp_manager.entry_obj_by_object_info_object_skin(obj_info, + rctx->disp_manager->entry_obj_by_object_info_object_skin(obj_info, &texture_pattern, &texture_data, alpha, mats, ex_data_bone_mats.data(), 0, mat); for (ExNodeBlock*& i : node_blocks) i->Disp(mat, rctx); } - rctx->disp_manager.set_obj_flags(flags); + rctx->disp_manager->set_obj_flags(flags); } int32_t rob_chara_item_equip_object::get_bone_index(const char* name, const bone_database* bone_data) { @@ -13484,10 +13485,10 @@ static void sub_140512C20(rob_chara_item_equip* rob_itm_equip, render_context* r mat4_mul(&mat, node->mat, &mat); int32_t tex_pat_count = (int32_t)rob_itm_equip->texture_pattern.size(); if (tex_pat_count) - rctx->disp_manager.set_texture_pattern(tex_pat_count, rob_itm_equip->texture_pattern.data()); - rctx->disp_manager.entry_obj_by_object_info(0, rob_itm_equip->field_D0); + rctx->disp_manager->set_texture_pattern(tex_pat_count, rob_itm_equip->texture_pattern.data()); + rctx->disp_manager->entry_obj_by_object_info(0, rob_itm_equip->field_D0); if (tex_pat_count) - rctx->disp_manager.set_texture_pattern(); + rctx->disp_manager->set_texture_pattern(); } void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { @@ -13497,20 +13498,19 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { if (rctx->chara_refract) enum_or(flags, mdl::OBJ_REFRACT); - mdl::DispManager& disp_manager = rctx->disp_manager; - Shadow* shad = rctx->render_manager.shadow_ptr; + mdl::DispManager& disp_manager = *rctx->disp_manager; if (shadow_type != -1) { if (field_A0 & 0x04) { vec3 pos = position; pos.y -= 0.2f; - shad->field_1D0[shadow_type].push_back(pos); + shadow_ptr_get()->field_1D0[shadow_type].push_back(pos); float_t v9; if (sub_140512F60(this) <= -0.2f) v9 = -0.5f; else v9 = 0.05f; - rctx->render_manager.shadow_ptr->field_1C0[shadow_type] = v9; + shadow_ptr_get()->field_1C0[shadow_type] = v9; disp_manager.set_shadow_type(shadow_type); enum_or(flags, mdl::OBJ_SHADOW); } @@ -13526,7 +13526,7 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { disp_manager.set_texture_color_coefficients(texture_color_coefficients); disp_manager.set_wet_param(wet); - rctx->render_manager.field_31C |= npr_flag; + rctx->render_manager->field_31C |= npr_flag; sub_140512C20(this, rctx); rob_chara_age_age_array_disp(rctx, chara_id, rctx->chara_reflect, chara_color); @@ -15258,19 +15258,18 @@ void pos_scale::get_screen_pos_scale(mat4& mat, vec3& trans, bool apply_offset) mat4_transform_vector(&mat, &v15, &v15); if (fabsf(v15.w) >= 1.0e-10f) { - post_process* pp = &rctx_ptr->post_process; + float_t v8 = v15.y * (1.0f / v15.w); + float_t v9 = v15.x * (1.0f / v15.w) + 1.0f; + resolution_struct* res_wind_int = res_window_internal_get(); + float_t v11 = (float_t)(v9 * 0.5f) * (float_t)res_wind_int->width; + float_t v12 = (float_t)((1.0f - v8) * 0.5f) * (float_t)res_wind_int->height; if (apply_offset) { - float_t v11 = (1.0f + v15.x * (1.0f / v15.w)) * 0.5f * (float_t)pp->screen_width; - float_t v12 = (1.0f - v15.y * (1.0f / v15.w)) * 0.5f * (float_t)pp->screen_height; - v11 += (float_t)pp->screen_x_offset; - v12 += (float_t)pp->screen_y_offset; - pos = { v11, v12 }; - } - else{ - float_t v11 = (1.0f + v15.x * (1.0f / v15.w)) * 0.5f * (float_t)pp->render_width; - float_t v12 = (1.0f - v15.y * (1.0f / v15.w)) * 0.5f * (float_t)pp->render_height; - pos = { v11, v12 }; + resolution_struct* res_wind = res_window_get(); + v11 += (float_t)res_wind_int->x_offset; + v12 += (float_t)(res_wind->height - res_wind_int->y_offset - res_wind_int->height); } + pos.x = v11; + pos.y = v12; scale = -v15.w; } else { @@ -17054,7 +17053,7 @@ OpdMakeManager::~OpdMakeManager() { bool OpdMakeManager::Init() { mode = 1; - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_3D, false); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_3D, false); if (path_check_directory_exists("ram/osage_play_data")) RemoveDirectoryA("ram/osage_play_data"); @@ -17205,7 +17204,7 @@ bool OpdMakeManager::Dest() { task_rob_manager_del_task(); } - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_3D, true); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_3D, true); if (path_check_directory_exists("ram/osage_play_data")) RemoveDirectoryA("ram/osage_play_data"); @@ -17368,10 +17367,10 @@ void rob_chara_age_age_object::disp(render_context* rctx, size_t chara_index, mdl::ObjFlags flags = (mdl::ObjFlags)(mdl::OBJ_SSS | mdl::OBJ_4 | mdl::OBJ_SHADOW); if (reflect) enum_or(flags, mdl::OBJ_CHARA_REFLECT); - rctx->disp_manager.set_obj_flags(flags); - rctx->disp_manager.set_chara_color(chara_color); - rctx->disp_manager.set_shadow_type(chara_index ? SHADOW_STAGE : SHADOW_CHARA); - rctx->disp_manager.entry_obj_by_obj(&mat4_identity, &obj, + rctx->disp_manager->set_obj_flags(flags); + rctx->disp_manager->set_chara_color(chara_color); + rctx->disp_manager->set_shadow_type(chara_index ? SHADOW_STAGE : SHADOW_CHARA); + rctx->disp_manager->entry_obj_by_obj(&mat4_identity, &obj, &get_obj_set_texture(), &obj_vert_buf, &obj_index_buf, 0, 1.0f); } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 636d12fd..39896055 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -11,8 +11,8 @@ #include "../../KKdLib/mat.hpp" #include "../../KKdLib/mot.hpp" #include "../../KKdLib/vec.hpp" -#include "../draw_object.hpp" #include "../item_table.hpp" +#include "../render_context.hpp" #include "../object.hpp" #include "../static_var.hpp" diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index 30817614..8c8e723e 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -2521,18 +2521,10 @@ static const uniform_name DOF_uniform[] = { // Added U_DOF, }; -static const uniform_name COPY_uniform[] = { // Added - U_INVALID, -}; - static const uniform_name GRID_uniform[] = { // Added U_INVALID, }; -static const uniform_name GHOST_uniform[] = { // Added - U_INVALID, -}; - static const uniform_name TRANSPARENCY_uniform[] = { // Added U_INVALID, }; @@ -2995,18 +2987,10 @@ static const bool DOF_permut[] = { // Added true, }; -static const bool COPY_permut[] = { // Added - false, -}; - static const bool GRID_permut[] = { // Added false, }; -static const bool GHOST_permut[] = { // Added - false, -}; - static const bool TRANSPARENCY_permut[] = { // Added false, }; diff --git a/src/CRE/shadow.cpp b/src/CRE/shadow.cpp new file mode 100644 index 00000000..87a83e60 --- /dev/null +++ b/src/CRE/shadow.cpp @@ -0,0 +1,362 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shadow.hpp" +#include "render_context.hpp" + +Shadow* shadow_ptr; + +extern render_context* rctx_ptr; + +Shadow::Shadow() : curr_render_textures(), view_region(), range(), field_1C0(), field_1C8(), +field_200(), field_208(), near_blur(), blur_filter(), far_blur(), field_2BC(), distance(), +field_2C4(), z_near(), z_far(), field_2D0(), field_2D4(), field_2D8(), field_2DC(), field_2E0(), +ambient(), field_2E8(), field_2EC(), field_2F0(), self_shadow(), blur_filter_enable(), field_2F5() { + Reset(); +} + +Shadow::~Shadow() { + Free(); +} + +void Shadow::Ctrl() { + for (int32_t i = 0; i < 2; i++) + field_2F0[i] = false; + + if (rctx_ptr->render_manager->shadow) { + view_mat[0] = rctx_ptr->camera->view; + view_mat[1] = rctx_ptr->camera->inv_view; + + ::light_set* set = &rctx_ptr->light_set[LIGHT_SET_MAIN]; + light_data* data = &set->lights[LIGHT_CHARA]; + + vec3 position; + data->get_position(position); + float_t length = vec3::length(position); + if (length < 0.000001f) + direction = { 0.0f, 1.0f, 0.0f }; + else + direction = -position * (1.0f / length); + + for (int32_t i = 0; i < 2; i++) + if (rctx_ptr->disp_manager->get_obj_count((mdl::ObjType)((int32_t)mdl::OBJ_TYPE_SHADOW_CHARA + i))) + field_2F0[i] = true; + } + + int32_t count = 0; + field_2EC = 0; + for (int32_t i = 0; i < 2; i++) + if (field_2F0[i] && field_1D0[i].size() > 0) { + field_2EC++; + count += (int32_t)field_1D0[i].size(); + } + else + field_2F0[i] = false; + + if (count < 3) { + for (int32_t i = 0; i < 2; i++) { + field_1A8[i] = 0.0f; + field_1C8[i] = 0.0f; + if (!field_2F0[i] || field_1D0[i].size() < 1) + continue; + + vec3 v7 = 0.0f; + for (vec3& j : field_1D0[i]) + v7 += j; + + float_t v14 = (float_t)(int64_t)field_1D0[i].size(); + if (v14 < 0.0f) + v14 += (float_t)UINT64_MAX; + v7 *= 1.0f / v14; + + float_t v15 = 0.0f; + for (vec3& j : field_1D0[i]) { + vec3 v22 = v7 - j; + vec3 v25 = direction * vec3::dot(v22, direction); + float_t v24 = vec3::distance(v25, v22); + v24 -= 0.25f; + if (v24 < 0.0f) + v24 = 0.0f; + if (v15 < v24) + v15 = v24; + } + field_1A8[i] = v7; + field_1C8[i] = v15; + } + + if (field_2EC > 0) { + vec3 view_point = 0.0f; + vec3 interest = 0.0f; + for (int32_t i = 0; i < 2; i++) { + if (!field_2F0[i]) + continue; + + vec3 v11 = field_1A8[i] - direction * field_208; + float_t v9 = vec3::distance(this->view_point[i], v11); + float_t v12 = vec3::distance(this->interest[i], field_1A8[i]); + if (v9 > 0.1f || v12 > 0.1f) { + this->view_point[i] = v11; + this->interest[i] = field_1A8[i]; + } + + view_point += this->view_point[i]; + interest += this->interest[i]; + } + + view_point_shared = view_point * (1.0f / (float_t)field_2EC); + interest_shared = interest * (1.0f / (float_t)field_2EC); + } + + float_t v2 = max_def(field_1C8[0], field_1C8[1]); + field_2F5 = false; + view_region = v2 + 1.2f; + field_200[0] = 0; + field_200[1] = 1; + if (field_2EC >= 2) { + vec3 v12 = field_1A8[0] - interest_shared; + vec3 v14 = field_1A8[1] - interest_shared; + + float_t v6 = vec3::length(direction * vec3::dot(v12, direction) - v12); + + float_t v16 = v6 - 0.25f; + if (v16 < 0.0f) + v16 = 0.0f; + + if (v16 > 1.2f) { + view_region = v2 + 2.4f; + field_2F5 = true; + } + else + view_region = v2 + 1.2f + v16; + + if (vec3::dot(v12, direction) < vec3::dot(v14, direction)) { + field_200[1] = 0; + field_200[0] = 1; + } + } + } + else { + vec3 v3; + vec3 v86; + if (direction.y * direction.y < 0.99f) { + v86 = vec3::cross(direction, vec3(0.0f, 1.0f, 0.0f)); + v3 = vec3::normalize(vec3::cross(v86, direction)); + v86 = vec3::normalize(v86); + } + else { + v3 = { 0.0f, 0.0f, 1.0f }; + v86 = { 1.0f, 0.0f, 0.0f }; + } + + for (int32_t i = 0; i < 2; i++) { + field_1A8[i] = 0.0f; + field_1C8[i] = 0.0; + if (!field_2F0[i] || field_1D0[i].size() < 1) + continue; + + vec3 v22 = 0.0f; + for (vec3& j : field_1D0[i]) + v22 += j; + + float_t v29 = (float_t)(int64_t)field_1D0[i].size(); + if (v29 < 0.0f) + v29 += (float_t)UINT64_MAX; + + float_t v30 = 0.0f; + vec3 v31 = v22 * (1.0f / v29); + + for (vec3& j : field_1D0[i]) { + vec3 v34 = v31 - j; + float_t v38 = fabsf(vec3::dot(v34, v3)); + float_t v39 = fabsf(vec3::dot(v34, v86)); + if (v39 >= v38) + v38 = v39; + if (v30 < v38) + v30 = v38; + } + field_1A8[i] = v31; + field_1C8[i] = v30; + } + + if (field_2EC > 0) { + for (int32_t i = 0; i < 2; i++) { + if (!field_2F0[i]) + continue; + + vec3 v53 = field_1A8[i] - direction * field_208; + float_t v51 = vec3::distance(view_point[i], v53); + float_t v54 = vec3::distance(interest[i], field_1A8[i]); + if (v51 > 0.1f || v54 > 0.1f) { + view_point[i] = v53; + interest[i] = field_1A8[i]; + } + } + + vec3 view_point = 0.0f; + vec3 interest = 0.0f; + int32_t count = 0; + for (int32_t i = 0; i < 2; i++) { + int32_t c = (int32_t)field_1D0[i].size(); + view_point += this->view_point[i] * (float_t)c; + interest += this->interest[i] * (float_t)c; + count += c; + } + + view_point_shared = view_point * (1.0f / (float_t)count); + interest_shared = interest * (1.0f / (float_t)count); + } + + float_t v2 = 0.0f; + float_t v67 = max_def(field_1C8[0], field_1C8[1]); + field_2F5 = false; + view_region = v67 + 1.2f; + field_200[0] = 0; + field_200[1] = 1; + if (field_2EC >= 2) { + float_t v68 = 0.0f; + float_t v69 = 0.0f; + float_t v70 = 0.0f; + for (int32_t i = 0; i < 2; i++) { + if (!field_2F0[i]) + continue; + + for (vec3& j : field_1D0[i]) { + vec3 v74 = j - interest_shared; + + float_t v77 = vec3::dot(v74, v86); + if (v2 > v77) + v2 = v77; + else if (v69 < v77) + v69 = v77; + + float_t v78 = vec3::dot(v74, v3); + if (v68 > v78) + v68 = v78; + else if (v70 < v78) + v70 = v78; + } + } + + float_t v79 = -v2; + if (v79 < v69) + v79 = v69; + if (v79 < -v68) + v79 = -v68; + if (v79 < v70) + v79 = v70; + + if (v79 > v67 + 1.2f) { + view_region = v67 + 2.4f; + field_2F5 = true; + } + else + view_region = v79 + 1.2f; + + if (vec3::dot(field_1A8[0] - interest_shared, direction) + < vec3::dot(field_1A8[1] - interest_shared, direction)) { + field_200[1] = 0; + field_200[0] = 1; + } + } + } + + for (std::vector& i : field_1D0) + i.clear(); +} + +void Shadow::Free() { + for (RenderTexture& i : render_textures) + i.Free(); + + Reset(); +} + +int32_t Shadow::Init() { + struct shadow_texture_init_params { + int32_t width; + int32_t height; + int32_t max_level; + GLenum color_format; + GLenum depth_format; + } init_params[] = { + { 0x800, 0x800, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F }, + { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, + { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, + { 0x800, 0x800, 0, GL_R32F , GL_ZERO }, + { 0x800, 0x800, 0, GL_R32F , GL_ZERO }, + { 0x200, 0x200, 0, GL_R32F , GL_ZERO }, + { 0x200, 0x200, 0, GL_R32F , GL_ZERO }, + }; + + shadow_texture_init_params* v3 = init_params; + for (int32_t i = 0; i < 7; i++, v3++) + if (render_textures[i].Init(v3->width, v3->height, + v3->max_level, v3->color_format, v3->depth_format) < 0) + return -1; + + for (int32_t i = 0; i < 3; i++) { + gl_state_bind_texture_2d(render_textures[i].GetColorTex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + static const vec4 border_color = 1.0f; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + } + gl_state_bind_texture_2d(0); + gl_state_get_error(); + return 0; +} + +void Shadow::Reset() { + view_region = 1.2f; + range = 1.0f; + + for (int32_t i = 0; i < 2; i++) { + view_point[i] = 1.0f; + field_1C0[i] = 0.0f; + field_1C8[i] = 0.0f; + field_200[i] = i; + } + + for (RenderTexture*& i : curr_render_textures) + i = 0; + + view_mat[0] = mat4_identity; + view_mat[1] = mat4_identity; + blur_filter = BLUR_FILTER_9; + near_blur = 1; + field_2BC = 2; + far_blur = 1; + distance = 4.0f; + field_2C4 = 0.4f; + z_near = 0.1f; + z_far = 20.0f; + field_2D0 = 1.4f; + field_2D4 = 10000.0f; + field_2D8 = 80.0f; + field_2DC = 2.0f; + field_2E0 = 0.05f; + ambient = 0.4f; + field_2EC = 0; + direction = vec3(0.0f, -1.0f, -1.0f) * (1.0f / sqrtf(2.0f)); + field_2E8 = false; + self_shadow = true; + field_2F5 = false; + field_208 = (z_far - z_near) * 0.5f; +} + +void shadow_ptr_init() { + shadow_ptr = new Shadow; +} + +Shadow* shadow_ptr_get() { + return shadow_ptr; +} + +void shadow_ptr_free() { + if (shadow_ptr) { + delete shadow_ptr; + shadow_ptr = 0; + } +} diff --git a/src/CRE/shadow.hpp b/src/CRE/shadow.hpp new file mode 100644 index 00000000..adb9efc0 --- /dev/null +++ b/src/CRE/shadow.hpp @@ -0,0 +1,70 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/time.hpp" +#include "../KKdLib/vec.hpp" +#include "render_texture.hpp" +#include "static_var.hpp" +#include + +enum shadow_type_enum { + SHADOW_CHARA = 0, + SHADOW_STAGE, + SHADOW_MAX, +}; + +struct Shadow { + RenderTexture render_textures[7]; + RenderTexture* curr_render_textures[3]; + float_t view_region; + float_t range; + vec3 view_point[2]; + vec3 interest[2]; + vec3 field_1A8[2]; + float_t field_1C0[2]; + float_t field_1C8[2]; + std::vector field_1D0[2]; + int32_t field_200[2]; + float_t field_208; + vec3 direction; + vec3 view_point_shared; + vec3 interest_shared; + mat4 view_mat[2]; + int32_t near_blur; + blur_filter_mode blur_filter; + int32_t far_blur; + int32_t field_2BC; + float_t distance; + float_t field_2C4; + float_t z_near; + float_t z_far; + float_t field_2D0; + float_t field_2D4; + float_t field_2D8; + float_t field_2DC; + float_t field_2E0; + float_t ambient; + bool field_2E8; + int32_t field_2EC; + bool field_2F0[2]; + bool self_shadow; + bool blur_filter_enable[2]; + bool field_2F5; + + Shadow(); + ~Shadow(); + + void Ctrl(); + void Free(); + int32_t Init(); + void Reset(); +}; + +extern void shadow_ptr_init(); +extern Shadow* shadow_ptr_get(); +extern void shadow_ptr_free(); diff --git a/src/CRE/shared.cpp b/src/CRE/shared.cpp index 030c087f..0009e045 100644 --- a/src/CRE/shared.cpp +++ b/src/CRE/shared.cpp @@ -4,3 +4,13 @@ */ #include "shared.hpp" +#include "gl_state.hpp" + +void fbo_blit(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_state_bind_read_framebuffer(src_fbo); + gl_state_bind_draw_framebuffer(dst_fbo); + glBlitFramebuffer(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/CRE/shared.hpp b/src/CRE/shared.hpp index 79b5235e..194be1c8 100644 --- a/src/CRE/shared.hpp +++ b/src/CRE/shared.hpp @@ -9,3 +9,7 @@ #include "../KKdLib/mat.hpp" #include "../KKdLib/vec.hpp" #include "static_var.hpp" + +extern void fbo_blit(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/CRE/sprite.cpp b/src/CRE/sprite.cpp index e245dba1..36bee66a 100644 --- a/src/CRE/sprite.cpp +++ b/src/CRE/sprite.cpp @@ -155,8 +155,7 @@ namespace spr { uint32_t AddSetModern(); void AddSprSets(const sprite_database* spr_db); void Clear(); - void Draw(render_context* rctx, - int32_t index, bool font, texture* tex, const mat4& vp); + void Draw(int32_t index, bool font, texture* tex, const mat4& vp); SprSet* GetSet(uint32_t index); bool GetSetReady(uint32_t index); uint32_t GetSetSpriteNum(uint32_t index); @@ -470,9 +469,8 @@ void sprite_manager_clear() { sprite_manager->Clear(); } -void sprite_manager_draw(render_context* rctx, - int32_t index, bool font, texture* tex, const mat4& vp) { - sprite_manager->Draw(rctx, index, font, tex, vp); +void sprite_manager_draw(int32_t index, bool font, texture* tex, const mat4& vp) { + sprite_manager->Draw(index, font, tex, vp); } int32_t sprite_manager_get_index() { @@ -770,8 +768,8 @@ namespace spr { render_data.Clear(); } - void SpriteManager::Draw(render_context* rctx, - int32_t index, bool font, texture* tex, const mat4& vp) { + void SpriteManager::Draw(int32_t index, bool font, texture* tex, const mat4& vp) { + render_context* rctx = rctx_ptr; draw_sprite_begin(rctx); ::resolution_mode mode = res_window_get()->resolution_mode; diff --git a/src/CRE/sprite.hpp b/src/CRE/sprite.hpp index e8ecb3e8..2dccb867 100644 --- a/src/CRE/sprite.hpp +++ b/src/CRE/sprite.hpp @@ -227,8 +227,7 @@ namespace spr { extern void sprite_manager_init(); extern void sprite_manager_add_spr_sets(const sprite_database* spr_db); extern void sprite_manager_clear(); -extern void sprite_manager_draw(render_context* rctx, - int32_t index, bool font, texture* tex, const mat4& vp); +extern void sprite_manager_draw(int32_t index, bool font, texture* tex, const mat4& vp); extern int32_t sprite_manager_get_index(); extern size_t sprite_manager_get_reqlist_count(int32_t index); extern ::spr_set* sprite_manager_get_set(uint32_t set_id, const sprite_database* spr_db); diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index fa173274..7abf27f5 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -434,7 +434,7 @@ static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* mat4_transform_point(view, ¢er, ¢er); float_t radius = sphere->radius; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); float_t v9 = shad->view_region * shad->range; if ((center.x + radius) < -v9 || (center.x - radius) > v9 @@ -448,14 +448,14 @@ static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere, mat4* view) { mat4 mat; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); mat4_look_at(&shad->view_point[0], &shad->interest[0], &mat); return object_bounding_sphere_check_visibility_shadow(sphere, view, &mat); } static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere, mat4* view) { mat4 mat; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); mat4_look_at(&shad->view_point[1], &shad->interest[1], &mat); return object_bounding_sphere_check_visibility_shadow(sphere, view, &mat); } @@ -476,7 +476,7 @@ static void stage_disp(stage* s) { if (s->state != 6 || !s->stage_display) return; - mdl::DispManager& disp_manager = rctx_ptr->disp_manager; + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; mat4 mat; mat4_rotate_y(s->rot_y, &mat); @@ -507,16 +507,16 @@ static void stage_disp(stage* s) { if (s->stage_data->lens_flare_texture != -1 && s->lens_flare) { int32_t object_set_id = s->stage_data->object_set_id; - post_process* pp = &rctx_ptr->post_process; - pp->lens_flare_texture = obj_database_get_obj_set_texture( + rndr::Render* rend = &rctx_ptr->render; + rend->lens_flare_texture = obj_database_get_obj_set_texture( object_set_id, s->stage_data->lens_flare_texture); - if (pp->lens_flare_texture) { - pp->lens_shaft_texture = obj_database_get_obj_set_texture( + if (rend->lens_flare_texture) { + rend->lens_shaft_texture = obj_database_get_obj_set_texture( object_set_id, s->stage_data->lens_shaft_texture); - pp->lens_ghost_texture = obj_database_get_obj_set_texture( + rend->lens_ghost_texture = obj_database_get_obj_set_texture( object_set_id, s->stage_data->lens_ghost_texture); - pp->lens_ghost_count = 16; - pp->lens_shaft_inv_scale = s->stage_data->lens_shaft_inv_scale; + rend->lens_ghost_count = 16; + rend->lens_shaft_inv_scale = s->stage_data->lens_shaft_inv_scale; } } } @@ -532,7 +532,7 @@ static void stage_disp_shadow(stage* s) { } static void stage_disp_shadow_object(object_info object, mat4* mat) { - mdl::DispManager& disp_manager = rctx_ptr->disp_manager; + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; for (int32_t i = SHADOW_CHARA; i < SHADOW_MAX; i++) { disp_manager.set_shadow_type((shadow_type_enum)i); @@ -558,18 +558,18 @@ static void stage_free(stage* s) { if (s->state < 7 || s->state > 9) return; - rndr::RenderManager* render_manager = &rctx_ptr->render_manager; + rndr::RenderManager* render_manager = rctx_ptr->render_manager; if (s->stage_data->render_texture != -1) - rctx_ptr->post_process.render_texture_free( + rctx_ptr->render.render_texture_free( texture_storage_get_texture(s->stage_data->render_texture), 0); if (s->stage_data->movie_texture != -1) - rctx_ptr->post_process.movie_texture_free( + rctx_ptr->render.movie_texture_free( texture_storage_get_texture(s->stage_data->movie_texture)); render_manager->set_shadow_true(); - //rctx_ptr->post_process.field_14 = 0; - //rctx_ptr->post_process.field_ED8 = 1; + //rctx_ptr->render.field_14 = 0; + //rctx_ptr->render.field_ED8 = 1; npr_cloth_spec_color.w = 1.0f; render_manager->field_31D = false; render_manager->field_31E = false; @@ -621,11 +621,11 @@ static void stage_load(stage* s) { return; if (s->stage_data->render_texture != -1) - rctx_ptr->post_process.render_texture_set( + rctx_ptr->render.render_texture_set( texture_storage_get_texture(s->stage_data->render_texture), 0); if (s->stage_data->movie_texture != -1) - rctx_ptr->post_process.movie_texture_set( + rctx_ptr->render.movie_texture_set( texture_storage_get_texture(s->stage_data->movie_texture)); s->state = 6; } @@ -651,7 +651,7 @@ static void stage_set(stage* s, stage* other) { if (other && s == other) return; - rndr::RenderManager* render_manager = &rctx_ptr->render_manager; + rndr::RenderManager* render_manager = rctx_ptr->render_manager; if (s) { //flt_14CC925C0 = 0.0; //flt_140CB3704 = -1001.0; @@ -664,8 +664,8 @@ static void stage_set(stage* s, stage* other) { render_manager->field_31F = false; render_manager->field_320 = false; render_manager->set_shadow_true(); - //rctx_ptr->post_process.field_14 = 0; - //rctx_ptr->post_process.field_ED8 = 1; + //rctx_ptr->render.field_14 = 0; + //rctx_ptr->render.field_ED8 = 1; npr_cloth_spec_color.w = 1.0f; render_manager->set_npr_param(0); light_chara_ambient = false; diff --git a/src/CRE/stage.hpp b/src/CRE/stage.hpp index 21c201cb..cd42928e 100644 --- a/src/CRE/stage.hpp +++ b/src/CRE/stage.hpp @@ -8,8 +8,9 @@ #include #include "../KKdLib/default.hpp" #include "../KKdLib/database/stage.hpp" -#include "render_context.hpp" #include "auth_3d.hpp" +#include "render_context.hpp" +#include "task.hpp" struct stage { int32_t index; diff --git a/src/CRE/stage_modern.cpp b/src/CRE/stage_modern.cpp index 650e1bd8..c9344995 100644 --- a/src/CRE/stage_modern.cpp +++ b/src/CRE/stage_modern.cpp @@ -450,7 +450,7 @@ static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* mat4_transform_point(view, ¢er, ¢er); float_t radius = sphere->radius; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); float_t view_region = shad->view_region * shad->range; if ((center.x + radius) < -view_region || (center.x - radius) > view_region @@ -464,14 +464,14 @@ static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere, mat4* view) { mat4 mat; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); mat4_look_at(&shad->view_point[0], &shad->interest[0], &mat); return object_bounding_sphere_check_visibility_shadow(sphere, view, &mat); } static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere, mat4* view) { mat4 mat; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); mat4_look_at(&shad->view_point[1], &shad->interest[1], &mat); return object_bounding_sphere_check_visibility_shadow(sphere, view, &mat); } @@ -492,7 +492,7 @@ static void stage_modern_disp(stage_modern* s) { if (s->state != 6 || !s->stage_display) return; - mdl::DispManager& disp_manager = rctx_ptr->disp_manager; + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; mat4 mat; mat4_rotate_y(s->rot_y, &mat); @@ -530,7 +530,7 @@ static void stage_modern_disp_shadow(stage_modern* s) { } static void stage_modern_disp_shadow_object(object_info object, mat4* mat) { - mdl::DispManager& disp_manager = rctx_ptr->disp_manager; + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; for (int32_t i = SHADOW_CHARA; i < SHADOW_MAX; i++) { disp_manager.set_shadow_type((shadow_type_enum)i); @@ -556,18 +556,18 @@ static void stage_modern_free(stage_modern* s) { if (s->state < 7 || s->state > 9) return; - rndr::RenderManager* render_manager = &rctx_ptr->render_manager; + rndr::RenderManager* render_manager = rctx_ptr->render_manager; if (s->stage_data->render_texture != -1 && s->stage_data->render_texture != hash_murmurhash_empty) - rctx_ptr->post_process.render_texture_free( + rctx_ptr->render.render_texture_free( texture_storage_get_texture(s->stage_data->render_texture), 0); if (s->stage_data->movie_texture != -1 && s->stage_data->movie_texture != hash_murmurhash_empty) - rctx_ptr->post_process.movie_texture_free( + rctx_ptr->render.movie_texture_free( texture_storage_get_texture(s->stage_data->movie_texture)); render_manager->set_shadow_true(); - //rctx_ptr->post_process.field_14 = 0; - //rctx_ptr->post_process.field_ED8 = 1; + //rctx_ptr->render.field_14 = 0; + //rctx_ptr->render.field_ED8 = 1; npr_cloth_spec_color.w = 1.0f; render_manager->field_31D = false; render_manager->field_31E = false; @@ -614,11 +614,11 @@ static void stage_modern_load(stage_modern* s, void* data, object_database* obj_ return; if (s->stage_data->render_texture != -1 && s->stage_data->render_texture != hash_murmurhash_empty) - rctx_ptr->post_process.render_texture_set( + rctx_ptr->render.render_texture_set( texture_storage_get_texture(s->stage_data->render_texture), 0); if (s->stage_data->movie_texture != -1 && s->stage_data->movie_texture != hash_murmurhash_empty) - rctx_ptr->post_process.movie_texture_set( + rctx_ptr->render.movie_texture_set( texture_storage_get_texture(s->stage_data->movie_texture)); s->state = 6; } @@ -642,7 +642,7 @@ static void stage_modern_set(stage_modern* s, stage_modern* other) { if (other && s == other) return; - rndr::RenderManager* render_manager = &rctx_ptr->render_manager; + rndr::RenderManager* render_manager = rctx_ptr->render_manager; if (s) { //flt_14CC925C0 = 0.0; //flt_140CB3704 = -1001.0; @@ -655,8 +655,8 @@ static void stage_modern_set(stage_modern* s, stage_modern* other) { render_manager->field_31F = false; render_manager->field_320 = false; render_manager->set_shadow_true(); - //rctx_ptr->post_process.field_14 = 0; - //rctx_ptr->post_process.field_ED8 = 1; + //rctx_ptr->render.field_14 = 0; + //rctx_ptr->render.field_ED8 = 1; npr_cloth_spec_color.w = 1.0f; render_manager->set_npr_param(0); light_chara_ambient = false; diff --git a/src/CRE/stage_modern.hpp b/src/CRE/stage_modern.hpp index 884b21c1..91b8d50b 100644 --- a/src/CRE/stage_modern.hpp +++ b/src/CRE/stage_modern.hpp @@ -8,8 +8,9 @@ #include #include "../KKdLib/default.hpp" #include "../KKdLib/database/stage.hpp" -#include "render_context.hpp" #include "auth_3d.hpp" +#include "render_context.hpp" +#include "task.hpp" struct stage_modern { uint32_t hash; diff --git a/src/CRE/static_var.hpp b/src/CRE/static_var.hpp index 23b1cb52..79dc7fa8 100644 --- a/src/CRE/static_var.hpp +++ b/src/CRE/static_var.hpp @@ -12,6 +12,14 @@ #include "../KKdLib/vec.hpp" #include +enum blur_filter_mode { + BLUR_FILTER_4 = 0, + BLUR_FILTER_9, + BLUR_FILTER_16, + BLUR_FILTER_32, + BLUR_FILTER_MAX, +}; + enum draw_pass_3d_type { DRAW_PASS_3D_OPAQUE = 0, DRAW_PASS_3D_TRANSLUCENT, diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 7c22a746..55abc666 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -198,7 +198,6 @@ struct stars_buffer_data { }; struct star_catalog { - GLuint vao; bool random; bool enable; stage_param_star* stage_param_data_ptr; @@ -383,19 +382,16 @@ static bool rain_particle_enable; static float_t rain_particle_delta_frame; static uint32_t rain_particle_tex_id; static particle_data rain_ptcl_data[8]; -static GLuint rain_vao; static GL::ShaderStorageBuffer rain_ssbo; static GL::UniformBuffer rain_particle_scene_ubo; static GL::UniformBuffer rain_particle_batch_ubo; static const size_t rain_ptcl_count = 0x8000; -static GLuint ripple_vao; static GL::UniformBuffer ripple_batch_ubo; static GL::UniformBuffer ripple_scene_ubo; static ripple_emit* ripple_emit_data; -static GLuint ripple_emit_vao; static GL::ShaderStorageBuffer ripple_emit_ssbo; static GL::UniformBuffer ripple_emit_scene_ubo; @@ -413,7 +409,6 @@ static uint32_t snow_particle_tex_id; static particle_data* snow_ptcl_data; static particle_data snow_ptcl_gpu[4]; static particle_data* snow_ptcl_fallen_data; -static GLuint snow_vao; static GL::ShaderStorageBuffer snow_ssbo; static GL::ShaderStorageBuffer snow_gpu_ssbo; static GL::ShaderStorageBuffer snow_fallen_ssbo; @@ -931,7 +926,7 @@ struc_573::struc_573() : chara_index(), bone_index() { TaskEffectFogRing::Data::Data() : enable(), delta_frame(), field_8(), ring_size(), tex_id(), ptcl_size(), max_ptcls(), num_ptcls(), density(), density_offset(), ptcl_data(), num_vtx(), -field_124(), field_2B8(), field_2B9(), disp(), frame_rate_control(), vao() { +field_124(), field_2B8(), field_2B9(), disp(), frame_rate_control() { current_stage_index = -1; } @@ -1055,43 +1050,38 @@ void TaskEffectFogRing::Data::Dest() { ptcl_data = 0; } - if (vao) { - glDeleteVertexArrays(1, &vao); - vao = 0; - } - ssbo.Destroy(); - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); - rctx_ptr->render_manager.clear_pre_process(0); - rctx_ptr->draw_state.set_fog_height(false); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); + rctx_ptr->render_manager->clear_pre_process(0); + rctx_ptr->draw_state->set_fog_height(false); } void TaskEffectFogRing::Data::Disp() { if (enable && disp) - rctx_ptr->disp_manager.entry_obj_user(&mat4_identity, + rctx_ptr->disp_manager->entry_obj_user(&mat4_identity, (mdl::UserArgsFunc)draw_fog_particle, this, mdl::OBJ_TYPE_USER); } void TaskEffectFogRing::Data::Draw() { render_context* rctx = rctx_ptr; - rctx->draw_state.set_fog_height(false); + rctx->draw_state->set_fog_height(false); if (!enable || !disp) return; - rctx->draw_state.set_fog_height(true); - RenderTexture& rt = rctx->render_manager.get_render_texture(8); + rctx->draw_state->set_fog_height(true); + RenderTexture& rt = rctx->render_manager->get_render_texture(8); rt.Bind(); glViewport(0, 0, rt.color_texture->get_width_align_mip_level(), rt.color_texture->get_height_align_mip_level()); glClearColor(density_offset, density_offset, density_offset, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_USER)) - rctx->disp_manager.draw(mdl::OBJ_TYPE_USER); + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) + rctx->disp_manager->draw(mdl::OBJ_TYPE_USER); gl_state_bind_framebuffer(0); - rctx->render_manager.set_effect_texture(rt.color_texture); + rctx->render_manager->set_effect_texture(rt.color_texture); gl_state_get_error(); } @@ -1137,8 +1127,8 @@ void TaskEffectFogRing::Data::Reset() { } void TaskEffectFogRing::Data::SetStageIndices(std::vector& stage_indices) { - rctx_ptr->render_manager.clear_pre_process(0); - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); + rctx_ptr->render_manager->clear_pre_process(0); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); disp = false; current_stage_index = -1; this->stage_indices.clear(); @@ -1212,24 +1202,16 @@ void TaskEffectFogRing::Data::SetStageIndices(std::vector& stage_indice ptcl_data = 0; } - if (vao) { - glDeleteVertexArrays(1, &vao); - vao = 0; - } - ssbo.Destroy(); ptcl_data = new (force_malloc(max_ptcls)) fog_ring_data[max_ptcls]; - if (!vao) - glGenVertexArrays(1, &vao); - ssbo.Create(sizeof(for_ring_vertex_data) * max_ptcls); InitParticleData(); - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, true); - rctx_ptr->render_manager.add_pre_process(0, TaskEffectFogRing::Data::DrawStatic, this); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, true); + rctx_ptr->render_manager->add_pre_process(0, TaskEffectFogRing::Data::DrawStatic, this); } void TaskEffectFogRing::Data::DrawStatic(void* data) { @@ -1863,7 +1845,7 @@ ripple_emit::~ripple_emit() { void ripple_emit::add_draw_ripple_emit(struc_101* data) { if (data->count > 0) - rctx_ptr->disp_manager.entry_obj_user(&mat4_identity, + rctx_ptr->disp_manager->entry_obj_user(&mat4_identity, (mdl::UserArgsFunc)draw_ripple_emit, data, mdl::OBJ_TYPE_USER); } @@ -1875,11 +1857,11 @@ void ripple_emit::clear_tex() { RenderTexture* rt; float_t v5; if (use_float_ripplemap) { - rt = &rctx_ptr->render_manager.get_render_texture(j - 3); + rt = &rctx_ptr->render_manager->get_render_texture(j - 3); v5 = -0.3f; } else { - rt = &rctx_ptr->render_manager.get_render_texture(j); + rt = &rctx_ptr->render_manager->get_render_texture(j); v5 = 0.5f; } @@ -1899,8 +1881,8 @@ void ripple_emit::ctrl() { void ripple_emit::dest() { stage_param_data_ripple_storage_clear(); - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); - rctx_ptr->render_manager.clear_pre_process(0); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, false); + rctx_ptr->render_manager->clear_pre_process(0); this->ground_y = -1001.0; } @@ -1932,7 +1914,7 @@ void ripple_emit::draw() { RenderTexture* rt[3]; for (int32_t i = 0, j = 2; i < 3; i++, j++) - rt[i] = &rctx->render_manager.get_render_texture( + rt[i] = &rctx->render_manager->get_render_texture( use_float_ripplemap ? j : (j + 3)); if (update) { @@ -1950,11 +1932,11 @@ void ripple_emit::draw() { glViewport(1, 1, width - 2, height - 2); - draw_pass_set_camera(rctx_ptr); + draw_pass_set_camera(); glClear(GL_DEPTH_BUFFER_BIT); - if (rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_USER)) { + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_USER)) { gl_state_active_bind_texture_2d(7, rt[counter % 3]->GetColorTex()); - rctx->disp_manager.draw(mdl::OBJ_TYPE_USER, 0, true); + rctx->disp_manager->draw(mdl::OBJ_TYPE_USER, 0, true); gl_state_active_bind_texture_2d(7, 0); } @@ -1980,8 +1962,8 @@ void ripple_emit::draw() { if (!use_float_ripplemap) v11 += 3; - rctx->render_manager.set_effect_texture( - rctx->render_manager.get_render_texture(v11).color_texture); + rctx->render_manager->set_effect_texture( + rctx->render_manager->get_render_texture(v11).color_texture); update = false; @@ -2052,8 +2034,8 @@ void ripple_emit::set_stage_indices(std::vector& stage_indices) { counter = 0; field_BEC = 0; - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, true); - rctx_ptr->render_manager.add_pre_process(0, ripple_emit::draw_static, this); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_PRE_PROCESS, true); + rctx_ptr->render_manager->add_pre_process(0, ripple_emit::draw_static, this); field_4F0 = 18; for (struc_207& i : field_4F4) @@ -2104,7 +2086,7 @@ void ripple_emit::sub_1403584A0(RenderTexture* rt) { field_BB8.SetColorDepthTextures(ripple_tex->tex); field_BB8.Bind(); - image_filter_scale(rctx_ptr, ripple_tex->tex, rt->GetColorTex(), 1.0f); + image_filter_scale(ripple_tex->tex, rt->GetColorTex(), 1.0f); gl_state_bind_framebuffer(0); } @@ -2822,7 +2804,6 @@ void rain_particle_draw() { vec4 color = rain->color; float_t color_a = color.w; - gl_state_bind_vertex_array(rain_vao); rain_particle_scene_ubo.Bind(0); rain_particle_batch_ubo.Bind(1); rain_ssbo.Bind(0); @@ -2890,7 +2871,7 @@ void snow_particle_draw() { return; stage_param_snow* snow = stage_param_data_snow_current; - draw_pass_set_camera(rctx_ptr); + draw_pass_set_camera(); gl_state_enable_blend(); gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2910,8 +2891,8 @@ void snow_particle_draw() { mat4_transpose(&rctx_ptr->view_mat, &temp); snow_scene.g_view_world_row2 = temp.row2; - snow_scene.g_size_in_projection.x = 1.0f / (float_t)rctx_ptr->post_process.render_width; - snow_scene.g_size_in_projection.y = 1.0f / (float_t)rctx_ptr->post_process.render_height; + snow_scene.g_size_in_projection.x = 1.0f / (float_t)rctx_ptr->render.render_width[0]; + snow_scene.g_size_in_projection.y = 1.0f / (float_t)rctx_ptr->render.render_height[0]; snow_scene.g_size_in_projection.z = snow_particle_size_min; snow_scene.g_size_in_projection.w = snow_particle_size_max; snow_scene.g_state_point_attenuation = { 0.0f, 0.0f, point_attenuation, 0.0f }; @@ -2929,8 +2910,8 @@ void snow_particle_draw() { snow_particle_batch_ubo.WriteMemory(snow_batch); gl_state_active_bind_texture_2d(0, tex->tex); - gl_state_active_bind_texture_2d(1, rctx_ptr->post_process.rend_texture.GetDepthTex()); - gl_state_bind_vertex_array(snow_vao); + gl_state_active_bind_texture_2d(1, rctx_ptr->render.rend_texture[0].GetDepthTex()); + gl_state_bind_vertex_array(rctx_ptr->common_vao); uniform_value[U_SNOW_PARTICLE] = 0; shaders_ft.set(SHADER_FT_SNOW_PT); @@ -3307,7 +3288,7 @@ particle_data::particle_data() : size(), alpha(), life_time() { } -star_catalog_milky_way::star_catalog_milky_way() : vao(), sampler(), restart_index(), +star_catalog_milky_way::star_catalog_milky_way() : sampler(), restart_index(), idx_count(), longitude_degs_10(), latitude_degs_10(), longitude_offset_degs_10(), latitude_offset_degs_10(), latitude(), longitude(), uv_rec_scale_u(), uv_rec_scale_v() { reset(); @@ -3436,7 +3417,7 @@ void star_catalog_milky_way::delete_buffers() { glDeleteSamplers(1, &sampler); sampler = 0; } - + vbo.Destroy(); ebo.Destroy(); @@ -3530,7 +3511,7 @@ star_catalog_vertex::star_catalog_vertex() { } -star_catalog::star_catalog() : vao(), stage_param_data_ptr(), star_count(), star_b_count() { +star_catalog::star_catalog() : stage_param_data_ptr(), star_count(), star_b_count() { random = false; enable = true; star_tex = -1; @@ -3576,9 +3557,6 @@ void star_catalog::draw() { if (milky_way_tex) milky_way.draw(vp, model, milky_way_tex, scene_ubo); - if (!vao) - return; - star_catalog_scene_shader_data scene_shader_data = {}; mat4 temp; mat4_mul(&model, &vp, &temp); @@ -3595,7 +3573,7 @@ void star_catalog::draw() { gl_state_set_blend_func(GL_ONE, GL_ONE); gl_state_enable_depth_test(); gl_state_set_depth_mask(false); - gl_state_bind_vertex_array(vao); + gl_state_bind_vertex_array(rctx_ptr->common_vao); for (int32_t i = 0; i < 2; i++) { stage_param_star_modifiers& modifiers = stage_param_data.modifiers[i]; @@ -3636,11 +3614,6 @@ void star_catalog::free() { star_catalog_data.file_handler.reset(); star_catalog_data.milky_way.delete_buffers(); - if (star_catalog_data.vao) { - glDeleteVertexArrays(1, &star_catalog_data.vao); - star_catalog_data.vao = 0; - } - star_catalog_data.stage_param_data_ptr = 0; } @@ -3691,9 +3664,6 @@ bool star_catalog::init() { star_count = (int32_t)vec.size(); stars_ssbo.Create(sizeof(stars_buffer_data) * vec.size(), vec.data()); - - if (!vao) - glGenVertexArrays(1, &vao); } milky_way.create_default_sphere(); @@ -4052,7 +4022,7 @@ static void draw_fog_particle(render_context* rctx, TaskEffectFogRing::Data* dat texture* tex = texture_storage_get_texture(data->tex_id); if (tex) gl_state_active_bind_texture_2d(0, tex->tex); - gl_state_bind_vertex_array(data->vao); + gl_state_bind_vertex_array(rctx_ptr->common_vao); data->ssbo.Bind(0); shaders_ft.draw_arrays(GL_TRIANGLES, 0, data->num_vtx); gl_state_disable_blend(); @@ -4080,7 +4050,7 @@ static void draw_ripple_emit(render_context* rctx, struc_101* data) { int32_t size = (int32_t)(data->size + 0.5f); - RenderTexture& rt = rctx->render_manager.get_render_texture( + RenderTexture& rt = rctx->render_manager->get_render_texture( ripple_emit_data->use_float_ripplemap ? 2 : 5); int32_t width = rt.GetWidth(); int32_t height = rt.GetHeight(); @@ -4104,7 +4074,7 @@ static void draw_ripple_emit(render_context* rctx, struc_101* data) { uniform_value[U_RIPPLE] = data->ripple_uniform; uniform_value[U_RIPPLE_EMIT] = data->ripple_emit_uniform; - gl_state_bind_vertex_array(ripple_emit_vao); + gl_state_bind_vertex_array(rctx_ptr->common_vao); shaders_ft.set(SHADER_FT_RIPEMIT); ripple_emit_scene_ubo.Bind(0); ripple_emit_ssbo.Bind(0); @@ -4629,9 +4599,6 @@ static void rain_particle_init(bool change_stage) { rain_particle_free(); - if (!rain_vao) - glGenVertexArrays(1, &rain_vao); - vec3* vtx_data = force_malloc(rain_ptcl_count); for (int32_t i = 0; i < rain_ptcl_count; i++) { vec3 position; @@ -4674,11 +4641,6 @@ static void rain_particle_ctrl() { } static void rain_particle_free() { - if (rain_vao) { - glDeleteVertexArrays(1, &rain_vao); - rain_vao = 0; - } - rain_ssbo.Destroy(); rain_particle_scene_ubo.Destroy(); @@ -4686,15 +4648,9 @@ static void rain_particle_free() { } static void ripple_emit_init() { - if (!ripple_vao) - glGenVertexArrays(1, &ripple_vao); - ripple_batch_ubo.Create(sizeof(ripple_batch_shader_data)); ripple_scene_ubo.Create(sizeof(ripple_scene_shader_data)); - if (!ripple_emit_vao) - glGenVertexArrays(1, &ripple_emit_vao); - size_t max_count = 16; ripple_emit_ssbo.Create(sizeof(vec3) * max_count); @@ -4703,21 +4659,11 @@ static void ripple_emit_init() { } static void ripple_emit_free() { - if (ripple_vao) { - glDeleteVertexArrays(1, &ripple_vao); - ripple_vao = 0; - } - ripple_batch_ubo.Destroy(); ripple_scene_ubo.Destroy(); ripple_emit_ssbo.Destroy(); - if (ripple_emit_vao) { - glDeleteVertexArrays(1, &ripple_emit_vao); - ripple_emit_vao = 0; - } - ripple_emit_scene_ubo.Destroy(); } @@ -4729,7 +4675,7 @@ static void snow_particle_init(bool change_stage) { snow_particle_fallen_count = 0; snow_particle_fallen_index = 0; - int32_t render_height = rctx_ptr->post_process.render_height; + int32_t render_height = rctx_ptr->render.render_height[0]; float_t snow_particle_size = (float_t)render_height * (float_t)(1.0 / 720.0); snow_particle_size_min = snow_particle_size; snow_particle_size_mid = snow_particle_size * 31.0f; @@ -4801,9 +4747,6 @@ static void snow_particle_init(bool change_stage) { snow_particle_free(); - if (!snow_vao) - glGenVertexArrays(1, &snow_vao); - snow_ssbo.Create(sizeof(snow_particle_vertex_data) * snow->num_snow); snow_particle_gpu_vertex_data* vtx_data = force_malloc(snow_ptcl_count); @@ -5023,11 +4966,6 @@ static vec3 snow_particle_get_random_velocity() { } static void snow_particle_free() { - if (snow_vao) { - glDeleteVertexArrays(1, &snow_vao); - snow_vao = 0; - } - snow_ssbo.Destroy(); snow_gpu_ssbo.Destroy(); snow_fallen_ssbo.Destroy(); @@ -5073,7 +5011,7 @@ static void sub_1403B6F60(GLuint a1, GLuint a2, GLuint a3, ripple_emit_params& p ripple_batch.g_params = { params.wake_attn, params.speed, params.field_8, params.field_C }; ripple_batch_ubo.WriteMemory(ripple_batch); - gl_state_bind_vertex_array(ripple_vao); + gl_state_bind_vertex_array(rctx_ptr->common_vao); shaders_ft.set(SHADER_FT_RIPPLE); ripple_scene_ubo.Bind(0); ripple_batch_ubo.Bind(1); diff --git a/src/CRE/task_effect.hpp b/src/CRE/task_effect.hpp index 75b8c394..6045441f 100644 --- a/src/CRE/task_effect.hpp +++ b/src/CRE/task_effect.hpp @@ -234,7 +234,6 @@ public: int32_t current_stage_index; std::vector stage_indices; FrameRateControl* frame_rate_control; - GLuint vao; GL::ShaderStorageBuffer ssbo; Data(); diff --git a/src/KKdLib/database/stage.hpp b/src/KKdLib/database/stage.hpp index 53471e3f..19df91fe 100644 --- a/src/KKdLib/database/stage.hpp +++ b/src/KKdLib/database/stage.hpp @@ -18,10 +18,10 @@ enum stage_data_format { }; enum stage_data_flags { - STAGE_DATA_FLAG_1 = 0x1, - STAGE_DATA_LIGHT_CHARA_AMBIENT = 0x2, - STAGE_DATA_FLAG_4 = 0x4, - STAGE_DATA_FLAG_8 = 0x8, + STAGE_DATA_FLAG_1 = 0x01, + STAGE_DATA_LIGHT_CHARA_AMBIENT = 0x02, + STAGE_DATA_FLAG_4 = 0x04, + STAGE_DATA_FLAG_8 = 0x08, }; enum stage_data_reflect_resolution_mode { diff --git a/src/KKdLib/farc.cpp b/src/KKdLib/farc.cpp index 98f6dbfe..d2477b18 100644 --- a/src/KKdLib/farc.cpp +++ b/src/KKdLib/farc.cpp @@ -490,7 +490,7 @@ static void farc_pack_files(farc* f, stream& s, farc_signature signature, farc_f free_def(i.data_compressed); i.compressed = false; i.encrypted = false; - + file_stream s_t; s_t.open(temp, "rb"); if (s_t.check_null()) diff --git a/src/KKdLib/light_param/glow.hpp b/src/KKdLib/light_param/glow.hpp index e9972f9c..e1df8518 100644 --- a/src/KKdLib/light_param/glow.hpp +++ b/src/KKdLib/light_param/glow.hpp @@ -12,6 +12,7 @@ enum tone_map_method { TONE_MAP_YCC_EXPONENT = 0, TONE_MAP_RGB_LINEAR = 1, TONE_MAP_RGB_LINEAR2 = 2, + TONE_MAP_MAX = 3, }; struct light_param_glow { diff --git a/src/ReDIVA/classes/data_view/draw_task.cpp b/src/ReDIVA/classes/data_view/draw_task.cpp index 858bf48d..91dfc30f 100644 --- a/src/ReDIVA/classes/data_view/draw_task.cpp +++ b/src/ReDIVA/classes/data_view/draw_task.cpp @@ -109,7 +109,7 @@ void data_view_draw_task_imgui(class_data* data) { } render_context* rctx = data_view->rctx; - std::vector* obj = rctx->disp_manager.obj; + std::vector* obj = rctx->disp_manager->obj; auto& obj_data = data_view->obj_data; ImGuiTreeNodeFlags tree_node_base_flags = 0; diff --git a/src/ReDIVA/classes/graphics/post_process.cpp b/src/ReDIVA/classes/graphics/post_process.cpp index 9c053f2e..8d88c931 100644 --- a/src/ReDIVA/classes/graphics/post_process.cpp +++ b/src/ReDIVA/classes/graphics/post_process.cpp @@ -49,11 +49,9 @@ void graphics_post_process_imgui(class_data* data) { return; } - post_process* pp = &rctx->post_process; + rndr::Render* rend = &rctx->render; - post_process_blur* blur = pp->blur; - post_process_dof* dof = pp->dof; - post_process_tone_map* tone_map = pp->tone_map; + renderer::DOF3* dof = rend->dof; static const char* mag_filter_labels[] = { "nearest", @@ -64,27 +62,38 @@ void graphics_post_process_imgui(class_data* data) { "cone(2tap)", }; - ImGui::ColumnComboBox("MAG Filter", mag_filter_labels, POST_PROCESS_MAG_FILTER_MAX, - (int32_t*)&pp->mag_filter, 0, false, &data->imgui_focus); + ImGui::ColumnComboBox("MAG Filter", mag_filter_labels, rndr::Render::MAG_FILTER_MAX, + (int32_t*)&rend->mag_filter, 0, false, &data->imgui_focus); - ImGui::CheckboxEnterKeyPressed("Morphological AA", &pp->mlaa); + bool mlaa = !!rend->mlaa; + if (ImGui::CheckboxEnterKeyPressed("Morphological AA", &mlaa)) + rend->mlaa = mlaa ? 1 : 0; ImGui::SetColumnSpace(1.0f / 4.0f); if (ImGui::TreeNode("Tone Trans")) { vec3 tone_trans_start; vec3 tone_trans_end; - tone_map->get_tone_trans(tone_trans_start, tone_trans_end); - ImGui::ColumnSliderVec3Button("Start", &tone_trans_start, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderVec3Button("End", &tone_trans_end, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); - tone_map->set_tone_trans(tone_trans_start, tone_trans_end, 0); + bool tone_trans_change = false; + rend->get_tone_trans(tone_trans_start, tone_trans_end); + tone_trans_change |= ImGui::ColumnSliderVec3Button("Start", + &tone_trans_start, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); + tone_trans_change |= ImGui::ColumnSliderVec3Button("End", + &tone_trans_end, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); + if (tone_trans_change) + rend->set_tone_trans(tone_trans_start, tone_trans_end, 0); ImGui::TreePop(); } if (ImGui::TreeNode("Scene Fade")) { - vec4 scene_fade = tone_map->get_scene_fade(); - ImGui::ColumnSliderFloatButton("Alpha", &scene_fade.w, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderVec3Button("Color", (vec3*)&scene_fade, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); - tone_map->set_scene_fade(scene_fade, 0); + float_t scene_fade_alpha = rend->get_scene_fade_alpha(); + if (ImGui::ColumnSliderFloatButton("Alpha", + &scene_fade_alpha, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0)) + rend->set_scene_fade_alpha(scene_fade_alpha, 0); + + vec3 scene_fade_color = rend->get_scene_fade_color(); + if (ImGui::ColumnSliderVec3Button("Color", + &scene_fade_color, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0)) + rend->set_scene_fade_color(scene_fade_color, 0); const char* scene_fade_blend_func_labels[] = { "0: OVER", @@ -92,10 +101,10 @@ void graphics_post_process_imgui(class_data* data) { "2: PLUS", }; - int32_t scene_fade_blend_func = tone_map->get_scene_fade_blend_func(); - ImGui::ColumnComboBox("Blend Func", scene_fade_blend_func_labels, 3, - &scene_fade_blend_func, 0, false, &data->imgui_focus); - tone_map->set_scene_fade_blend_func(scene_fade_blend_func, 0); + int32_t scene_fade_blend_func = rend->get_scene_fade_blend_func(); + if (ImGui::ColumnComboBox("Blend Func", scene_fade_blend_func_labels, 3, + &scene_fade_blend_func, 0, false, &data->imgui_focus)) + rend->set_scene_fade_blend_func(scene_fade_blend_func, 0); ImGui::TreePop(); } @@ -106,46 +115,58 @@ void graphics_post_process_imgui(class_data* data) { "RGB LINEAR2", }; - int32_t _tone_map_method = tone_map->get_tone_map_method(); - ImGui::ColumnComboBox("Tone Map", tone_map_method_labels, 3, - &_tone_map_method, 0, false, &data->imgui_focus); - tone_map->set_tone_map_method((tone_map_method)_tone_map_method); + tone_map_method tone_map_method = rend->get_tone_map(); + if (ImGui::ColumnComboBox("Tone Map", tone_map_method_labels, TONE_MAP_MAX, + (int32_t*)&tone_map_method, 0, false, &data->imgui_focus)) + rend->set_tone_map(tone_map_method); - float_t exposure = tone_map->get_exposure(); - ImGui::ColumnSliderFloatButton("Exposure", &exposure, 0.02f, 0.0f, 4.0f, 0.1f, "%.2f", 0); - exposure = prj::roundf(exposure / 0.02f) * 0.02f; - tone_map->set_exposure(exposure); + float_t exposure = rend->get_exposure(); + if (ImGui::ColumnSliderFloatButton("Exposure", + &exposure, 0.02f, 0.0f, 4.0f, 0.1f, "%.2f", 0)) { + exposure = prj::roundf(exposure / 0.02f) * 0.02f; + rend->set_exposure(exposure); + } - bool auto_exposure = tone_map->get_auto_exposure(); - ImGui::CheckboxEnterKeyPressed("Auto Exposure", &auto_exposure); - tone_map->set_auto_exposure(auto_exposure); + bool auto_exposure = rend->get_auto_exposure(); + if (ImGui::CheckboxEnterKeyPressed("Auto Exposure", &auto_exposure)) + rend->set_auto_exposure(auto_exposure); - float_t gamma = tone_map->get_gamma(); - ImGui::ColumnSliderFloatButton("Gamma", &gamma, 0.01f, 0.2f, 2.2f, 0.1f, "%.2f", 0); - tone_map->set_gamma(gamma); + float_t gamma = rend->get_gamma(); + if (ImGui::ColumnSliderFloatButton("Gamma", &gamma, 0.01f, 0.2f, 2.2f, 0.1f, "%.2f", 0)) + rend->set_gamma(gamma); - int32_t saturate1 = tone_map->get_saturate_power(); - ImGui::ColumnSliderIntButton("Saturate1", &saturate1, 1, 6, "%d", 0); - tone_map->set_saturate_power(saturate1); + int32_t saturate1 = rend->get_saturate_power(); + if (ImGui::ColumnSliderIntButton("Saturate1", &saturate1, 1, 6, "%d", 0)) + rend->set_saturate_power(saturate1); - float_t saturate2 = tone_map->get_saturate_coeff(); - ImGui::ColumnSliderFloatButton("Saturate2", &saturate2, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0); - tone_map->set_saturate_coeff(saturate2, 0, false); + float_t saturate2 = rend->get_saturate_coeff(); + if (ImGui::ColumnSliderFloatButton("Saturate2", &saturate2, 0.01f, 0.0f, 1.0f, 0.1f, "%.2f", 0)) + rend->set_saturate_coeff(saturate2, 0, false); ImGui::TreePop(); } if (ImGui::TreeNodeEx("Glare", ImGuiTreeNodeFlags_DefaultOpen)) { - vec3 radius = blur->get_radius(); - ImGui::ColumnSliderFloatButton("Radius R", &radius.x, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderFloatButton("Radius G", &radius.y, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderFloatButton("Radius B", &radius.z, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); - blur->set_radius(radius); + vec3 radius = rend->get_radius(); + bool radius_change = false; + radius_change |= ImGui::ColumnSliderFloatButton("Radius R", + &radius.x, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); + radius_change |= ImGui::ColumnSliderFloatButton("Radius G", + &radius.y, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); + radius_change |= ImGui::ColumnSliderFloatButton("Radius B", + &radius.z, 0.1f, 1.0f, 3.0f, 0.1f, "%.2f", 0); + if (radius_change) + rend->set_radius(radius); - vec3 intensity = blur->get_intensity(); - ImGui::ColumnSliderFloatButton("Inten R", &intensity.x, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderFloatButton("Inten G", &intensity.y, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); - ImGui::ColumnSliderFloatButton("Inten B", &intensity.z, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); - blur->set_intensity(intensity); + vec3 intensity = rend->get_intensity(); + bool intensity_change = false; + intensity_change |= ImGui::ColumnSliderFloatButton("Inten R", + &intensity.x, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); + intensity_change |= ImGui::ColumnSliderFloatButton("Inten G", + &intensity.y, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); + intensity_change |= ImGui::ColumnSliderFloatButton("Inten B", + &intensity.z, 0.05f, 0.0f, 2.0f, 0.1f, "%.2f", 0); + if (intensity_change) + rend->set_intensity(intensity); ImGui::TreePop(); } ImGui::SetDefaultColumnSpace(); diff --git a/src/ReDIVA/data_test/auth_3d_test.cpp b/src/ReDIVA/data_test/auth_3d_test.cpp index 08555faf..e3c29a04 100644 --- a/src/ReDIVA/data_test/auth_3d_test.cpp +++ b/src/ReDIVA/data_test/auth_3d_test.cpp @@ -395,7 +395,7 @@ bool Auth3dTestTask::Init() { obj_sets.clear(); obj_sets.shrink_to_fit(); - rctx_ptr->render_manager.shadow_ptr->self_shadow = true; + shadow_ptr_get()->self_shadow = true; clear_color = 0x00999999; auth_3d_test_window_init(); task_stage_load_task("A3D_STAGE"); @@ -456,7 +456,7 @@ bool Auth3dTestTask::Dest() { task_stage_unload_task(); auth_3d_test_window->Hide(); clear_color = color_black; - rctx_ptr->render_manager.shadow_ptr->self_shadow = true; + shadow_ptr_get()->self_shadow = true; if (category.size()) auth_3d_data_unload_category(category.c_str()); category.clear(); @@ -479,7 +479,7 @@ void Auth3dTestTask::Disp() { etc.color = 0xFFFFFFFF; etc.data.plane.w = 20; etc.data.plane.h = 20; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc); } } @@ -1158,7 +1158,7 @@ Auth3dTestWindow::SelectionButtonShadowType::~SelectionButtonShadowType() { void Auth3dTestWindow::SelectionButtonShadowType::Callback(dw::SelectionListener::CallbackData* data) { dw::Button* button = dynamic_cast(data->widget); if (button) - rctx_ptr->render_manager.shadow_ptr->self_shadow = !!button->callback_data.i64; + shadow_ptr_get()->self_shadow = !!button->callback_data.i64; } Auth3dTestWindow::SelectionButtonSave::SelectionButtonSave() { diff --git a/src/ReDIVA/data_test/glitter_test.cpp b/src/ReDIVA/data_test/glitter_test.cpp index f5fb859f..f494fcbe 100644 --- a/src/ReDIVA/data_test/glitter_test.cpp +++ b/src/ReDIVA/data_test/glitter_test.cpp @@ -179,7 +179,7 @@ void TaskDataTestGlitterParticle::Disp() { etc.data.grid.h = 50; etc.data.grid.ws = 50; etc.data.grid.hs = 50; - rctx_ptr->disp_manager.entry_obj_etc(&mat4_identity, &etc); + rctx_ptr->disp_manager->entry_obj_etc(&mat4_identity, &etc); } int32_t life_time = 0; diff --git a/src/ReDIVA/glitter_editor.cpp b/src/ReDIVA/glitter_editor.cpp index cd1e9002..1752c36a 100644 --- a/src/ReDIVA/glitter_editor.cpp +++ b/src/ReDIVA/glitter_editor.cpp @@ -2055,12 +2055,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_f2( etc.constant = true; etc.data.cube.size = vec3::max(emit_inst->data.box.size * scale, 0.1f); etc.data.cube.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.cube.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_CYLINDER: { @@ -2074,12 +2074,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_f2( etc.data.cylinder.slices = 16; etc.data.cylinder.stacks = 1; etc.data.cylinder.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.cylinder.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_SPHERE: { @@ -2091,12 +2091,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_f2( etc.data.sphere.slices = 16; etc.data.sphere.stacks = 16; etc.data.sphere.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.sphere.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_POLYGON: { @@ -2106,11 +2106,11 @@ static void glitter_editor_draw_emitter_type_emitter_inst_f2( etc.constant = true; etc.data.line.pos[0] = vec3(-emit_inst->data.polygon.size * scale.x * 0.5f, 0.0f, 0.0f); etc.data.line.pos[1] = vec3(emit_inst->data.polygon.size * scale.x * 0.5f, 0.0f, 0.0f); - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; } @@ -2151,12 +2151,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_x( etc.constant = true; etc.data.cube.size = vec3::max(emit_inst->data.box.size * scale, 0.1f); etc.data.cube.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.cube.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_CYLINDER: { @@ -2170,12 +2170,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_x( etc.data.cylinder.slices = 16; etc.data.cylinder.stacks = 1; etc.data.cylinder.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.cylinder.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_SPHERE: { @@ -2187,12 +2187,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_x( etc.data.sphere.slices = 16; etc.data.sphere.stacks = 16; etc.data.sphere.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.sphere.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; case Glitter::EMITTER_POLYGON: { @@ -2206,12 +2206,12 @@ static void glitter_editor_draw_emitter_type_emitter_inst_x( etc.data.cylinder.slices = 16; etc.data.cylinder.stacks = 0; etc.data.cylinder.wire = false; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); if (glt_edt->draw_flags & GLITTER_EDITOR_DISP_WIREFRAME) { etc.color = 0xFF000000; etc.data.cylinder.wire = true; - rctx_ptr->disp_manager.entry_obj_etc(&mat, &etc, local); + rctx_ptr->disp_manager->entry_obj_etc(&mat, &etc, local); } } break; } @@ -2307,7 +2307,7 @@ static void glitter_editor_disp_wireframe_render_scene(GlitterEditor* glt_edt, || rend_group->blend_mode == Glitter::PARTICLE_BLEND_TYPICAL) emission = rend_group->emission; - Glitter::BatchShaderData shader_data = {}; + glitter_batch_shader_data shader_data = {}; mat4_transpose(&mat, &mat); shader_data.g_mvp[0] = mat.row0; shader_data.g_mvp[1] = mat.row1; @@ -2316,10 +2316,10 @@ static void glitter_editor_disp_wireframe_render_scene(GlitterEditor* glt_edt, 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 }; - GPM_VAL->batch_ubo.WriteMemory(shader_data); + rctx_ptr->glitter_batch_ubo.WriteMemory(shader_data); shaders_dev.set(SHADER_DEV_GLITTER_PT_WIREFRAME); - GPM_VAL->batch_ubo.Bind(2); + rctx_ptr->glitter_batch_ubo.Bind(2); switch (rend_group->type) { case Glitter::PARTICLE_QUAD: gl_state_bind_vertex_array(rend_group->vao); diff --git a/src/ReDIVA/input_state.cpp b/src/ReDIVA/input_state.cpp index 519af9c6..7a8df8a3 100644 --- a/src/ReDIVA/input_state.cpp +++ b/src/ReDIVA/input_state.cpp @@ -612,10 +612,10 @@ static bool sub_140190A30(struc_794* a1, int32_t index) { float_t x_scale = 1280.0f / (float_t)BAKE_BASE_WIDTH; float_t y_scale = 720.0f / (float_t)BAKE_BASE_HEIGHT; #else - int32_t x_offset = rctx_ptr->post_process.screen_x_offset; - int32_t y_offset = rctx_ptr->post_process.screen_y_offset; - float_t x_scale = 1280.0f / (float_t)rctx_ptr->post_process.sprite_width; - float_t y_scale = 720.0f / (float_t)rctx_ptr->post_process.sprite_height; + int32_t x_offset = rctx_ptr->screen_x_offset; + int32_t y_offset = rctx_ptr->screen_y_offset; + float_t x_scale = 1280.0f / (float_t)rctx_ptr->sprite_width; + float_t y_scale = 720.0f / (float_t)rctx_ptr->sprite_height; #endif a1->field_30[8] = (int32_t)((float_t)(Input::pos.x - x_offset) * x_scale); diff --git a/src/ReDIVA/main.cpp b/src/ReDIVA/main.cpp index 6a799abb..165e9b29 100644 --- a/src/ReDIVA/main.cpp +++ b/src/ReDIVA/main.cpp @@ -1069,6 +1069,196 @@ void process_edit_dsc() { free(dsc_data); }*/ +/*void scan_arguments(int32_t argc, wchar_t** argv) { + std::vector arguments; + arguments.assign(argv + 1, argv + argc); + + bool show_help = false; + auto i_begin = arguments.begin(); + auto i_end = arguments.end(); + for (auto i = i_begin; i != i_end; i++) { + if (i->find(L"-", 0, 1)) + continue; + + if (!i->compare(L"--help")) + show_help = true; + else if (!i->compare(L"-debug")) + stru_140EDA5B0.debug = 1; + else if (!i->compare(L"-t")) + test_mode_set(1); + else if (!i->compare(L"-m")) { + if (++i == i_end) + break; + + stru_140EDA5B0.mode = _wtoi(i->c_str()); + } + else if (!i->compare(L"-s")) { + if (++i == i_end) + break; + + stru_140EDA5B0.sub_mode = _wtoi(i->c_str()); + } + else if (!i->compare(L"-sm") || !i->compare(L"--start-up-mode")) { + if (++i == i_end) + break; + + if (i->compare(L"server")) + stru_140EDA5B0.field_1C = 0; + else + stru_140EDA5B0.field_1C = 1; + } + else if (!i->compare(L"-ve")) + stru_140EDA5B0.vsync_emulation = 1; + else if (!i->compare(L"-fs") || !i->compare(L"-f")) + stru_140EDA5B0.full_screen = 1; + else if (!i->compare(L"-w")) + stru_140EDA5B0.full_screen = 0; + else if (!i->compare(L"-aa")) + stru_140EDA5B0.ssaa = 1; + else if (!i->compare(L"-qvga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_QVGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-vga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_VGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-wvga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_WVGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-svga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_SVGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-xga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_XGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-wxga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_WXGA; + stru_140EDA5B0.hd_res = 1; + } + else if (!i->compare(L"-wxga_dbd")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_WXGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-uxga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_UXGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-wuxga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_WUXGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-wqxga")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_WQXGA; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-hdtv720")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_HD; + stru_140EDA5B0.hd_res = 1; + } + else if (!i->compare(L"-hdtv720_dbd")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_HD; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-hdtv1080")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_FHD; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-wqhd")) { + stru_140EDA5B0.res_launch = RESOLUTION_MODE_QHD; + stru_140EDA5B0.hd_res = 0; + } + else if (!i->compare(L"-ss")) { + if (++i == i_end) + break; + + stru_140EDA5B0.screen_shot = 1; + stru_140EDA5B0.field_80 = 0; + stru_140EDA5B0.field_40.assign(*i); + stru_140EDA5B0.field_60.assign(stru_140EDA5B0.field_40); + stru_140EDA5B0.ssaa = 1; + } + else if (!i->compare(L"-no_aa")) { + stru_140EDA5B0.ssaa = 0; + continue; + } + else if (!i->compare(L"-ssformat")) { + if (++i == i_end) + break; + + if (!i->compare(L"ppm")) + stru_140EDA5B0.ss_format = 0; + else if (!i->compare(L"bmp")) + stru_140EDA5B0.ss_format = 1; + else if (!i->compare(L"tga")) + stru_140EDA5B0.ss_format = 2; + else if (!i->compare(L"yuy2")) + stru_140EDA5B0.ss_format = 3; + else if (!i->compare(L"jpg")) + stru_140EDA5B0.ss_format = 4; + } + else if (!i->compare(L"-ss4x")) { + if (++i == i_end) + break; + + stru_140EDA5B0.screen_shot = 1; + stru_140EDA5B0.field_80 = 0; + stru_140EDA5B0.field_40.assign(*i); + stru_140EDA5B0.field_60.assign(stru_140EDA5B0.field_40); + stru_140EDA5B0.screen_shot_4x = 1; + stru_140EDA5B0.ssaa = 1; + } + else if (!i->compare(L"-ss36x")); + else if (i->compare(L"-ssalphamask")) + stru_140EDA5B0.ss_alpha_mask = 1; + else if (!i->compare(L"-fix_pv_timer")) + stru_140EDA5B0.fix_pv_timer = 1; + else if (!i->compare(L"-ps3")) + stru_140EDA5B0.ps3 = 1; + else if (!i->compare(L"-dev_rom")) + stru_140EDA5B0.dev_rom = 1; + else if (!i->compare(L"-pv_full_open")) + stru_140EDA5B0.pv_full_open = 1; + else if (!i->compare(L"-no_local_rom")) + stru_140EDA5B0.local_rom = 0; + else if (!i->compare(L"-pcv")) + stru_140EDA5B0.pcv = 1; + } + + sub_140558EB0(screen_shot_impl_ptr, stru_140EDA5B0.ss_format); + if (stru_140EDA5B0.ssaa || stru_140EDA5B0.screen_shot) + stru_140EDA5B0.hd_res = 0; + + if (show_help) { + printf("Usage: %ls [option]...\n", *argv); + printf("\t--help Disp Usage\n"); + printf("\t-debug Debug Mode(use gdb)\n"); + printf("\t-t Test Mode Start\n"); + printf("\t-m Mode No\n"); + printf("\t-s Sub Mode No\n"); + printf("\t-sm Sub Mode No\n"); + printf("\t-ss Screen Shot\n"); + printf("\t-ss4x Screen Shot (4x screen size)\n"); + printf("\t-ssformat Screen Shot file format\n"); + printf("\t-ssalphamask Enable Chara Alpha Mask\n"); + printf("\t-ve <0|1> Use Vsync Emulation\n"); + printf("\t-fs Full Screen Mode\n"); + printf("\t-f Full Screen Mode\n"); + printf("\t-w Window Mode\n"); + printf("\t-ps3 Use rom_ps3 Data\n"); + printf("\t-aa Enable Anti-Alias\n"); + printf("\t-vga VGA(640x480) Mode\n"); + printf("\t-xga XGA(1024x768) Mode\n"); + printf("\t-wxga WXGA(1280x768) Mode\n"); + printf("\t-wxga_dbd WXGA(1280x768) dot by dot Mode\n"); + printf("\t-wxga2 WXGA(1360x768) Mode\n"); + exit(0); + } +}*/ + int32_t wmain(int32_t argc, wchar_t** argv) { /*#if defined(ReDIVA_DEV) if (argc >= 2 && !wcscmp(argv[1], L"--compile-spir-v")) { diff --git a/src/ReDIVA/pv_game/pv_game.cpp b/src/ReDIVA/pv_game/pv_game.cpp index f1a1ed44..6e9289f1 100644 --- a/src/ReDIVA/pv_game/pv_game.cpp +++ b/src/ReDIVA/pv_game/pv_game.cpp @@ -1188,13 +1188,13 @@ void pv_game::change_field(size_t field, ssize_t dsc_time, ssize_t curr_time) { task_stage_current_set_stage_display(false, true); light_param_data_storage_data_set_pv_cut((int32_t)field); - rctx_ptr->render_manager.set_npr_param(next_field_data.npr_type); - //rctx_ptr->post_process.set_cam_blur(next_field_data.cam_blur); + rctx_ptr->render_manager->set_npr_param(next_field_data.npr_type); + //rctx_ptr->render.set_cam_blur(next_field_data.cam_blur); if (next_field_data.sdw_off) - rctx_ptr->render_manager.set_shadow_false(); + rctx_ptr->render_manager->set_shadow_false(); else - rctx_ptr->render_manager.set_shadow_true(); + rctx_ptr->render_manager->set_shadow_true(); bool disp_front = true; bool disp_front_low = true; @@ -2580,7 +2580,11 @@ bool pv_game::load() { i.rob_chr = rob_chara_array_get(i.chara_id); } - rctx_ptr->render_manager.set_effect_texture(0); + if (data.pv->get_performer_count() < 2) + rctx_ptr->render.update_res(false, 1); + else + rctx_ptr->render.update_res(false, 2); + rctx_ptr->render_manager->set_effect_texture(0); state = 12; return false; } @@ -2653,7 +2657,11 @@ bool pv_game::load() { i.rob_chr = rob_chara_array_get(i.chara_id); } - rctx_ptr->render_manager.set_effect_texture(0); + if (data.pv->get_performer_count() < 2) + rctx_ptr->render.update_res(false, 1); + else + rctx_ptr->render.update_res(false, 2); + rctx_ptr->render_manager->set_effect_texture(0); state = 3; } return false; case 3: { @@ -3152,7 +3160,7 @@ bool pv_game::load() { for (const pv_db_pv_frame_texture& i : get_pv_db_pv()->frame_texture) if (i.data.size()) { data.has_frame_texture = true; - rctx_ptr->post_process.frame_texture_reset(); + rctx_ptr->render.frame_texture_reset(); break; } } @@ -3474,12 +3482,12 @@ bool pv_game::load() { state = 12; } break; case 12: { - post_process& pp = rctx_ptr->post_process; + rndr::Render& rend = rctx_ptr->render; int32_t frame_texture_slot = 0; for (const pv_db_pv_frame_texture& i : data.pv->frame_texture) { texture* tex = texture_storage_get_texture(aft_tex_db->get_texture_id(i.data.c_str())); if (tex) - pp.frame_texture_load(frame_texture_slot, (post_process_frame_texture_type)i.type, tex); + rend.frame_texture_load(frame_texture_slot, (rndr::Render::FrameTextureType)i.type, tex); frame_texture_slot++; } @@ -3691,7 +3699,7 @@ bool pv_game::load() { if (sub_14013C8C0()->sub_1400E7910() < 4) data.pv_data.get_target_target_count(0, 0.0f, true); } - rctx_ptr->disp_manager.object_culling = false; + rctx_ptr->disp_manager->object_culling = false; state = 22; } break; case 22: { @@ -3833,11 +3841,11 @@ bool pv_game::load() { data.play_data.free_aet_title_image(); data.title_image_state = 0; Glitter::glt_particle_manager->counter = 0; - rctx_ptr->disp_manager.object_culling = true; + rctx_ptr->disp_manager->object_culling = true; loaded = true; state = false; //sel_vocal_change_get()->DelTask(); - rctx_ptr->render_manager.set_effect_texture(0); + rctx_ptr->render_manager->set_effect_texture(0); pv_param_task::post_process_task_add_task(); } return true; } @@ -4461,19 +4469,19 @@ bool pv_game::unload() { data.field_2CF30 = 4; - post_process& pp = rctx_ptr->post_process; + rndr::Render& rend = rctx_ptr->render; int32_t frame_texture_slot = 0; for (const pv_db_pv_frame_texture& i : data.pv->frame_texture) { if (i.data.size()) { texture* tex = texture_storage_get_texture(aft_tex_db->get_texture_id(i.data.c_str())); if (tex) - pp.frame_texture_unload(frame_texture_slot, tex); + rend.frame_texture_unload(frame_texture_slot, tex); } frame_texture_slot++; } if (data.has_frame_texture) { - rctx_ptr->post_process.frame_texture_free(); + rend.frame_texture_free(); data.has_frame_texture = false; } @@ -4666,19 +4674,17 @@ bool pv_game::unload() { light_param_data_storage_data_reset(); - post_process& pp = rctx_ptr->post_process; - pp.tone_map->reset_saturate_coeff(0, true); + rndr::Render& rend = rctx_ptr->render; + rend.reset_saturate_coeff(0, true); dof_pv_set(); - pp.tone_map->reset_scene_fade(0); + rend.reset_scene_fade(0); - /*if (!sub_140192E20()) - post_process_set_taa(&pp, 1);*/ + rend.set_taa(1); + rend.update_res(0, -1); - //sub_1404A9480(&pp, 0, -1); - - rctx_ptr->disp_manager.object_culling = true; - rctx_ptr->render_manager.shadow_ptr->range = 1.0f; - rctx_ptr->render_manager.set_effect_texture(0); + rctx_ptr->disp_manager->object_culling = true; + shadow_ptr_get()->range = 1.0f; + rctx_ptr->render_manager->set_effect_texture(0); sound_work_reset_all_se(); @@ -4763,7 +4769,7 @@ int32_t pv_game::sub_1400FC780(float_t delta_time) { //task_mask_screen_fade_out(0.75f, 0); } - rctx_ptr->post_process.tone_map->set_exposure(0.0f); + rctx_ptr->render.set_exposure(0.0f); if (data.play_data.get_aet_next_info_disp()) return 0; diff --git a/src/ReDIVA/pv_game/pv_game_pv_data.cpp b/src/ReDIVA/pv_game/pv_game_pv_data.cpp index 776c0064..c6377627 100644 --- a/src/ReDIVA/pv_game/pv_game_pv_data.cpp +++ b/src/ReDIVA/pv_game/pv_game_pv_data.cpp @@ -253,8 +253,8 @@ void pv_scene_fade::ctrl(float_t delta_time) { end = false; } - rctx_ptr->post_process.tone_map->set_scene_fade_color(color, 1); - rctx_ptr->post_process.tone_map->set_scene_fade_alpha(alpha, 1); + rctx_ptr->render.set_scene_fade_color(color, 1); + rctx_ptr->render.set_scene_fade_alpha(alpha, 1); if (end) reset(); @@ -1307,7 +1307,7 @@ bool pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, playdata->shadow = enable == 1; - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) if (chara_id == 1) shad->blur_filter_enable[1] = playdata->shadow; @@ -1540,17 +1540,17 @@ bool pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, end.y = (float_t)data[4] * 0.001f; end.z = (float_t)data[5] * 0.001f; - rctx_ptr->post_process.tone_map->set_tone_trans(start, end, 1); + rctx_ptr->render.set_tone_trans(start, end, 1); } break; case DSC_FT_SATURATE: { float_t saturate_coeff = (float_t)data[0] * 0.001f; - rctx_ptr->post_process.tone_map->set_saturate_coeff(saturate_coeff, 1, false); + rctx_ptr->render.set_saturate_coeff(saturate_coeff, 1, false); } break; case DSC_FT_FADE_MODE: { int32_t blend_func = data[0]; - rctx_ptr->post_process.tone_map->set_scene_fade_blend_func(blend_func, 1); + rctx_ptr->render.set_scene_fade_blend_func(blend_func, 1); } break; case DSC_FT_AUTO_BLINK: { chara_id = data[0]; @@ -1857,7 +1857,7 @@ bool pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, case DSC_FT_SHADOW_RANGE: { float_t range = (float_t)data[0] * 0.001f; - rctx_ptr->render_manager.shadow_ptr->range = range; + shadow_ptr_get()->range = range; } break; case DSC_FT_HAND_SCALE: { chara_id = data[0]; @@ -1938,19 +1938,19 @@ bool pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, int32_t enable = data[0]; if (pv_game->data.pv) - rctx_ptr->post_process.frame_texture_cont_capture_set(enable == 1); + rctx_ptr->render.frame_texture_cont_capture_set(enable == 1); } break; case DSC_FT_MAN_CAP: { int32_t slot = data[0]; if (pv_game->data.pv && slot >= 0 && slot <= 4) - rctx_ptr->post_process.frame_texture_slot_capture_set(slot + 1); + rctx_ptr->render.frame_texture_slot_capture_set(slot + 1); } break; case DSC_FT_TOON: { int32_t npr_param = data[0]; int32_t value = data[1]; - rctx_ptr->render_manager.set_npr_param(npr_param); + rctx_ptr->render_manager->set_npr_param(npr_param); if (npr_param == 1) if (value > 0) npr_cloth_spec_color.w = (float_t)(value - 1) * 0.1f; @@ -2444,7 +2444,7 @@ void pv_game_pv_data::init(::pv_game* pv_game, bool music_play) { sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); find_set_motion(diff); - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) { shad->blur_filter_enable[0] = true; shad->blur_filter_enable[1] = true; @@ -2541,12 +2541,11 @@ void pv_game_pv_data::reset_camera_post_process() { cam->set_ignore_fov(false); cam->set_fov(32.2673416137695f); - post_process* pp = &rctx_ptr->post_process; - pp->tone_map->reset_scene_fade(1); - pp->tone_map->reset_tone_trans(1); - pp->tone_map->reset_saturate_coeff(1, 1); + rctx_ptr->render.reset_scene_fade(1); + rctx_ptr->render.reset_tone_trans(1); + rctx_ptr->render.reset_saturate_coeff(1, 1); - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) for (bool& i : shad->blur_filter_enable) i = true; diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 32a8c8e0..9ce0ff34 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -17,7 +17,6 @@ #include "../CRE/clear_color.hpp" #include "../CRE/customize_item_table.hpp" #include "../CRE/data.hpp" -#include "../CRE/fbo.hpp" #include "../CRE/file_handler.hpp" #include "../CRE/font.hpp" #include "../CRE/gl_state.hpp" @@ -31,6 +30,8 @@ #include "../CRE/pv_db.hpp" #include "../CRE/pv_expression.hpp" #include "../CRE/random.hpp" +#include "../CRE/render.hpp" +#include "../CRE/render_manager.hpp" #include "../CRE/shader.hpp" #include "../CRE/shader_dev.hpp" #include "../CRE/shader_ft.hpp" @@ -42,7 +43,6 @@ #include "../CRE/task.hpp" #include "../CRE/task_effect.hpp" #include "../CRE/texture.hpp" -#include "../CRE/post_process.hpp" #include "../KKdLib/database/item_table.hpp" #include "../KKdLib/timer.hpp" #include "../KKdLib/sort.hpp" @@ -345,7 +345,7 @@ void draw_pass_3d_grid(render_context* rctx) { shaders_ft.set(SHADER_FT_GRID); rctx->obj_scene_ubo.Bind(0); gl_state_bind_vertex_array(render->grid_vao); - glDrawArrays(GL_LINES, 0, (GLsizei)grid_vertex_count); + shaders_ft.draw_arrays(GL_LINES, 0, (GLsizei)grid_vertex_count); gl_state_use_program(0); gl_state_disable_depth_test(); @@ -566,7 +566,6 @@ static render_context* render_context_load() { rctx_ptr = rctx; gl_state_get(); - render_texture_data_init(); data_struct* aft_data = &data_list[DATA_AFT]; aet_database* aft_aet_db = &aft_data->data_ft.aet_db; @@ -596,6 +595,13 @@ static render_context* render_context_load() { game_state_init(); + render_manager_init_data(0, 0, 0, false); + /*render_manager_init_data( + stru_140EDA5B0.ssaa, + stru_140EDA5B0.hd_res, + stru_140EDA5B0.ss_alpha_mask, + stru_140EDA5B0.screen_shot_4x == 1);*/ + object_storage_init(aft_obj_db); stage_param_data_storage_init(); pv_expression_file_storage_init(); @@ -913,17 +919,15 @@ static render_context* render_context_load() { render_resize_fb(rctx, false); - rctx->post_process.init_fbo(internal_3d_res.x, internal_3d_res.y, + rctx->resize(internal_3d_res.x, internal_3d_res.y, internal_2d_res.x, internal_2d_res.y, width, height); - rctx->render_manager.resize(internal_2d_res.x, internal_2d_res.y); - rctx->litproj->resize(internal_3d_res.x, internal_3d_res.y); - sprite_manager_set_res((double_t)internal_2d_res.x / (double_t)internal_2d_res.y, - internal_2d_res.x, internal_2d_res.y); rctx->camera->initialize(aspect); render_resize_fb(rctx, true); + rctx->init(); + Glitter::glt_particle_manager_add_task(); for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) @@ -1161,7 +1165,7 @@ static void render_context_disp(render_context* rctx) { glViewport(0, 0, internal_3d_res.x, internal_3d_res.y); - rctx->post_process.rend_texture.Bind(); + rctx->render.rend_texture[0].Bind(); gl_state_set_depth_mask(GL_TRUE); glClearBufferfv(GL_COLOR, 0, color_clear); glClearBufferfv(GL_DEPTH, 0, &depth_clear); @@ -1172,17 +1176,17 @@ static void render_context_disp(render_context* rctx) { rctx->disp(); #if BAKE_PNG || BAKE_VIDEO - fbo::blit(rctx->post_process.screen_texture.fbos[0], 0, - 0, 0, rctx->post_process.sprite_width, rctx->post_process.sprite_height, - 0, 0, rctx->post_process.screen_width, rctx->post_process.screen_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + fbo_blit(rctx->screen_texture.fbos[0], 0, + 0, 0, rctx->sprite_width, rctx->sprite_height, + 0, 0, rctx->screen_width, rctx->screen_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); #else - fbo::blit(rctx->post_process.screen_texture.fbos[0], 0, - 0, 0, rctx->post_process.sprite_width, rctx->post_process.sprite_height, - rctx->post_process.screen_x_offset, rctx->post_process.screen_y_offset, - rctx->post_process.sprite_width, rctx->post_process.sprite_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + fbo_blit(rctx->screen_buffer.fbos[0], 0, + 0, 0, rctx->sprite_width, rctx->sprite_height, + rctx->screen_x_offset, rctx->screen_y_offset, + rctx->sprite_width, rctx->sprite_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); #endif - glViewport(0, 0, rctx->post_process.screen_width, rctx->post_process.screen_height); + glViewport(0, 0, rctx->screen_width, rctx->screen_height); classes_process_disp(classes, classes_count); if (draw_imgui) @@ -1210,6 +1214,9 @@ static void render_context_dispose(render_context* rctx) { render->unload_common_data(); Glitter::glt_particle_manager_del_task(); + + rctx->free(); + task_auth_3d_del_task(); aet_manager_del_task(); task_pv_db_del_task(); @@ -1270,6 +1277,8 @@ static void render_context_dispose(render_context* rctx) { auth_3d_test_task_free(); data_test_sel_free(); + render_manager_free_data(); + dw_free(); Glitter::glt_particle_manager_free(); @@ -1306,8 +1315,6 @@ static void render_context_dispose(render_context* rctx) { app::task_work_free(); - render_texture_data_free(); - delete rctx; file_handler_storage_free(); @@ -1393,10 +1400,7 @@ static void render_resize_fb_glfw(GLFWwindow* window, int32_t w, int32_t h) { } static void render_resize_fb(render_context* rctx, bool change_fb) { - if (internal_3d_res.x < 20) - internal_3d_res.x = 20; - if (internal_3d_res.y < 20) - internal_3d_res.y = 20; + internal_3d_res = vec2i::max(internal_3d_res, 20); double_t res_width = (double_t)width; double_t res_height = (double_t)height; @@ -1428,14 +1432,9 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { old_internal_2d_res = internal_2d_res; old_internal_3d_res = internal_3d_res; - if (fb_changed && change_fb) { - rctx->post_process.init_fbo(internal_3d_res.x, internal_3d_res.y, + if (fb_changed && change_fb) + rctx->resize(internal_3d_res.x, internal_3d_res.y, internal_2d_res.x, internal_2d_res.y, width, height); - rctx->render_manager.resize(internal_2d_res.x, internal_2d_res.y); - rctx->litproj->resize(internal_3d_res.x, internal_3d_res.y); - sprite_manager_set_res((double_t)internal_2d_res.x / (double_t)internal_2d_res.y, - internal_2d_res.x, internal_2d_res.y); - } } static void render_imgui_context_menu(classes_data* classes, diff --git a/src/ReDIVA/system_startup.cpp b/src/ReDIVA/system_startup.cpp index ca220f45..2477ec80 100644 --- a/src/ReDIVA/system_startup.cpp +++ b/src/ReDIVA/system_startup.cpp @@ -59,7 +59,7 @@ namespace system_startup_detail { system_startup.state = 4; break; case 4: - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_3D, false); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_3D, false); task_pv_game_init_test_pv(); system_startup.state = 5; break; @@ -76,7 +76,7 @@ namespace system_startup_detail { system_startup.state = 8; break; case 8: - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_3D, true); + rctx_ptr->render_manager->set_pass_sw(rndr::RND_PASSID_3D, true); system_startup_ready = 1; break; } diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 3bcc82d2..21cc8828 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -2715,17 +2715,17 @@ bool x_pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, end.y = (float_t)data[4] * 0.001f; end.z = (float_t)data[5] * 0.001f; - rctx_ptr->post_process.tone_map->set_tone_trans(start, end, 1); + rctx_ptr->render.set_tone_trans(start, end, 1); } break; case DSC_X_SATURATE: { float_t saturate_coeff = (float_t)data[0] * 0.001f; - rctx_ptr->post_process.tone_map->set_saturate_coeff(saturate_coeff, 1, false); + rctx_ptr->render.set_saturate_coeff(saturate_coeff, 1, false); } break; case DSC_X_FADE_MODE: { int32_t blend_func = data[0]; - rctx_ptr->post_process.tone_map->set_scene_fade_blend_func(blend_func, 1); + rctx_ptr->render.set_scene_fade_blend_func(blend_func, 1); } break; case DSC_X_AUTO_BLINK: { @@ -3584,7 +3584,7 @@ void x_pv_game_pv_data::init(class x_pv_game* pv_game, bool music_play) { find_change_fields(pv_game->get_data().change_fields); - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) { shad->blur_filter_enable[0] = true; shad->blur_filter_enable[1] = true; @@ -5483,7 +5483,7 @@ bool x_pv_game::Ctrl() { #if BAKE_PNG || BAKE_VIDEO if (img_write && frame_prev != x_pv_game_ptr->frame) { - texture* tex = rctx_ptr->post_process.screen_texture.color_texture; + texture* tex = rctx_ptr->render.rediva_screen_texture.color_texture; int32_t width = tex->width; int32_t height = tex->height; @@ -5691,6 +5691,11 @@ bool x_pv_game::Ctrl() { break; } + if (pv_data.play_param->chara.size() < 2) + rctx_ptr->render.update_res(false, 1); + else + rctx_ptr->render.update_res(false, 2); + #if BAKE_PV826 if (pv_id == 826) { for (int32_t i = (int32_t)pv_data.play_param->chara.size(); i < ROB_CHARA_COUNT; i++) { @@ -6074,7 +6079,7 @@ bool x_pv_game::Ctrl() { get_data().pv_data.init(this, true); - Shadow* shad = rctx_ptr->render_manager.shadow_ptr; + Shadow* shad = shadow_ptr_get(); if (shad) { shad->blur_filter_enable[0] = true; shad->blur_filter_enable[1] = true; @@ -6150,7 +6155,7 @@ bool x_pv_game::Ctrl() { for (auto& i : pv_data.chara_effect.auth_3d) for (x_pv_game_chara_effect_auth_3d& j : i) add_auth_3d(chara_effect_auth_3ds, j.id); - + for (x_pv_game_song_effect& i : pv_data.effect.song_effect) for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) add_auth_3d(song_effect_auth_3ds, j.id); @@ -6205,7 +6210,7 @@ bool x_pv_game::Ctrl() { for (auth_3d*& i : chara_effect_auth_3ds) add_auth_3d_object_set_id(i); - + for (auth_3d*& i : song_effect_auth_3ds) add_auth_3d_object_set_id(i); @@ -6297,7 +6302,7 @@ bool x_pv_game::Ctrl() { for (auto& i : chara_effect_auth_3ds) x_pv_game_write_auth_3d(i); - + for (auto& i : stage_data_effect_auth_3ds) x_pv_game_write_auth_3d(i); @@ -6619,13 +6624,6 @@ bool x_pv_game::Dest() { task_rob_manager_del_task(); - light_param_data_storage_data_reset(); - rctx_ptr->post_process.tone_map->reset_saturate_coeff(0, false); - rctx_ptr->post_process.tone_map->reset_scene_fade(0); - dof_pv_data.enable = false; - rctx_ptr->disp_manager.object_culling = true; - rctx_ptr->render_manager.shadow_ptr->range = 1.0f; - Glitter::glt_particle_manager->SetPause(false); extern float_t frame_speed; frame_speed = 1.0f; @@ -6648,7 +6646,7 @@ void x_pv_game::Basic() { #if DOF_BAKE if (dof_cam_data.frame != frame) { camera* cam = rctx_ptr->camera; - post_process_dof* dof = rctx_ptr->post_process.dof; + renderer::DOF3* dof = rctx_ptr->render.dof; dof_pv pv; dof_pv_get(&dof_pv_data); @@ -7370,6 +7368,27 @@ bool x_pv_game::Unload() { i = 0; Glitter::glt_particle_manager->draw_all = true; + + osage_play_data_manager_reset(); + + skin_param_storage_reset(); + + light_param_data_storage_data_reset(); + + rndr::Render& rend = rctx_ptr->render; + rend.reset_saturate_coeff(0, true); + dof_pv_set(); + rend.reset_scene_fade(0); + + rend.set_taa(1); + rend.update_res(0, -1); + + rctx_ptr->disp_manager->object_culling = true; + shadow_ptr_get()->range = 1.0f; + rctx_ptr->render_manager->set_effect_texture(0); + + sound_work_reset_all_se(); + pv_param_task::post_process_task_del_task(); return true; }