From b2dee81b48f19683d1e1f53d5af543028edc6c7c Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sat, 31 Aug 2024 21:01:49 +0300 Subject: [PATCH] Don't write stuff when it not needed --- src/DivaGL/GL/array_buffer.cpp | 2 +- src/DivaGL/GL/element_array_buffer.cpp | 2 +- src/DivaGL/GL/shader_storage_buffer.cpp | 2 +- src/DivaGL/GL/uniform_buffer.cpp | 2 +- src/DivaGL/Glitter/render_scene.cpp | 12 +- src/DivaGL/camera.cpp | 4 + src/DivaGL/camera.hpp | 1 + src/DivaGL/effect.cpp | 7 +- src/DivaGL/hook.cpp | 4 +- src/DivaGL/light_param/fog.cpp | 61 ++- src/DivaGL/light_param/light.cpp | 118 ++--- src/DivaGL/mdl/disp_manager.cpp | 163 +++--- src/DivaGL/mdl/disp_manager.hpp | 3 +- src/DivaGL/mdl/draw_object.cpp | 239 ++++----- src/DivaGL/render_context.cpp | 669 +++++++++++++++++++----- src/DivaGL/render_context.hpp | 471 ++++++++++------- src/DivaGL/render_manager.cpp | 71 +-- src/DivaGL/shader_ft.cpp | 2 +- src/DivaGL/uniform.hpp | 2 +- 19 files changed, 1138 insertions(+), 697 deletions(-) diff --git a/src/DivaGL/GL/array_buffer.cpp b/src/DivaGL/GL/array_buffer.cpp index d3030f0..c8e8916 100644 --- a/src/DivaGL/GL/array_buffer.cpp +++ b/src/DivaGL/GL/array_buffer.cpp @@ -95,7 +95,7 @@ namespace GL { } void ArrayBuffer::WriteMemory(size_t offset, size_t size, const void* data) { - if (!buffer) + if (!buffer || !size) return; if (GL_VERSION_4_5) diff --git a/src/DivaGL/GL/element_array_buffer.cpp b/src/DivaGL/GL/element_array_buffer.cpp index a0ec967..1bb00cf 100644 --- a/src/DivaGL/GL/element_array_buffer.cpp +++ b/src/DivaGL/GL/element_array_buffer.cpp @@ -95,7 +95,7 @@ namespace GL { } void ElementArrayBuffer::WriteMemory(size_t offset, size_t size, const void* data) { - if (!buffer) + if (!buffer || !size) return; if (GL_VERSION_4_5) diff --git a/src/DivaGL/GL/shader_storage_buffer.cpp b/src/DivaGL/GL/shader_storage_buffer.cpp index e8e28f6..99abc20 100644 --- a/src/DivaGL/GL/shader_storage_buffer.cpp +++ b/src/DivaGL/GL/shader_storage_buffer.cpp @@ -95,7 +95,7 @@ namespace GL { } void ShaderStorageBuffer::WriteMemory(size_t offset, size_t size, const void* data) { - if (!buffer) + if (!buffer || !size) return; if (GL_VERSION_4_5) diff --git a/src/DivaGL/GL/uniform_buffer.cpp b/src/DivaGL/GL/uniform_buffer.cpp index 44bdfa3..d6bab09 100644 --- a/src/DivaGL/GL/uniform_buffer.cpp +++ b/src/DivaGL/GL/uniform_buffer.cpp @@ -95,7 +95,7 @@ namespace GL { } void UniformBuffer::WriteMemory(size_t offset, size_t size, const void* data) { - if (!buffer) + if (!buffer || !size) return; if (GL_VERSION_4_5) diff --git a/src/DivaGL/Glitter/render_scene.cpp b/src/DivaGL/Glitter/render_scene.cpp index 4bac2d3..5f25d39 100644 --- a/src/DivaGL/Glitter/render_scene.cpp +++ b/src/DivaGL/Glitter/render_scene.cpp @@ -212,12 +212,8 @@ namespace Glitter { break; } - rctx->obj_shader.set_shader_flags(uniform->arr); - rctx->obj_shader_ubo.WriteMemory(rctx->obj_shader); - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx->obj_shader_ubo.Bind(0); - rctx->obj_scene_ubo.Bind(1); + rctx->set_glitter_render_data(); rctx->glitter_batch_ubo.Bind(3); switch (rend_group->type) { case PARTICLE_QUAD: @@ -2048,12 +2044,8 @@ namespace Glitter { else gl_state_disable_cull_face(); - rctx->obj_shader.set_shader_flags(uniform->arr); - rctx->obj_shader_ubo.WriteMemory(rctx->obj_shader); - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx->obj_shader_ubo.Bind(0); - rctx->obj_scene_ubo.Bind(1); + rctx->set_glitter_render_data(); rctx->glitter_batch_ubo.Bind(3); switch (rend_group->type) { case PARTICLE_QUAD: diff --git a/src/DivaGL/camera.cpp b/src/DivaGL/camera.cpp index 8547ff2..de69254 100644 --- a/src/DivaGL/camera.cpp +++ b/src/DivaGL/camera.cpp @@ -75,6 +75,10 @@ HOOK(void, FASTCALL, camera_update, 0x00000001401F8970) { camera_data->fast_change = false; } +void camera_struct::get_view_point(vec3& value) { + value = view_point; +} + void camera_struct::get_view_point(vec4& value) { *(vec3*)&value = view_point; value.w = 0.0f; diff --git a/src/DivaGL/camera.hpp b/src/DivaGL/camera.hpp index 39cc5c6..fa8ca7e 100644 --- a/src/DivaGL/camera.hpp +++ b/src/DivaGL/camera.hpp @@ -53,6 +53,7 @@ struct camera_struct { bool fast_change_hist1; int32_t field_22C; + void get_view_point(vec3& value); void get_view_point(vec4& value); static void update_data(); diff --git a/src/DivaGL/effect.cpp b/src/DivaGL/effect.cpp index 8564a8f..c45f691 100644 --- a/src/DivaGL/effect.cpp +++ b/src/DivaGL/effect.cpp @@ -556,10 +556,9 @@ void leaf_particle_draw() { shader_data.g_transform[3] = temp.row3; camera_data->get_view_point(shader_data.g_view_pos); shader_data.g_color = stage_param_data_leaf_current->color; - light_stage.get_diffuse(shader_data.g_light_env_stage_diffuse); - light_stage.get_specular(shader_data.g_light_env_stage_specular); - shader_data.g_lit_dir = rctx->obj_scene.g_light_chara_dir; - shader_data.g_lit_luce = rctx->obj_scene.g_light_chara_luce; + rctx->get_scene_light(&shader_data.g_light_env_stage_diffuse, + &shader_data.g_light_env_stage_specular, + &shader_data.g_lit_dir, &shader_data.g_lit_luce, 0, 0); leaf_particle_scene_ubo.WriteMemory(shader_data); gl_state_active_bind_texture_2d(0, tex->glid); diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp index 607781f..dc836af 100644 --- a/src/DivaGL/hook.cpp +++ b/src/DivaGL/hook.cpp @@ -206,11 +206,11 @@ HOOK(int32_t, FASTCALL, shader_get_index_by_name, 0x00000001405E4ED0, const char } HOOK(void, FASTCALL, env_set_blend_color, 0x00000001405E5600, float_t r, float_t g, float_t b, float_t a) { - rctx->obj_batch.g_blend_color = { r, g, b, a }; + rctx->set_batch_blend_color({ r, g, b, a }); } HOOK(void, FASTCALL, env_set_offset_color, 0x00000001405E5630, float_t r, float_t g, float_t b, float_t a) { - rctx->obj_batch.g_offset_color = { r, g, b, a }; + rctx->set_batch_offset_color({ r, g, b, a }); } HOOK(void, FASTCALL, set_render_defaults, 0x00000001401948B0) { diff --git a/src/DivaGL/light_param/fog.cpp b/src/DivaGL/light_param/fog.cpp index 9fe3b8d..b509edd 100644 --- a/src/DivaGL/light_param/fog.cpp +++ b/src/DivaGL/light_param/fog.cpp @@ -80,16 +80,55 @@ void fog::data_set(fog_id id) { extern render_context* rctx; switch (id) { - case FOG_DEPTH: - get_color(rctx->obj_scene.g_fog_depth_color); - rctx->obj_scene.g_fog_state_params = params; - break; - case FOG_HEIGHT: - get_color(rctx->obj_scene.g_fog_height_color); - rctx->obj_scene.g_fog_height_params = params; - break; - case FOG_BUMP: - rctx->obj_scene.g_fog_bump_params = params; - break; + case FOG_DEPTH: { + float_t density = get_density(); + float_t start = get_start(); + float_t end = get_end(); + if (start >= end) + start = end - 0.01f; + vec4 color; + get_color(color); + + render_context::fog_params params = {}; + rctx->get_scene_fog_params(params); + params.density = density; + params.start = start; + params.end = end; + params.depth_color = color; + rctx->set_scene_fog_params(params); + } break; + case FOG_HEIGHT: { + float_t density = get_density(); + float_t start = get_start(); + float_t end = get_end(); + if (start >= end) + start = end - 0.01f; + vec4 color; + get_color(color); + + render_context::fog_params params = {}; + rctx->get_scene_fog_params(params); + params.height_params.x = density; + params.height_params.y = start; + params.height_params.z = end; + params.height_params.w = 1.0f / (end - start); + params.height_color = color; + rctx->set_scene_fog_params(params); + } break; + case FOG_BUMP: { + float_t density = get_density(); + float_t start = get_start(); + float_t end = get_end(); + if (start >= end) + start = end - 0.01f; + + render_context::fog_params params = {}; + rctx->get_scene_fog_params(params); + params.bump_params.x = density; + params.bump_params.y = start; + params.bump_params.z = end; + params.bump_params.w = 1.0f / (end - start); + rctx->set_scene_fog_params(params); + } break; } } diff --git a/src/DivaGL/light_param/light.cpp b/src/DivaGL/light_param/light.cpp index 925ec14..3b0aa6e 100644 --- a/src/DivaGL/light_param/light.cpp +++ b/src/DivaGL/light_param/light.cpp @@ -318,28 +318,30 @@ void light_set::data_set(light_set_id id) { static const float_t spec_coef = (float_t)(1.0 / (1.0 - cos(18.0 * DEG_TO_RAD))); static const float_t luce_coef = (float_t)(1.0 / (1.0 - cos(45.0 * DEG_TO_RAD))); - extern render_context* rctx; - obj_scene_shader_data& obj_scene = rctx->obj_scene; - light_data_color light_color[LIGHT_MAX]; for (int32_t i = 0; i < LIGHT_MAX; i++) light_get_light_color(&lights[i], light_color[i], (light_id)i); - obj_scene.g_light_env_stage_diffuse = light_color[LIGHT_STAGE].diffuse; - obj_scene.g_light_env_stage_specular = light_color[LIGHT_STAGE].specular; + vec4 light_env_stage_diffuse = light_color[LIGHT_STAGE].diffuse; + vec4 light_env_stage_specular = light_color[LIGHT_STAGE].specular; - obj_scene.g_light_env_chara_diffuse = light_color[LIGHT_CHARA].diffuse; - obj_scene.g_light_env_chara_ambient = light_color[LIGHT_CHARA].ambient; - obj_scene.g_light_env_chara_specular = light_color[LIGHT_CHARA].specular; + vec4 light_env_chara_diffuse = light_color[LIGHT_CHARA].diffuse; + vec4 light_env_chara_ambient = light_color[LIGHT_CHARA].ambient; + vec4 light_env_chara_specular = light_color[LIGHT_CHARA].specular; - lights[LIGHT_REFLECT].get_diffuse(obj_scene.g_light_env_reflect_diffuse); - lights[LIGHT_REFLECT].get_ambient(obj_scene.g_light_env_reflect_ambient); + vec4 light_env_reflect_diffuse; + vec4 light_env_reflect_ambient; + lights[LIGHT_REFLECT].get_diffuse(light_env_reflect_diffuse); + lights[LIGHT_REFLECT].get_ambient(light_env_reflect_ambient); - lights[LIGHT_PROJECTION].get_diffuse(obj_scene.g_light_env_proj_diffuse); - lights[LIGHT_PROJECTION].get_specular(obj_scene.g_light_env_proj_specular); - lights[LIGHT_PROJECTION].get_position(obj_scene.g_light_env_proj_position); + vec4 light_env_proj_diffuse; + vec4 light_env_proj_specular; + vec4 light_env_proj_position; + lights[LIGHT_PROJECTION].get_diffuse(light_env_proj_diffuse); + lights[LIGHT_PROJECTION].get_specular(light_env_proj_specular); + lights[LIGHT_PROJECTION].get_position(light_env_proj_position); if (lights[LIGHT_PROJECTION].get_type() == LIGHT_PARALLEL) - light_get_direction_from_position(&obj_scene.g_light_env_proj_position, 0, true); + light_get_direction_from_position(&light_env_proj_position, 0, true); vec4 light_chara_dir; vec4 light_chara_ibl_color0; @@ -351,10 +353,9 @@ void light_set::data_set(light_set_id id) { lights[LIGHT_CHARA].get_ibl_color1(light_chara_ibl_color1); lights[LIGHT_CHARA].get_specular(light_chara_specular); - obj_scene.g_light_chara_dir = light_chara_dir; - obj_scene.g_light_chara_spec = light_chara_specular * light_chara_ibl_color0 * spec_coef; - obj_scene.g_light_chara_luce = light_chara_ibl_color0 * luce_coef; - obj_scene.g_light_chara_back = light_chara_specular * light_chara_ibl_color1 * spec_coef; + vec4 light_chara_spec = light_chara_specular * light_chara_ibl_color0 * spec_coef; + vec4 light_chara_luce = light_chara_ibl_color0 * luce_coef; + vec4 light_chara_back = light_chara_specular * light_chara_ibl_color1 * spec_coef; vec4 light_stage_dir; vec4 light_stage_ibl_color; @@ -366,44 +367,42 @@ void light_set::data_set(light_set_id id) { lights[LIGHT_STAGE].get_diffuse(light_stage_diffuse); lights[LIGHT_STAGE].get_specular(light_stage_specular); - obj_scene.g_light_stage_dir = light_stage_dir; - obj_scene.g_light_stage_diff = light_stage_diffuse * light_stage_ibl_color; - obj_scene.g_light_stage_spec = light_stage_specular * light_stage_ibl_color * spec_coef; + vec4 light_stage_diff = light_stage_diffuse * light_stage_ibl_color; + vec4 light_stage_spec = light_stage_specular * light_stage_ibl_color * spec_coef; mat4 irradiance_r_transforms; mat4 irradiance_g_transforms; mat4 irradiance_b_transforms; get_irradiance(irradiance_r_transforms, irradiance_g_transforms, irradiance_b_transforms); - obj_scene.set_g_irradiance_r_transforms(irradiance_r_transforms); - obj_scene.set_g_irradiance_g_transforms(irradiance_g_transforms); - obj_scene.set_g_irradiance_b_transforms(irradiance_b_transforms); - float_t* (FASTCALL * face_data_get)() = (float_t * (FASTCALL*)())0x00000001403D8310; - float_t offset = face_data_get()[0]; - float_t v28 = (float_t)(1.0 - exp(offset * -0.44999999)) * 2.0f; - offset = max_def(offset, 0.0f); - obj_scene.g_light_face_diff = { v28 * 0.1f, offset * 0.06f, 1.0f, 1.0f }; + float_t v27 = face_data_get()[0]; + float_t v28 = (float_t)(1.0 - exp(v27 * -0.44999999)) * 2.0f; + v27 = max_def(v27, 0.0f); + vec4 light_face_diff = { v28 * 0.1f, v27 * 0.06f, 1.0f, 1.0f }; + vec4 chara_color_rim; + vec4 chara_color0; + vec4 chara_color1; if (lights[LIGHT_CHARA_COLOR].get_type() == LIGHT_PARALLEL) { - lights[LIGHT_CHARA_COLOR].get_ambient(obj_scene.g_chara_color_rim); - lights[LIGHT_CHARA_COLOR].get_diffuse(obj_scene.g_chara_color0); - lights[LIGHT_CHARA_COLOR].get_specular(obj_scene.g_chara_color1); - if (obj_scene.g_chara_color1.w > 1.0f) - obj_scene.g_chara_color1.w = 1.0f; + lights[LIGHT_CHARA_COLOR].get_ambient(chara_color_rim); + lights[LIGHT_CHARA_COLOR].get_diffuse(chara_color0); + lights[LIGHT_CHARA_COLOR].get_specular(chara_color1); + if (chara_color1.w > 1.0f) + chara_color1.w = 1.0f; } else { - obj_scene.g_chara_color_rim = 0.0f; - obj_scene.g_chara_color0 = 0.0f; - obj_scene.g_chara_color1 = 0.0f; + chara_color_rim = 0.0f; + chara_color0 = 0.0f; + chara_color1 = 0.0f; } + vec4 chara_f_dir; + vec4 chara_f_ambient; + vec4 chara_f_diffuse; + vec4 chara_tc_param; if (lights[LIGHT_TONE_CURVE].get_type() == LIGHT_PARALLEL) { uniform->arr[U_TONE_CURVE] = 1; - vec4 chara_f_dir; - vec4 chara_f_ambient; - vec4 chara_f_diffuse; - vec4 chara_tc_param; lights[LIGHT_TONE_CURVE].get_position(chara_f_dir); light_get_direction_from_position(&chara_f_dir, &lights[LIGHT_TONE_CURVE]); lights[LIGHT_TONE_CURVE].get_ambient(chara_f_ambient); @@ -419,18 +418,13 @@ void light_set::data_set(light_set_id id) { chara_tc_param.y = 0.0f; chara_tc_param.z = tone_curve.coefficient; chara_tc_param.w = 0.0f; - - obj_scene.g_chara_f_dir = chara_f_dir; - obj_scene.g_chara_f_ambient = chara_f_ambient; - obj_scene.g_chara_f_diffuse = chara_f_diffuse; - obj_scene.g_chara_tc_param = chara_tc_param; } else { uniform->arr[U_TONE_CURVE] = 0; - obj_scene.g_chara_f_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; - obj_scene.g_chara_f_ambient = 0.0f; - obj_scene.g_chara_f_diffuse = 0.0f; - obj_scene.g_chara_tc_param = 0.0f; + chara_f_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + chara_f_ambient = 0.0f; + chara_f_diffuse = 0.0f; + chara_tc_param = 0.0f; } vec4 light_reflect_dir; @@ -445,24 +439,20 @@ void light_set::data_set(light_set_id id) { } light_reflect_dir.w = 1.0f; - obj_scene.g_light_reflect_dir = light_reflect_dir; - + vec4 clip_plane; if (lights[LIGHT_REFLECT].get_type() == LIGHT_SPOT) { vec3 spot_direction; vec4 position; lights[LIGHT_REFLECT].get_spot_direction(spot_direction); lights[LIGHT_REFLECT].get_position(position); - vec4 clip_plane; *(vec3*)&clip_plane = -spot_direction; light_get_direction_from_position(&clip_plane, &lights[LIGHT_REFLECT], true); clip_plane.w = -vec3::dot(*(vec3*)&position, *(vec3*)&clip_plane); - - obj_scene.g_clip_plane = clip_plane; } else if (lights[LIGHT_REFLECT].get_type() == LIGHT_POINT) - obj_scene.g_clip_plane = { 0.0f, -1.0f, 0.0f, 9999.0f }; + clip_plane = { 0.0f, -1.0f, 0.0f, 9999.0f }; else - obj_scene.g_clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; + clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; vec4 light_chara_ibl_direction; vec4 light_chara_position; @@ -493,8 +483,18 @@ void light_set::data_set(light_set_id id) { } } - obj_scene.set_g_normal_tangent_transforms(normal_tangent_transforms); - obj_scene.g_npr_cloth_spec_color = npr_cloth_spec_color; + extern render_context* rctx; + rctx->set_scene_light(irradiance_r_transforms, irradiance_g_transforms, irradiance_b_transforms, + light_env_stage_diffuse, light_env_stage_specular, light_env_chara_diffuse, + light_env_chara_ambient, light_env_chara_specular, + light_env_reflect_diffuse, light_env_reflect_ambient, + light_env_proj_diffuse, light_env_proj_specular, + light_env_proj_position, light_stage_dir, light_stage_diff, + light_stage_spec, light_chara_dir, light_chara_spec, + light_chara_luce, light_chara_back, light_face_diff, + chara_color0, chara_color1, chara_f_dir, chara_f_ambient, + chara_f_diffuse, chara_tc_param, normal_tangent_transforms, + light_reflect_dir, clip_plane, npr_cloth_spec_color); } static void light_get_direction_from_position(vec4* pos_dir, light_data* light, bool force) { diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 68e26f3..26deb12 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -1971,7 +1971,7 @@ namespace mdl { i.reset_vertex_attrib(); } - void DispManager::draw(ObjType type, int32_t depth_mask, bool reflect_texture_mask) { + void DispManager::draw(ObjType type, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) { if (type < 0 || type >= mdl::OBJ_TYPE_LOCAL_MAX || get_obj_count(type) < 1) return; @@ -2074,29 +2074,68 @@ namespace mdl { case OBJ_TYPE_USER: func = draw_sub_mesh_translucent; 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; + 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; default: break; } - rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + rctx->set_batch_alpha_threshold(alpha_threshold); + rctx->set_batch_min_alpha(min_alpha); uniform->arr[U_ALPHA_TEST] = alpha_test; - for (ObjData*& i : get_obj_list(type)) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_ETC: { - draw_etc_obj(&i->args.etc, &i->mat); - } break; - case OBJ_KIND_USER: { - i->args.user.func(i->args.user.data, &i->mat); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (int32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); - } break; + if (alpha < 0) + for (ObjData*& i : get_obj_list(type)) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_ETC: { + draw_etc_obj(&i->args.etc, &i->mat); + } break; + case OBJ_KIND_USER: { + i->args.user.func(i->args.user.data, &i->mat); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (int32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); + } break; + } + } + else + for (ObjData*& i : get_obj_list(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(&i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (int32_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(args, &i->mat, func); + } + } break; + } } - } switch (type) { case OBJ_TYPE_TRANSLUCENT: @@ -2116,6 +2155,16 @@ namespace mdl { case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: gl_state_set_cull_face_mode(GL_BACK); 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; + 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; } uniform_value_reset(); @@ -2126,84 +2175,6 @@ namespace mdl { gl_state_bind_sampler(i, 0); } - void DispManager::draw_translucent(ObjType type, int32_t alpha) { - if (type < 0 || type >= mdl::OBJ_TYPE_LOCAL_MAX || get_obj_count(type) < 1) - return; - - int32_t alpha_test = 0; - float_t min_alpha = 1.0f; - float_t alpha_threshold = 0.0f; - bool reflect = uniform->arr[U_REFLECT] == 1; - void(*func)(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->glid); - gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map->glid); - gl_state_active_texture(0); - gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - uniform_value_reset(); - gl_state_get(); - - 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->arr[U_ALPHA_TEST] = alpha_test; - - for (ObjData*& i : get_obj_list(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(&i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (int32_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(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; diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index b060f3c..d8c3e78 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -451,8 +451,7 @@ namespace mdl { void check_index_buffer(GLuint buffer); void check_vertex_arrays(); void check_vertex_buffer(GLuint buffer); - void draw(mdl::ObjType type, int32_t depth_mask = 0, bool reflect_texture_mask = true); - void draw_translucent(mdl::ObjType type, int32_t alpha); + void draw(mdl::ObjType type, int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); /*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, diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp index 07d6656..0c6b236 100644 --- a/src/DivaGL/mdl/draw_object.cpp +++ b/src/DivaGL/mdl/draw_object.cpp @@ -52,13 +52,7 @@ namespace mdl { GL_UNSIGNED_INT, }; - rctx->obj_shader.set_shader_flags(uniform->arr); - rctx->obj_shader_ubo.WriteMemory(rctx->obj_shader); - rctx->obj_batch_ubo.WriteMemory(rctx->obj_batch); - - rctx->obj_shader_ubo.Bind(0); - rctx->obj_scene_ubo.Bind(1); - rctx->obj_batch_ubo.Bind(2); + rctx->set_render_data(); if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP && index_format == OBJ_INDEX_U16) shaders_ft.draw_range_elements(GL_TRIANGLE_STRIP, @@ -100,33 +94,26 @@ namespace mdl { draw_object_model_mat_load(*mat); - vec4 g_material_state_diffuse = rctx->obj_batch.g_material_state_diffuse; - vec4 g_material_state_ambient = rctx->obj_batch.g_material_state_ambient; - vec4 g_material_state_specular = rctx->obj_batch.g_material_state_specular; - vec4 g_material_state_emission = rctx->obj_batch.g_material_state_emission; - vec4 g_material_state_shininess = rctx->obj_batch.g_material_state_shininess; + const vec4 color = etc->color; - vec4 color = etc->color; + if (etc->constant) { + vec4 diffuse = color; + vec4 ambient = color * 0.5f; + ambient.w = color.w; + vec4 emission = etc->constant ? 1.0f : vec4(0.0f, 0.0f, 0.0f, 1.0f); + vec4 specular = { 0.0f, 0.0f, 0.0f, 1.0f }; - vec4 ambient; - *(vec3*)&ambient = *(vec3*)&color * 0.5f; - ambient.w = color.w; - - rctx->obj_batch.g_material_state_diffuse = color; - rctx->obj_batch.g_material_state_ambient = ambient; - rctx->obj_batch.g_material_state_specular = { 0.0f, 0.0f, 0.0f, 1.0f }; - rctx->obj_batch.g_material_state_emission = etc->constant ? 1.0f : vec4(0.0f, 0.0f, 0.0f, 1.0f); - rctx->obj_batch.g_material_state_shininess = { 0.0f, 0.0f, 0.0f, 1.0f }; - - rctx->obj_batch.g_blend_color = color; + rctx->set_batch_material_color(diffuse, ambient, emission, + 0.0f, specular, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); + } + else + rctx->set_batch_blend_color_offset_color(color, 0.0f); gl_state_bind_vertex_array(vao); - rctx->obj_shader.set_shader_flags(uniform->arr); - rctx->obj_shader_ubo.WriteMemory(rctx->obj_shader); - rctx->obj_batch_ubo.WriteMemory(rctx->obj_batch); - - //shaders_ft.set(SHADER_FT_SIMPLE); - shaders_ft.set(etc->constant ? SHADER_FT_CONSTANT : SHADER_FT_SIMPLE); + //rctx->set_shader(SHADER_FT_SIMPLE); + rctx->set_shader(etc->constant ? SHADER_FT_CONSTANT : SHADER_FT_SIMPLE); + rctx->set_render_data(); switch (etc->type) { case mdl::ETC_OBJ_TEAPOT: shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); @@ -181,13 +168,7 @@ namespace mdl { shader::unbind(); uniform_value_reset(); - rctx->obj_batch.g_material_state_diffuse = g_material_state_diffuse; - rctx->obj_batch.g_material_state_ambient = g_material_state_ambient; - rctx->obj_batch.g_material_state_specular = g_material_state_specular; - rctx->obj_batch.g_material_state_emission = g_material_state_emission; - rctx->obj_batch.g_material_state_shininess = g_material_state_shininess; - - rctx->obj_batch.g_blend_color = 1.0f; + rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); } void draw_sub_mesh(const ObjSubMeshArgs* args, const mat4* mat, @@ -198,9 +179,11 @@ namespace mdl { if (args->mats) { const mat4* mats = args->mats; - rctx->obj_batch.set_g_joint(mats[0]); - vec4* g_joint_transforms = rctx->obj_skinning.g_joint_transforms; + if (args->mat_count == 2) + rctx->set_batch_joint(mats[0]); + + vec4* g_joint_transforms = rctx->data.buffer_skinning_data.g_joint_transforms; mat4 mat; for (int32_t i = 0; i < args->mat_count; i++, mats++, g_joint_transforms += 3) { @@ -210,11 +193,9 @@ namespace mdl { g_joint_transforms[2] = mat.row2; } - rctx->obj_skinning_ssbo.WriteMemory(rctx->obj_skinning); + rctx->data.buffer_skinning.WriteMemory(rctx->data.buffer_skinning_data); - rctx->obj_skinning_ssbo.Bind(0); - - rctx->obj_batch.set_transforms(mat4_identity, rctx->view_mat, rctx->proj_mat); + rctx->set_batch_worlds(mat4_identity); uniform->arr[U_SKINNING] = 1; gl_state_bind_vertex_array(vao); @@ -248,10 +229,8 @@ namespace mdl { }*/ void draw_sub_mesh_default(const ObjSubMeshArgs* args) { - if (args->set_blend_color) { - rctx->obj_batch.g_blend_color = args->blend_color; - rctx->obj_batch.g_offset_color = 0.0f; - } + if (args->set_blend_color) + rctx->set_batch_blend_color_offset_color(args->blend_color, 0.0f); if (!args->func) draw_object_vertex_attrib_set_default(args); @@ -271,20 +250,16 @@ namespace mdl { if (!args->func) draw_object_vertex_attrib_reset_default(args); - if (args->set_blend_color) { - rctx->obj_batch.g_blend_color = 1.0f; - rctx->obj_batch.g_offset_color = 0.0f; - } + if (args->set_blend_color) + rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); draw_state.stats.object_draw_count++; } void draw_sub_mesh_default_instanced( const ObjSubMeshArgs* args, const mat4* mat) { - if (args->set_blend_color) { - rctx->obj_batch.g_blend_color = args->blend_color; - rctx->obj_batch.g_offset_color = 0.0f; - } + if (args->set_blend_color) + rctx->set_batch_blend_color_offset_color(args->blend_color, 0.0f); if (!args->func) draw_object_vertex_attrib_set_default(args); @@ -310,10 +285,8 @@ namespace mdl { if (!args->func) draw_object_vertex_attrib_reset_default(args); - if (args->set_blend_color) { - rctx->obj_batch.g_blend_color = 1.0f; - rctx->obj_batch.g_offset_color = 0.0f; - } + if (args->set_blend_color) + rctx->set_batch_blend_color_offset_color(1.0f, 0.0f); draw_state.stats.object_draw_count++; } @@ -338,7 +311,6 @@ namespace mdl { if (!render_manager->npr_param) chara = true; break; - //case SHADER_FT_EYEBALL: case SHADER_FT_GLASEYE: uniform->arr[U_NPR_NORMAL] = 0; chara = true; @@ -349,12 +321,12 @@ namespace mdl { } if (chara) { - rctx->obj_batch.g_sss_param = { 0.0f, 0.0f, 0.0f, 0.5f }; + rctx->set_batch_sss_param({ 0.0f, 0.0f, 0.0f, 0.5f }); uniform->arr[U_SSS_CHARA] = 1; } else { const vec4& sss_param = sss_data_get()->param; - rctx->obj_batch.g_sss_param = { sss_param.x, sss_param.y, sss_param.z, 0.5f }; + rctx->set_batch_sss_param({ sss_param.x, sss_param.y, sss_param.z, 0.5f }); uniform->arr[U_SSS_CHARA] = 0; } draw_sub_mesh_default(args); @@ -413,24 +385,24 @@ namespace mdl { || args->sub_mesh->attrib.m.transparent) || attrib.punch_through) { uniform->arr[U_ALPHA_TEST] = 1; - rctx->obj_batch.g_max_alpha.z = 0.5f; + rctx->set_batch_alpha_threshold(0.5f); draw_sub_mesh_translucent(args); - } - else { uniform->arr[U_ALPHA_TEST] = 0; - draw_sub_mesh_translucent(args); + rctx->set_batch_alpha_threshold(0.0f); } + else + draw_sub_mesh_translucent(args); } void draw_sub_mesh_translucent(const ObjSubMeshArgs* args) { const obj_material_data* material = args->material; const prj::vector* textures = args->textures; if (draw_state.shader_index != -1) { - rctx->obj_batch.g_material_state_emission = args->emission; + rctx->set_batch_material_color_emission(args->emission); draw_object_material_set_uniform(material, false); if (material->material.attrib.m.alpha_texture) uniform->arr[U_TEXTURE_COUNT] = 0; - shaders_ft.set(draw_state.shader_index); + rctx->set_shader(draw_state.shader_index); } draw_object_vertex_attrib_set_default(args); @@ -779,16 +751,16 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo draw_object_chara_color_fog_set(args, disable_fog); - rctx->obj_batch.g_material_state_ambient = material->material.color.ambient; + vec4 ambient = material->material.color.ambient; if (!sss_data_get()->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; + ambient.w = 1.0f; + vec4 diffuse = material->material.color.diffuse; + vec4 emission = args->emission; + vec4 specular = { 0.0f, 0.0f, 0.0f, 1.0f }; float_t line_light; if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) { - const vec4& specular = material->material.color.specular; - rctx->obj_batch.g_material_state_specular = specular; + specular = material->material.color.specular; float_t luma = vec3::dot(*(vec3*)&specular, { 0.30f, 0.59f, 0.11f }); if (luma >= 0.01f || args->texture_color_coefficients.w >= 0.1f) @@ -804,32 +776,20 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo else line_light = 0.0; - if (!use_shader) - shaders_ft.set(SHADER_FT_SIMPLE); - else if (draw_state.shader_index != -1) - shaders_ft.set(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); - else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT) - shaders_ft.set(SHADER_FT_LAMBERT); - else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) - shaders_ft.set(SHADER_FT_BLINN); - else - shaders_ft.set(SHADER_FT_CONSTANT); - } - else - shaders_ft.set(SHADER_FT_CONSTANT); - + float_t material_shininess = 0.0f; + vec4 fresnel_coefficients; + float_t shininess = 0.0f; + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; if (lighting_type != OBJ_MATERIAL_SHADER_LIGHTING_CONSTANT) { - float_t material_shininess; if (material->material.shader.index == SHADER_FT_GLASEYE) material_shininess = 10.0f; else { material_shininess = (material->material.color.shininess - 16.0f) * (float_t)(1.0 / 112.0); material_shininess = max_def(material_shininess, 0.0f); } - rctx->obj_batch.g_material_state_shininess = { material_shininess, 0.0f, 0.0f, 1.0f }; float_t fresnel = (float_t)material->material.shader_info.m.fresnel_type; if (fresnel > 9.0f) @@ -838,45 +798,62 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo fresnel = draw_state.fresnel; fresnel = (fresnel - 1.0f) * 0.12f * 0.82f; - rctx->obj_batch.g_fresnel_coefficients = { fresnel, 0.18f, line_light, 0.0f }; + fresnel_coefficients = { fresnel, 0.18f, line_light, 0.0f }; - float_t shininess = max_def(material->material.color.shininess, 1.0f); - rctx->obj_batch.g_shininess = { shininess, 0.0f, 0.0f, 0.0f }; + shininess = max_def(material->material.color.shininess, 1.0f); switch (material->material.shader.index) { case SHADER_FT_SKIN: { - vec4 texture_color_coefficients = args->texture_color_coefficients; - vec4 texture_color_offset = args->texture_color_offset; - vec4 texture_specular_coefficients = args->texture_specular_coefficients; - vec4 texture_specular_offset = args->texture_specular_offset; + texture_color_coefficients = args->texture_color_coefficients; + texture_color_offset = args->texture_color_offset; + texture_specular_coefficients = args->texture_specular_coefficients; + texture_specular_offset = args->texture_specular_offset; texture_color_coefficients.w *= 0.015f; texture_specular_coefficients.w *= 0.015f; - - rctx->obj_batch.g_texture_color_coefficients = texture_color_coefficients; - rctx->obj_batch.g_texture_color_offset = texture_color_offset; - rctx->obj_batch.g_texture_specular_coefficients = texture_specular_coefficients; - rctx->obj_batch.g_texture_specular_offset = texture_specular_offset; } break; case SHADER_FT_HAIR: case SHADER_FT_CLOTH: case SHADER_FT_TIGHTS: - rctx->obj_batch.g_texture_color_coefficients = { + texture_color_coefficients = { 1.0f - args->texture_color_coefficients.w * 0.4f, 0.0f, 0.0f, args->texture_color_coefficients.w * 0.02f }; break; } } + rctx->set_batch_material_color(diffuse, ambient, emission, material_shininess, + specular, fresnel_coefficients, texture_color_coefficients, texture_color_offset, + texture_specular_coefficients, texture_specular_offset, shininess); + + if (!use_shader) + rctx->set_shader(SHADER_FT_SIMPLE); + else if (draw_state.shader_index != -1) + rctx->set_shader(draw_state.shader_index); + else if (material->material.shader.index != -1) { + if (material->material.shader.index != SHADER_FT_BLINN) + rctx->set_shader(material->material.shader.index); + else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT) + rctx->set_shader(SHADER_FT_LAMBERT); + else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) + rctx->set_shader(SHADER_FT_BLINN); + else + rctx->set_shader(SHADER_FT_CONSTANT); + } + else + rctx->set_shader(SHADER_FT_CONSTANT); + draw_object_material_set_parameter(material); } static void draw_object_material_set_parameter(const obj_material_data* mat_data) { + vec4 specular; float_t bump_depth; float_t intensity; float_t reflect_uv_scale; float_t refract_uv_scale; float_t inv_bump_depth; + bool has_specular; if (draw_state.use_global_material) { bump_depth = draw_state.bump_depth; intensity = draw_state.intensity; @@ -884,9 +861,9 @@ static void draw_object_material_set_parameter(const obj_material_data* mat_data refract_uv_scale = draw_state.refract_uv_scale; inv_bump_depth = (1.0f - draw_state.bump_depth) * 64.0f + 1.0f; - vec4 specular = mat_data->material.color.specular; + specular = mat_data->material.color.specular; specular.w = draw_state.reflectivity; - rctx->obj_batch.g_material_state_specular = specular; + has_specular = true; } else { bump_depth = mat_data->material.bump_depth; @@ -894,12 +871,13 @@ static void draw_object_material_set_parameter(const obj_material_data* mat_data intensity = mat_data->material.color.intensity; refract_uv_scale = 0.1f; inv_bump_depth = (1.0f - bump_depth) * 256.0f + 1.0f; + has_specular = false; } - rctx->obj_batch.g_bump_depth = { inv_bump_depth, bump_depth, 0.0f, 0.0f }; - rctx->obj_batch.g_intensity = { intensity, max_def(intensity, 1.0f), intensity * 25.5f, 1.0f }; - rctx->obj_batch.g_reflect_uv_scale = { - reflect_uv_scale, reflect_uv_scale, refract_uv_scale, refract_uv_scale }; + rctx->set_batch_material_parameter(has_specular ? &specular : 0, + { inv_bump_depth, bump_depth, 0.0f, 0.0f }, + { intensity, max_def(intensity, 1.0f), intensity * 25.5f, 1.0f }, + reflect_uv_scale, refract_uv_scale); } static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args) { @@ -970,11 +948,9 @@ static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args) { } draw_object_material_set_uniform(material, true); - shaders_ft.set(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; - rctx->obj_batch.g_material_state_specular = specular; + rctx->set_shader(draw_state.shader_index); + rctx->set_batch_material_color(diffuse, ambient, emission, + 0.0f, specular, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); draw_object_material_set_parameter(args->material); } @@ -1032,8 +1008,7 @@ static void draw_object_material_set_uniform(const obj_material_data* mat_data, } static void draw_object_model_mat_load(const mat4& mat) { - rctx->obj_batch.set_transforms(mat, rctx->view_mat, rctx->proj_mat); - rctx->obj_batch.set_g_joint(mat); + rctx->set_batch_worlds(mat); } static void draw_object_vertex_attrib_reset_default(const mdl::ObjSubMeshArgs* args) { @@ -1073,6 +1048,9 @@ static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* arg const obj_mesh* mesh = args->mesh; obj_vertex_format vertex_format = mesh->vertex_format; + mat4 mats[2]; + mats[0] = mat4_identity; + mats[1] = mat4_identity; bool texcoord_mat_set[4] = { false }; const obj_material_data* material = args->material; const obj_material_texture_data* texdata = material->material.texdata; @@ -1095,18 +1073,18 @@ static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* arg uint32_t texture_id = texdata->tex_index & 0xFFFFF; - rctx->obj_batch.set_g_texcoord_transforms(texcoord_index, - texdata->tex_coord_mat); + mats[texcoord_index] = texdata->tex_coord_mat; if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t k = 0; k < args->texture_transform_count; k++) if (args->texture_transform_array[k].id == texture_id) { - rctx->obj_batch.set_g_texcoord_transforms(texcoord_index, - args->texture_transform_array[k].mat); + mats[texcoord_index] = args->texture_transform_array[k].mat; texcoord_mat_set[texcoord_index] = true; break; } } + rctx->set_batch_texcoord_transforms(mats); + if (vertex_format & OBJ_VERTEX_BONE_DATA) uniform->arr[U_SKINNING] = 1; else @@ -1120,7 +1098,7 @@ static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* arg else uniform->arr[U_MORPH_COLOR] = 0; - rctx->obj_batch.g_morph_weight = { args->morph_weight, 1.0f - args->morph_weight, 0.0f, 0.0f }; + rctx->set_batch_morph_weight(args->morph_weight); } else { uniform->arr[U_MORPH] = 0; @@ -1137,21 +1115,24 @@ static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* arg const obj_mesh* mesh = args->mesh; obj_vertex_format vertex_format = mesh->vertex_format; + mat4 mats[2]; + mats[0] = mat4_identity; + mats[1] = mat4_identity; const obj_material_data* material = args->material; if (material->material.texdata[0].tex_index != -1) { uint32_t texture_id = material->material.texdata[0].tex_index & 0xFFFFF; - rctx->obj_batch.set_g_texcoord_transforms(0, - material->material.texdata[0].tex_coord_mat); + mats[0] = material->material.texdata[0].tex_coord_mat; if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t j = 0; j < args->texture_transform_count; j++) if (args->texture_transform_array[j].id == texture_id) { - rctx->obj_batch.set_g_texcoord_transforms(0, - args->texture_transform_array[j].mat); + mats[0] = args->texture_transform_array[j].mat; break; } } + rctx->set_batch_texcoord_transforms(mats); + if (vertex_format & OBJ_VERTEX_BONE_DATA) uniform->arr[U_SKINNING] = 1; else @@ -1165,7 +1146,7 @@ static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* arg else uniform->arr[U_MORPH_COLOR] = 0; - rctx->obj_batch.g_morph_weight = { args->morph_weight, 1.0f - args->morph_weight, 0.0f, 0.0f }; + rctx->set_batch_morph_weight(args->morph_weight); } else { uniform->arr[U_MORPH] = 0; diff --git a/src/DivaGL/render_context.cpp b/src/DivaGL/render_context.cpp index 2fc969f..56bfb34 100644 --- a/src/DivaGL/render_context.cpp +++ b/src/DivaGL/render_context.cpp @@ -5,6 +5,7 @@ #include "render_context.hpp" #include "render_manager.hpp" +#include "shader_ft.hpp" #include "uniform.hpp" draw_state_struct& draw_state = *(draw_state_struct*)0x00000001411A32B0; @@ -52,7 +53,11 @@ void draw_state_struct::set_fog_height(bool value) { fog_height = value; } -void obj_shader_shader_data::set_shader_flags(int32_t* shader_flags) { +void render_data::obj_shader_data::reset() { + g_shader_flags = {}; +} + +void render_data::obj_shader_data::set_shader_flags(const int32_t* shader_flags) { g_shader_flags.x.m.alpha_mask = shader_flags[U_ALPHA_MASK]; g_shader_flags.x.m.alpha_test = shader_flags[U_ALPHA_TEST]; g_shader_flags.x.m.aniso = shader_flags[U_ANISO]; @@ -77,7 +82,7 @@ void obj_shader_shader_data::set_shader_flags(int32_t* shader_flags) { g_shader_flags.y.m.fog_chara = shader_flags[U_FOG_CHARA]; g_shader_flags.y.m.u16 = shader_flags[U16]; g_shader_flags.y.m.gauss = shader_flags[U_GAUSS]; - g_shader_flags.y.m.eyeball = shader_flags[U_EYEBALL]; + g_shader_flags.y.m.eye_lens = shader_flags[U_EYE_LENS]; g_shader_flags.y.m.image_filter = shader_flags[U_IMAGE_FILTER]; g_shader_flags.y.m.instance = shader_flags[U_INSTANCE]; g_shader_flags.y.m.tone_curve = shader_flags[U_TONE_CURVE]; @@ -125,136 +130,224 @@ void obj_shader_shader_data::set_shader_flags(int32_t* shader_flags) { g_shader_flags.w.m.u45 = shader_flags[U45]; } -void obj_scene_shader_data::set_g_irradiance_r_transforms(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_irradiance_r_transforms[0] = temp.row0; - g_irradiance_r_transforms[1] = temp.row1; - g_irradiance_r_transforms[2] = temp.row2; - g_irradiance_r_transforms[3] = temp.row3; +void render_data::obj_scene_data::reset() { + g_irradiance_r_transforms[0] = 0.0f; + g_irradiance_r_transforms[1] = 0.0f; + g_irradiance_r_transforms[2] = 0.0f; + g_irradiance_r_transforms[3] = 0.0f; + g_irradiance_g_transforms[0] = 0.0f; + g_irradiance_g_transforms[1] = 0.0f; + g_irradiance_g_transforms[2] = 0.0f; + g_irradiance_g_transforms[3] = 0.0f; + g_irradiance_b_transforms[0] = 0.0f; + g_irradiance_b_transforms[1] = 0.0f; + g_irradiance_b_transforms[2] = 0.0f; + g_irradiance_b_transforms[3] = 0.0f; + g_light_env_stage_diffuse = 1.0f; + g_light_env_stage_specular = 0.0f; + g_light_env_chara_diffuse = 1.0f; + g_light_env_chara_ambient = 0.0f; + g_light_env_chara_specular = 0.0f; + g_light_env_reflect_diffuse = 1.0f; + g_light_env_reflect_ambient = 0.0f; + g_light_env_proj_diffuse = 1.0f; + g_light_env_proj_specular = 0.0f; + g_light_env_proj_position = 0.0f; + g_light_stage_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + g_light_stage_diff = 0.0f; + g_light_stage_spec = 0.0f; + g_light_chara_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + g_light_chara_spec = 0.0f; + g_light_chara_luce = 0.0f; + g_light_chara_back = 0.0f; + g_light_face_diff = 0.0f; + g_chara_color_rim = 0.0f; + g_chara_color0 = 0.0f; + g_chara_color1 = 0.0f; + g_chara_f_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + g_chara_f_ambient = 0.0f; + g_chara_f_diffuse = 0.0f; + g_chara_tc_param = 0.0f; + g_fog_depth_color = 0.0f; + g_fog_height_params = 0.0f; + g_fog_height_color = 0.0f; + g_fog_bump_params = 0.0f; + g_fog_state_params = 0.0f; + g_normal_tangent_transforms[0] = mat4_identity.row0; + g_normal_tangent_transforms[1] = mat4_identity.row1; + g_normal_tangent_transforms[2] = mat4_identity.row2; + g_esm_param = 0.0f; + g_self_shadow_receivers[0] = 0.0f; + g_self_shadow_receivers[1] = 0.0f; + g_self_shadow_receivers[2] = 0.0f; + g_self_shadow_receivers[3] = 0.0f; + g_self_shadow_receivers[4] = 0.0f; + g_self_shadow_receivers[5] = 0.0f; + g_shadow_ambient = 1.0f; + g_shadow_ambient1 = 0.0f; + g_framebuffer_size = { 1.0f / 1280.0f, 1.0f / 720.0f, 1.0f / 1280.0f, 1.0f / 720.0f, }; + g_light_reflect_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + g_clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; + g_npr_cloth_spec_color = 1.0f; + g_view[0] = mat4_identity.row0; + g_view[1] = mat4_identity.row1; + g_view[2] = mat4_identity.row2; + g_view_inverse[0] = mat4_identity.row0; + g_view_inverse[1] = mat4_identity.row1; + g_view_inverse[2] = mat4_identity.row2; + g_projection_view[0] = mat4_identity.row0; + g_projection_view[1] = mat4_identity.row1; + g_projection_view[2] = mat4_identity.row2; + g_projection_view[3] = mat4_identity.row3; + g_view_position = 0.0f; + g_light_projection[0] = mat4_identity.row0; + g_light_projection[1] = mat4_identity.row1; + g_light_projection[2] = mat4_identity.row2; + g_light_projection[3] = mat4_identity.row3; } -void obj_scene_shader_data::set_g_irradiance_g_transforms(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_irradiance_g_transforms[0] = temp.row0; - g_irradiance_g_transforms[1] = temp.row1; - g_irradiance_g_transforms[2] = temp.row2; - g_irradiance_g_transforms[3] = temp.row3; +void render_data::obj_batch_data::reset() { + g_transforms[0] = mat4_identity.row0; + g_transforms[1] = mat4_identity.row1; + g_transforms[2] = mat4_identity.row2; + g_transforms[3] = mat4_identity.row3; + g_worlds[0] = mat4_identity.row0; + g_worlds[1] = mat4_identity.row1; + g_worlds[2] = mat4_identity.row2; + g_worlds_invtrans[0] = mat4_identity.row0; + g_worlds_invtrans[1] = mat4_identity.row1; + g_worlds_invtrans[2] = mat4_identity.row2; + g_worldview[0] = mat4_identity.row0; + g_worldview[1] = mat4_identity.row1; + g_worldview[2] = mat4_identity.row2; + g_worldview_inverse[0] = mat4_identity.row0; + g_worldview_inverse[1] = mat4_identity.row1; + g_worldview_inverse[2] = mat4_identity.row2; + g_joint[0] = mat4_identity.row0; + g_joint[1] = mat4_identity.row1; + g_joint[2] = mat4_identity.row2; + g_joint_inverse[0] = mat4_identity.row0; + g_joint_inverse[1] = mat4_identity.row1; + g_joint_inverse[2] = mat4_identity.row2; + g_texcoord_transforms[0] = mat4_identity.row0; + g_texcoord_transforms[1] = mat4_identity.row1; + g_texcoord_transforms[2] = mat4_identity.row0; + g_texcoord_transforms[3] = mat4_identity.row1; + g_blend_color = 1.0f; + g_offset_color = 0.0f; + g_material_state_diffuse = 1.0f; + g_material_state_ambient = 0.0f; + g_material_state_emission = 0.0f; + g_material_state_shininess = { 0.0f, 0.0f, 0.0f, 1.0f }; + g_material_state_specular = 0.0f; + g_fresnel_coefficients = 0.0f; + g_texture_color_coefficients = 0.0f; + g_texture_color_offset = 0.0f; + g_texture_specular_coefficients = 0.0f; + g_texture_specular_offset = 0.0f; + g_shininess = 0.0f; + g_max_alpha = { 0.0f, 0.0f, 0.0f, 1.0f }; + g_morph_weight = { 1.0f, 0.0f, 0.0f, 0.0f }; + g_sss_param = 0.0f; + g_bump_depth = 0.0f; + g_intensity = 0.0f; + g_reflect_uv_scale = 0.0f; } -void obj_scene_shader_data::set_g_irradiance_b_transforms(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_irradiance_b_transforms[0] = temp.row0; - g_irradiance_b_transforms[1] = temp.row1; - g_irradiance_b_transforms[2] = temp.row2; - g_irradiance_b_transforms[3] = temp.row3; +void render_data::init() { + buffer_shader.Create(sizeof(obj_shader_data)); + buffer_scene.Create(sizeof(obj_scene_data)); + buffer_batch.Create(sizeof(obj_batch_data)); + buffer_skinning.Create(sizeof(obj_skinning_data)); + + buffer_shader_data.reset(); + enum_or(flags, RENDER_DATA_SHADER_UPDATE); + buffer_scene_data.reset(); + enum_or(flags, RENDER_DATA_SCENE_UPDATE); + buffer_batch_data.reset(); + enum_or(flags, RENDER_DATA_BATCH_UPDATE); } -void obj_scene_shader_data::set_g_normal_tangent_transforms(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_normal_tangent_transforms[0] = temp.row0; - g_normal_tangent_transforms[1] = temp.row1; - g_normal_tangent_transforms[2] = temp.row2; +void render_data::free() { + buffer_skinning.Destroy(); + buffer_batch.Destroy(); + buffer_scene.Destroy(); + buffer_shader.Destroy(); } -void obj_scene_shader_data::set_g_self_shadow_receivers(int32_t index, const mat4& mat) { - size_t _index = index * 3LL; +void render_data::set(render_context* rctx) { + shaders_ft.set(shader_index); - mat4 temp; - mat4_transpose(&mat, &temp); - g_self_shadow_receivers[_index + 0] = temp.row0; - g_self_shadow_receivers[_index + 1] = temp.row1; - g_self_shadow_receivers[_index + 2] = temp.row2; + if (flags & RENDER_DATA_SHADER_UPDATE) { + buffer_shader.WriteMemory(buffer_shader_data); + enum_and(flags, ~RENDER_DATA_SHADER_UPDATE); + } + + if (flags & RENDER_DATA_SCENE_UPDATE) { + buffer_scene.WriteMemory(buffer_scene_data); + enum_and(flags, ~RENDER_DATA_SCENE_UPDATE); + } + + if (flags & RENDER_DATA_BATCH_UPDATE) { + mat4 worlds; + worlds.row0 = buffer_batch_data.g_worlds[0]; + worlds.row1 = buffer_batch_data.g_worlds[1]; + worlds.row2 = buffer_batch_data.g_worlds[2]; + worlds.row3 = mat4_identity.row3; + mat4_transpose(&worlds, &worlds); + + mat4 temp; + mat4_mul(&worlds, &rctx->vp_mat, &temp); + mat4_transpose(&temp, &temp); + buffer_batch_data.g_transforms[0] = temp.row0; + buffer_batch_data.g_transforms[1] = temp.row1; + buffer_batch_data.g_transforms[2] = temp.row2; + buffer_batch_data.g_transforms[3] = temp.row3; + + mat4 worlds_inv; + mat4_invert(&worlds, &temp); + buffer_batch_data.g_worlds_invtrans[0] = temp.row0; + buffer_batch_data.g_worlds_invtrans[1] = temp.row1; + buffer_batch_data.g_worlds_invtrans[2] = temp.row2; + + mat4_mul(&worlds, &rctx->view_mat, &worlds); + mat4_transpose(&worlds, &temp); + buffer_batch_data.g_worldview[0] = temp.row0; + buffer_batch_data.g_worldview[1] = temp.row1; + buffer_batch_data.g_worldview[2] = temp.row2; + + mat4_invert(&worlds, &worlds); + mat4_transpose(&worlds, &temp); + buffer_batch_data.g_worldview_inverse[0] = temp.row0; + buffer_batch_data.g_worldview_inverse[1] = temp.row1; + buffer_batch_data.g_worldview_inverse[2] = temp.row2; + + temp.row0 = buffer_batch_data.g_joint[0]; + temp.row1 = buffer_batch_data.g_joint[1]; + temp.row2 = buffer_batch_data.g_joint[2]; + temp.row3 = mat4_identity.row3; + mat4_invert(&temp, &temp); + buffer_batch_data.g_joint_inverse[0] = temp.row0; + buffer_batch_data.g_joint_inverse[1] = temp.row1; + buffer_batch_data.g_joint_inverse[2] = temp.row2; + + buffer_batch.WriteMemory(buffer_batch_data); + enum_and(flags, ~RENDER_DATA_BATCH_UPDATE); + } + + buffer_shader.Bind(0); + buffer_scene.Bind(1); + buffer_batch.Bind(2); + + if (uniform->arr[U_SKINNING]) + buffer_skinning.Bind(0); } -void obj_scene_shader_data::set_g_light_projection(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_light_projection[0] = temp.row0; - g_light_projection[1] = temp.row1; - g_light_projection[2] = temp.row2; - g_light_projection[3] = temp.row3; -} +void render_data::set_shader(uint32_t index) { + shader_index = index; -void obj_scene_shader_data::set_projection_view(const mat4& view, const mat4& proj) { - mat4 temp; - mat4_transpose(&view, &temp); - g_view[0] = temp.row0; - g_view[1] = temp.row1; - g_view[2] = temp.row2; - - mat4_invert(&view, &temp); - mat4_transpose(&temp, &temp); - g_view_inverse[0] = temp.row0; - g_view_inverse[1] = temp.row1; - g_view_inverse[2] = temp.row2; - - mat4_mul(&view, &proj, &temp); - mat4_transpose(&temp, &temp); - g_projection_view[0] = temp.row0; - g_projection_view[1] = temp.row1; - g_projection_view[2] = temp.row2; - g_projection_view[3] = temp.row3; -} - -void obj_batch_shader_data::set_g_joint(const mat4& mat) { - mat4 temp; - mat4_transpose(&mat, &temp); - g_joint[0] = temp.row0; - g_joint[1] = temp.row1; - g_joint[2] = temp.row2; - - mat4_invert(&mat, &temp); - mat4_transpose(&temp, &temp); - g_joint_inverse[0] = temp.row0; - g_joint_inverse[1] = temp.row1; - g_joint_inverse[2] = temp.row2; -} - -void obj_batch_shader_data::set_g_texcoord_transforms(int32_t index, const mat4& mat) { - size_t _index = index * 2LL; - - mat4 temp; - mat4_transpose(&mat, &temp); - g_texcoord_transforms[_index + 0] = temp.row0; - g_texcoord_transforms[_index + 1] = temp.row1; -} - -void obj_batch_shader_data::set_transforms(const mat4& model, const mat4& view, const mat4& proj) { - mat4 temp; - mat4_transpose(&model, &temp); - g_worlds[0] = temp.row0; - g_worlds[1] = temp.row1; - g_worlds[2] = temp.row2; - - mat4_invert(&model, &temp); - g_worlds_invtrans[0] = temp.row0; - g_worlds_invtrans[1] = temp.row1; - g_worlds_invtrans[2] = temp.row2; - - mat4 mv; - mat4_mul(&model, &view, &mv); - - mat4_transpose(&mv, &temp); - g_worldview[0] = temp.row0; - g_worldview[1] = temp.row1; - g_worldview[2] = temp.row2; - - mat4_invert(&mv, &temp); - mat4_transpose(&temp, &temp); - g_worldview_inverse[0] = temp.row0; - g_worldview_inverse[1] = temp.row1; - g_worldview_inverse[2] = temp.row2; - - mat4_mul(&mv, &proj, &temp); - mat4_transpose(&temp, &temp); - g_transforms[0] = temp.row0; - g_transforms[1] = temp.row1; - g_transforms[2] = temp.row2; - g_transforms[3] = temp.row3; + buffer_shader_data.set_shader_flags(uniform->arr); + enum_or(flags, RENDER_DATA_SHADER_UPDATE); } render_context::render_context() : box_vao(), lens_ghost_vao(), common_vao(), reflect_buffer(), @@ -342,14 +435,8 @@ samplers(), render_samplers(), sprite_samplers(), screen_width(), screen_height( tone_map_ubo.Create(sizeof(tone_map_shader_data)); transparency_batch_ubo.Create(sizeof(transparency_batch_shader_data)); - obj_shader = {}; - obj_scene = {}; - obj_batch = {}; - obj_skinning = {}; - obj_shader_ubo.Create(sizeof(obj_shader_shader_data)); - obj_scene_ubo.Create(sizeof(obj_scene_shader_data)); - obj_batch_ubo.Create(sizeof(obj_batch_shader_data)); - obj_skinning_ssbo.Create(sizeof(obj_skinning_shader_data)); + data = {}; + data.init(); static const vec4 border_color = 0.0f; @@ -449,10 +536,7 @@ render_context::~render_context() { glDeleteSamplers(4, render_samplers); glDeleteSamplers(18, samplers); - obj_skinning_ssbo.Destroy(); - obj_batch_ubo.Destroy(); - obj_scene_ubo.Destroy(); - obj_shader_ubo.Destroy(); + data.free(); transparency_batch_ubo.Destroy(); tone_map_ubo.Destroy(); @@ -608,6 +692,327 @@ void render_context::init() { screen_buffer.Init(screen_width, screen_height, 0, GL_RGBA8, 0); } +void render_context::get_scene_fog_params(render_context::fog_params& value) { + render_data* data = &this->data; + value.depth_color = data->buffer_scene_data.g_fog_depth_color; + value.height_params = data->buffer_scene_data.g_fog_height_params; + value.height_color = data->buffer_scene_data.g_fog_height_color; + value.bump_params = data->buffer_scene_data.g_fog_bump_params; + value.density = data->buffer_scene_data.g_fog_state_params.x; + value.start = data->buffer_scene_data.g_fog_state_params.y; + value.end = data->buffer_scene_data.g_fog_state_params.z; +} + +void render_context::get_scene_light(vec4* light_env_stage_diffuse, + vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, + vec4* light_env_chara_diffuse, vec4* light_env_chara_specular) { + render_data* data = &this->data; + if (light_env_stage_diffuse) + *light_env_stage_diffuse = data->buffer_scene_data.g_light_env_stage_diffuse; + if (light_env_stage_specular) + *light_env_stage_specular = data->buffer_scene_data.g_light_env_stage_specular; + if (light_chara_dir) + *light_chara_dir = data->buffer_scene_data.g_light_chara_dir; + if (light_chara_luce) + *light_chara_luce = data->buffer_scene_data.g_light_chara_luce; + if (light_env_chara_diffuse) + *light_env_chara_diffuse = data->buffer_scene_data.g_light_env_chara_diffuse; + if (light_env_chara_specular) + *light_env_chara_specular = data->buffer_scene_data.g_light_env_chara_specular; +} + +void render_context::set_batch_alpha_threshold(const float_t value) { + render_data* data = &this->data; + data->buffer_batch_data.g_max_alpha.z = value; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_blend_color(const vec4& blend_color) { + render_data* data = &this->data; + data->buffer_batch_data.g_blend_color = blend_color; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_blend_color_offset_color( + const vec4& blend_color, const vec4& offset_color) { + render_data* data = &this->data; + data->buffer_batch_data.g_blend_color = blend_color; + data->buffer_batch_data.g_offset_color = offset_color; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_joint(const mat4& mat) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&mat, &temp); + if (data->buffer_batch_data.g_joint[0] != temp.row0 + || data->buffer_batch_data.g_joint[1] != temp.row1 + || data->buffer_batch_data.g_joint[2] != temp.row2) { + data->buffer_batch_data.g_joint[0] = temp.row0; + data->buffer_batch_data.g_joint[1] = temp.row1; + data->buffer_batch_data.g_joint[2] = temp.row2; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); + } +} + +void render_context::set_batch_material_color(const vec4& diffuse, const vec4& ambient, + const vec4& emission, const float_t material_shininess, const vec4& specular, + const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, + const vec4& texture_color_offset, const vec4& texture_specular_coefficients, + const vec4& texture_specular_offset, const float_t shininess) { + render_data* data = &this->data; + data->buffer_batch_data.g_material_state_diffuse = diffuse; + data->buffer_batch_data.g_material_state_ambient = ambient; + data->buffer_batch_data.g_material_state_emission = emission; + data->buffer_batch_data.g_material_state_shininess = { material_shininess, 0.0f, 0.0f, 1.0f }; + data->buffer_batch_data.g_material_state_specular = specular; + data->buffer_batch_data.g_fresnel_coefficients = fresnel_coefficients; + data->buffer_batch_data.g_texture_color_coefficients = texture_color_coefficients; + data->buffer_batch_data.g_texture_color_offset = texture_color_offset; + data->buffer_batch_data.g_texture_specular_coefficients = texture_specular_coefficients; + data->buffer_batch_data.g_shininess.x = shininess; + data->buffer_batch_data.g_texture_specular_offset = texture_specular_offset; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_material_color_emission(const vec4& emission) { + render_data* data = &this->data; + data->buffer_batch_data.g_material_state_emission = emission; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, + const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale) { + render_data* data = &this->data; + if (specular) + data->buffer_batch_data.g_material_state_specular = *specular; + data->buffer_batch_data.g_bump_depth = bump_depth; + data->buffer_batch_data.g_intensity = intensity; + data->buffer_batch_data.g_reflect_uv_scale.x = reflect_uv_scale; + data->buffer_batch_data.g_reflect_uv_scale.y = reflect_uv_scale; + data->buffer_batch_data.g_reflect_uv_scale.z = refract_uv_scale; + data->buffer_batch_data.g_reflect_uv_scale.w = refract_uv_scale; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_min_alpha(const float_t value) { + render_data* data = &this->data; + data->buffer_batch_data.g_max_alpha.w = value; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_morph_weight(const float_t value) { + render_data* data = &this->data; + data->buffer_batch_data.g_morph_weight.x = value; + data->buffer_batch_data.g_morph_weight.y = 1.0f - value; + data->buffer_batch_data.g_morph_weight.z = 0.0f; + data->buffer_batch_data.g_morph_weight.w = 0.0f; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_offset_color(const vec4& offset_color) { + render_data* data = &this->data; + data->buffer_batch_data.g_offset_color = offset_color; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_sss_param(const vec4& sss_param) { + render_data* data = &this->data; + data->buffer_batch_data.g_sss_param = sss_param; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_texcoord_transforms(const mat4 mats[2]) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&mats[0], &temp); + data->buffer_batch_data.g_texcoord_transforms[0] = temp.row0; + data->buffer_batch_data.g_texcoord_transforms[1] = temp.row1; + mat4_transpose(&mats[1], &temp); + data->buffer_batch_data.g_texcoord_transforms[2] = temp.row0; + data->buffer_batch_data.g_texcoord_transforms[3] = temp.row1; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); +} + +void render_context::set_batch_worlds(const mat4& mat) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&mat, &temp); + if (data->buffer_batch_data.g_worlds[0] != temp.row0 + || data->buffer_batch_data.g_worlds[1] != temp.row1 + || data->buffer_batch_data.g_worlds[2] != temp.row2) { + data->buffer_batch_data.g_worlds[0] = temp.row0; + data->buffer_batch_data.g_worlds[1] = temp.row1; + data->buffer_batch_data.g_worlds[2] = temp.row2; + enum_or(data->flags, RENDER_DATA_BATCH_UPDATE); + } +} + +void render_context::set_glitter_render_data() { + render_data* data = &this->data; + data->buffer_shader_data.set_shader_flags(uniform->arr); + data->buffer_shader.WriteMemory(data->buffer_shader_data); + data->buffer_shader.Bind(0); + + if (data->flags & RENDER_DATA_SCENE_UPDATE) { + data->buffer_scene.WriteMemory(data->buffer_scene_data); + enum_and(data->flags, ~RENDER_DATA_SCENE_UPDATE); + } + data->buffer_scene.Bind(1); +} + +void render_context::set_render_data() { + data.set(this); +} + +void render_context::set_scene_fog_params(const render_context::fog_params& value) { + render_data* data = &this->data; + data->buffer_scene_data.g_fog_depth_color = value.depth_color; + data->buffer_scene_data.g_fog_height_params = value.height_params; + data->buffer_scene_data.g_fog_height_color = value.height_color; + data->buffer_scene_data.g_fog_bump_params = value.bump_params; + const float_t start = value.start; + const float_t end = value.end; + data->buffer_scene_data.g_fog_state_params.x = value.density; + data->buffer_scene_data.g_fog_state_params.y = value.start; + data->buffer_scene_data.g_fog_state_params.z = value.end; + data->buffer_scene_data.g_fog_state_params.w = end - start > 0.0f ? 1.0f / (end - start) : 0.0f; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_context::set_scene_framebuffer_size(const int32_t width, const int32_t height, + const int32_t render_width, const int32_t render_height) { + render_data* data = &this->data; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); + data->buffer_scene_data.g_framebuffer_size.x = 1.0f / (float_t)width; + data->buffer_scene_data.g_framebuffer_size.y = 1.0f / (float_t)height; + data->buffer_scene_data.g_framebuffer_size.w = 1.0f / (float_t)render_height; + data->buffer_scene_data.g_framebuffer_size.z = 1.0f / (float_t)render_width; +} + +void render_context::set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, + const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, + const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, + const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, + const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, + const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, + const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, + const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, + const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, + const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, + const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, + const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&irradiance_r_transforms, &temp); + data->buffer_scene_data.g_irradiance_r_transforms[0] = temp.row0; + data->buffer_scene_data.g_irradiance_r_transforms[1] = temp.row1; + data->buffer_scene_data.g_irradiance_r_transforms[2] = temp.row2; + data->buffer_scene_data.g_irradiance_r_transforms[3] = temp.row3; + mat4_transpose(&irradiance_g_transforms, &temp); + data->buffer_scene_data.g_irradiance_g_transforms[0] = temp.row0; + data->buffer_scene_data.g_irradiance_g_transforms[1] = temp.row1; + data->buffer_scene_data.g_irradiance_g_transforms[2] = temp.row2; + data->buffer_scene_data.g_irradiance_g_transforms[3] = temp.row3; + mat4_transpose(&irradiance_b_transforms, &temp); + data->buffer_scene_data.g_irradiance_b_transforms[0] = temp.row0; + data->buffer_scene_data.g_irradiance_b_transforms[1] = temp.row1; + data->buffer_scene_data.g_irradiance_b_transforms[2] = temp.row2; + data->buffer_scene_data.g_irradiance_b_transforms[3] = temp.row3; + data->buffer_scene_data.g_light_env_stage_diffuse = light_env_stage_diffuse; + data->buffer_scene_data.g_light_env_stage_specular = light_env_stage_specular; + data->buffer_scene_data.g_light_env_chara_diffuse = light_env_chara_diffuse; + data->buffer_scene_data.g_light_env_chara_ambient = light_env_chara_ambient; + data->buffer_scene_data.g_light_env_chara_specular = light_env_chara_specular; + data->buffer_scene_data.g_light_env_reflect_diffuse = light_env_reflect_diffuse; + data->buffer_scene_data.g_light_env_reflect_ambient = light_env_reflect_ambient; + data->buffer_scene_data.g_light_env_proj_diffuse = light_env_proj_diffuse; + data->buffer_scene_data.g_light_env_proj_specular = light_env_proj_specular; + data->buffer_scene_data.g_light_env_proj_position = light_env_proj_position; + data->buffer_scene_data.g_light_stage_dir = light_stage_dir; + data->buffer_scene_data.g_light_stage_diff = light_stage_diff; + data->buffer_scene_data.g_light_stage_spec = light_stage_spec; + data->buffer_scene_data.g_light_chara_dir = light_chara_dir; + data->buffer_scene_data.g_light_chara_spec = light_chara_spec; + data->buffer_scene_data.g_light_chara_luce = light_chara_luce; + data->buffer_scene_data.g_light_chara_back = light_chara_back; + data->buffer_scene_data.g_light_face_diff = light_face_diff; + data->buffer_scene_data.g_chara_color0 = chara_color0; + data->buffer_scene_data.g_chara_color1 = chara_color1; + data->buffer_scene_data.g_chara_f_dir = chara_f_dir; + data->buffer_scene_data.g_chara_f_ambient = chara_f_ambient; + data->buffer_scene_data.g_chara_f_diffuse = chara_f_diffuse; + data->buffer_scene_data.g_chara_tc_param = chara_tc_param; + mat4_transpose(&normal_tangent_transforms, &temp); + data->buffer_scene_data.g_normal_tangent_transforms[0] = temp.row0; + data->buffer_scene_data.g_normal_tangent_transforms[1] = temp.row1; + data->buffer_scene_data.g_normal_tangent_transforms[2] = temp.row2; + data->buffer_scene_data.g_light_reflect_dir = light_reflect_dir; + data->buffer_scene_data.g_clip_plane = clip_plane; + data->buffer_scene_data.g_npr_cloth_spec_color = npr_cloth_spec_color; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_context::set_scene_light_projection(const mat4& light_projection) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&light_projection, &temp); + data->buffer_scene_data.g_light_projection[0] = temp.row0; + data->buffer_scene_data.g_light_projection[1] = temp.row1; + data->buffer_scene_data.g_light_projection[2] = temp.row2; + data->buffer_scene_data.g_light_projection[3] = temp.row3; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_context::set_scene_projection_view(const mat4& view, const mat4& proj, const vec3& view_position) { + render_data* data = &this->data; + mat4 temp; + mat4_transpose(&view, &temp); + data->buffer_scene_data.g_view[0] = temp.row0; + data->buffer_scene_data.g_view[1] = temp.row1; + data->buffer_scene_data.g_view[2] = temp.row2; + + mat4_invert(&view, &temp); + mat4_transpose(&temp, &temp); + data->buffer_scene_data.g_view_inverse[0] = temp.row0; + data->buffer_scene_data.g_view_inverse[1] = temp.row1; + data->buffer_scene_data.g_view_inverse[2] = temp.row2; + + mat4_mul(&view, &proj, &temp); + mat4_transpose(&temp, &temp); + data->buffer_scene_data.g_projection_view[0] = temp.row0; + data->buffer_scene_data.g_projection_view[1] = temp.row1; + data->buffer_scene_data.g_projection_view[2] = temp.row2; + data->buffer_scene_data.g_projection_view[3] = temp.row3; + data->buffer_scene_data.g_view_position.x = view_position.x; + data->buffer_scene_data.g_view_position.y = view_position.y; + data->buffer_scene_data.g_view_position.z = view_position.z; + data->buffer_scene_data.g_view_position.w = 0.0f; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_context::set_scene_shadow_params(const float_t esm_param, + const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1) { + render_data* data = &this->data; + data->buffer_scene_data.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f }; + mat4 temp; + mat4_transpose(&mats[0], &temp); + data->buffer_scene_data.g_self_shadow_receivers[0] = temp.row0; + data->buffer_scene_data.g_self_shadow_receivers[1] = temp.row1; + data->buffer_scene_data.g_self_shadow_receivers[2] = temp.row2; + mat4_transpose(&mats[1], &temp); + data->buffer_scene_data.g_self_shadow_receivers[3] = temp.row0; + data->buffer_scene_data.g_self_shadow_receivers[4] = temp.row1; + data->buffer_scene_data.g_self_shadow_receivers[5] = temp.row2; + data->buffer_scene_data.g_shadow_ambient = shadow_ambient; + data->buffer_scene_data.g_shadow_ambient1 = shadow_ambient1; + enum_or(data->flags, RENDER_DATA_SCENE_UPDATE); +} + +void render_context::set_shader(uint32_t index) { + data.set_shader(index); +} + sss_data* sss_data_get() { return &_sss_data; } diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp index 4a5c096..d7ea7f4 100644 --- a/src/DivaGL/render_context.hpp +++ b/src/DivaGL/render_context.hpp @@ -19,6 +19,12 @@ #include "render_manager.hpp" #include "render_texture.hpp" +enum render_data_flags { + RENDER_DATA_SHADER_UPDATE = 0x01, + RENDER_DATA_SCENE_UPDATE = 0x02, + RENDER_DATA_BATCH_UPDATE = 0x04, +}; + struct draw_state_stats { int32_t object_draw_count; int32_t object_translucent_draw_count; @@ -139,201 +145,6 @@ struct glitter_batch_shader_data { vec4 g_state_material_emission; }; -struct obj_shader_shader_data { - struct { - union { - struct { - uint32_t alpha_mask : 1; // bit 0 - uint32_t alpha_test : 1; // bit 1 - uint32_t aniso : 2; // bit 2:3 - uint32_t aet_back : 1; // bit 4 - uint32_t texture_blend : 3; // bit 5:7 - uint32_t unk : 2; // bit 8:9 - uint32_t chara_color : 1; // bit 10 - uint32_t clip_plane : 1; // bit 11 - uint32_t u08 : 1; // bit 12 - uint32_t depth_peel : 1; // bit 13 - uint32_t depth : 1; // bit 14 - uint32_t u0b : 1; // bit 15 - uint32_t alpha_blend : 3; // bit 16:18 - uint32_t ripple_emit : 1; // bit 19 - uint32_t esm_filter : 2; // bit 20:21 - uint32_t exposure : 2; // bit 22:23 - uint32_t scene_fade : 1; // bit 24 - uint32_t fade : 3; // bit 25:27 - uint32_t stage_ambient : 1; // bit 28 - uint32_t flare : 2; // bit 29:30 - } m; - uint32_t w; - } x; - union { - struct { - uint32_t fog_stage : 2; // bit 32+0:1 - uint32_t fog_chara : 2; // bit 32+2:3 - uint32_t u16 : 1; // bit 32+4 - uint32_t gauss : 2; // bit 32+5:6 - uint32_t eyeball : 1; // bit 32+7 - uint32_t image_filter : 3; // bit 32+8:10 - uint32_t instance : 1; // bit 32+11 - uint32_t tone_curve : 1; // bit 32+12 - uint32_t light_proj : 1; // bit 32+13 - uint32_t magnify : 4; // bit 32+14:17 - uint32_t membrane : 2; // bit 32+18:19 - uint32_t mlaa : 2; // bit 32+20:21 - uint32_t mlaa_search : 2; // bit 32+22:23 - uint32_t morph_color : 1; // bit 32+24 - uint32_t morph : 1; // bit 32+25 - uint32_t movie : 2; // bit 32+26:27 - uint32_t u24 : 2; // bit 32+28:29 - uint32_t u25 : 1; // bit 32+30 - uint32_t npr_normal : 1; // bit 32+31 - } m; - uint32_t w; - } y; - union { - struct { - uint32_t npr : 1; // bit 64+0 - uint32_t stage_shadow2 : 2; // bit 64+1:2 - uint32_t reflect : 2; // bit 64+3:4 - uint32_t reduce : 4; // bit 64+5:8 - uint32_t chara_shadow : 1; // bit 64+9 - uint32_t chara_shadow2 : 2; // bit 64+10:11 - uint32_t u2d : 3; // bit 64+12:14 - uint32_t u2e : 2; // bit 64+15:16 - uint32_t show_vector : 2; // bit 64+17:18 - uint32_t skinning : 1; // bit 64+19 - uint32_t snow_particle : 2; // bit 64+20:21 - uint32_t specular_ibl : 2; // bit 64+22:23 - uint32_t combiner : 1; // bit 64+24 - uint32_t tex_0_type : 2; // bit 64+25:26 - uint32_t tex_1_type : 2; // bit 64+27:28 - uint32_t sss_filter : 2; // bit 64+29:30 - } m; - uint32_t w; - } z; - union { - struct { - uint32_t sss_chara : 1; // bit 96+0 - uint32_t star : 1; // bit 96+1 - uint32_t texture_count : 2; // bit 96+2:3 - uint32_t env_map : 1; // bit 96+4 - uint32_t ripple : 2; // bit 96+5:6 - uint32_t translucency : 1; // bit 96+7 - uint32_t normal : 1; // bit 96+8 - uint32_t transparency : 1; // bit 96+9 - uint32_t water_reflect : 1; // bit 96+10 - uint32_t u40 : 1; // bit 96+11 - uint32_t u41 : 1; // bit 96+12 - uint32_t stage_shadow : 1; // bit 96+13 - uint32_t specular : 1; // bit 96+14 - uint32_t tone_map : 2; // bit 96+15 - uint32_t u45 : 1; // bit 96+16 - } m; - uint32_t w; - } w; - } g_shader_flags; - - void set_shader_flags(int32_t* shader_flags); -}; - -struct obj_scene_shader_data { - vec4 g_irradiance_r_transforms[4]; - vec4 g_irradiance_g_transforms[4]; - vec4 g_irradiance_b_transforms[4]; - vec4 g_light_env_stage_diffuse; - vec4 g_light_env_stage_specular; - vec4 g_light_env_chara_diffuse; - vec4 g_light_env_chara_ambient; - vec4 g_light_env_chara_specular; - vec4 g_light_env_reflect_diffuse; - vec4 g_light_env_reflect_ambient; - vec4 g_light_env_proj_diffuse; - vec4 g_light_env_proj_specular; - vec4 g_light_env_proj_position; - vec4 g_light_stage_dir; - vec4 g_light_stage_diff; - vec4 g_light_stage_spec; - vec4 g_light_chara_dir; - vec4 g_light_chara_spec; - vec4 g_light_chara_luce; - vec4 g_light_chara_back; - vec4 g_light_face_diff; - vec4 g_chara_color_rim; - vec4 g_chara_color0; - vec4 g_chara_color1; - vec4 g_chara_f_dir; - vec4 g_chara_f_ambient; - vec4 g_chara_f_diffuse; - vec4 g_chara_tc_param; - vec4 g_fog_depth_color; - vec4 g_fog_height_params; //x=density, y=start, z=end, w=1/(end-start) - vec4 g_fog_height_color; - vec4 g_fog_bump_params; //x=density, y=start, z=end, w=1/(end-start) - vec4 g_fog_state_params; //x=density, y=start, z=end, w=1/(end-start) - vec4 g_normal_tangent_transforms[3]; - vec4 g_esm_param; - vec4 g_self_shadow_receivers[6]; - vec4 g_shadow_ambient; - vec4 g_shadow_ambient1; - vec4 g_framebuffer_size; - vec4 g_light_reflect_dir; - vec4 g_clip_plane; - vec4 g_npr_cloth_spec_color; - vec4 g_view[3]; - vec4 g_view_inverse[3]; - vec4 g_projection_view[4]; - vec4 g_view_position; - vec4 g_light_projection[4]; - - void set_g_irradiance_r_transforms(const mat4& mat); - void set_g_irradiance_g_transforms(const mat4& mat); - void set_g_irradiance_b_transforms(const mat4& mat); - void set_g_normal_tangent_transforms(const mat4& mat); - void set_g_self_shadow_receivers(int32_t index, const mat4& mat); - void set_g_light_projection(const mat4& mat); - - void set_projection_view(const mat4& view, const mat4& proj); -}; - -struct obj_batch_shader_data { - vec4 g_transforms[4]; - vec4 g_worlds[3]; - vec4 g_worlds_invtrans[3]; - vec4 g_worldview[3]; - vec4 g_worldview_inverse[3]; - vec4 g_joint[3]; - vec4 g_joint_inverse[3]; - vec4 g_texcoord_transforms[4]; - vec4 g_blend_color; - vec4 g_offset_color; - vec4 g_material_state_diffuse; - vec4 g_material_state_ambient; - vec4 g_material_state_emission; - vec4 g_material_state_shininess; - vec4 g_material_state_specular; - vec4 g_fresnel_coefficients; - vec4 g_texture_color_coefficients; - vec4 g_texture_color_offset; - vec4 g_texture_specular_coefficients; - vec4 g_texture_specular_offset; - vec4 g_shininess; - vec4 g_max_alpha; - vec4 g_morph_weight; - vec4 g_sss_param; - vec4 g_bump_depth; - vec4 g_intensity; - vec4 g_reflect_uv_scale; - - void set_g_joint(const mat4& mat); - void set_g_texcoord_transforms(int32_t index, const mat4& mat); - - void set_transforms(const mat4& model, const mat4& view, const mat4& proj); -}; - -struct obj_skinning_shader_data { - vec4 g_joint_transforms[768]; -}; - struct quad_shader_data { vec4 g_texcoord_modifier; vec4 g_texel_size; @@ -369,7 +180,223 @@ struct transparency_batch_shader_data { vec4 g_opacity; }; +struct render_context; + +struct render_data { + struct obj_shader_data { + struct { + union { + struct { + uint32_t alpha_mask : 1; // bit 0 + uint32_t alpha_test : 1; // bit 1 + uint32_t aniso : 2; // bit 2:3 + uint32_t aet_back : 1; // bit 4 + uint32_t texture_blend : 3; // bit 5:7 + uint32_t unk : 2; // bit 8:9 + uint32_t chara_color : 1; // bit 10 + uint32_t clip_plane : 1; // bit 11 + uint32_t u08 : 1; // bit 12 + uint32_t depth_peel : 1; // bit 13 + uint32_t depth : 1; // bit 14 + uint32_t u0b : 1; // bit 15 + uint32_t alpha_blend : 3; // bit 16:18 + uint32_t ripple_emit : 1; // bit 19 + uint32_t esm_filter : 2; // bit 20:21 + uint32_t exposure : 2; // bit 22:23 + uint32_t scene_fade : 1; // bit 24 + uint32_t fade : 3; // bit 25:27 + uint32_t stage_ambient : 1; // bit 28 + uint32_t flare : 2; // bit 29:30 + } m; + uint32_t w; + } x; + union { + struct { + uint32_t fog_stage : 2; // bit 32+0:1 + uint32_t fog_chara : 2; // bit 32+2:3 + uint32_t u16 : 1; // bit 32+4 + uint32_t gauss : 2; // bit 32+5:6 + uint32_t eye_lens : 1; // bit 32+7 + uint32_t image_filter : 3; // bit 32+8:10 + uint32_t instance : 1; // bit 32+11 + uint32_t tone_curve : 1; // bit 32+12 + uint32_t light_proj : 1; // bit 32+13 + uint32_t magnify : 4; // bit 32+14:17 + uint32_t membrane : 2; // bit 32+18:19 + uint32_t mlaa : 2; // bit 32+20:21 + uint32_t mlaa_search : 2; // bit 32+22:23 + uint32_t morph_color : 1; // bit 32+24 + uint32_t morph : 1; // bit 32+25 + uint32_t movie : 2; // bit 32+26:27 + uint32_t u24 : 2; // bit 32+28:29 + uint32_t u25 : 1; // bit 32+30 + uint32_t npr_normal : 1; // bit 32+31 + } m; + uint32_t w; + } y; + union { + struct { + uint32_t npr : 1; // bit 64+0 + uint32_t stage_shadow2 : 2; // bit 64+1:2 + uint32_t reflect : 2; // bit 64+3:4 + uint32_t reduce : 4; // bit 64+5:8 + uint32_t chara_shadow : 1; // bit 64+9 + uint32_t chara_shadow2 : 2; // bit 64+10:11 + uint32_t u2d : 3; // bit 64+12:14 + uint32_t u2e : 2; // bit 64+15:16 + uint32_t show_vector : 2; // bit 64+17:18 + uint32_t skinning : 1; // bit 64+19 + uint32_t snow_particle : 2; // bit 64+20:21 + uint32_t specular_ibl : 2; // bit 64+22:23 + uint32_t combiner : 1; // bit 64+24 + uint32_t tex_0_type : 2; // bit 64+25:26 + uint32_t tex_1_type : 2; // bit 64+27:28 + uint32_t sss_filter : 2; // bit 64+29:30 + } m; + uint32_t w; + } z; + union { + struct { + uint32_t sss_chara : 1; // bit 96+0 + uint32_t star : 1; // bit 96+1 + uint32_t texture_count : 2; // bit 96+2:3 + uint32_t env_map : 1; // bit 96+4 + uint32_t ripple : 2; // bit 96+5:6 + uint32_t translucency : 1; // bit 96+7 + uint32_t normal : 1; // bit 96+8 + uint32_t transparency : 1; // bit 96+9 + uint32_t water_reflect : 1; // bit 96+10 + uint32_t u40 : 1; // bit 96+11 + uint32_t u41 : 1; // bit 96+12 + uint32_t stage_shadow : 1; // bit 96+13 + uint32_t specular : 1; // bit 96+14 + uint32_t tone_map : 2; // bit 96+15 + uint32_t u45 : 1; // bit 96+16 + } m; + uint32_t w; + } w; + } g_shader_flags; + + void reset(); + void set_shader_flags(const int32_t* shader_flags); + }; + + struct obj_scene_data { + vec4 g_irradiance_r_transforms[4]; + vec4 g_irradiance_g_transforms[4]; + vec4 g_irradiance_b_transforms[4]; + vec4 g_light_env_stage_diffuse; + vec4 g_light_env_stage_specular; + vec4 g_light_env_chara_diffuse; + vec4 g_light_env_chara_ambient; + vec4 g_light_env_chara_specular; + vec4 g_light_env_reflect_diffuse; + vec4 g_light_env_reflect_ambient; + vec4 g_light_env_proj_diffuse; + vec4 g_light_env_proj_specular; + vec4 g_light_env_proj_position; + vec4 g_light_stage_dir; + vec4 g_light_stage_diff; + vec4 g_light_stage_spec; + vec4 g_light_chara_dir; + vec4 g_light_chara_spec; + vec4 g_light_chara_luce; + vec4 g_light_chara_back; + vec4 g_light_face_diff; + vec4 g_chara_color_rim; + vec4 g_chara_color0; + vec4 g_chara_color1; + vec4 g_chara_f_dir; + vec4 g_chara_f_ambient; + vec4 g_chara_f_diffuse; + vec4 g_chara_tc_param; + vec4 g_fog_depth_color; + vec4 g_fog_height_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_fog_height_color; + vec4 g_fog_bump_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_fog_state_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_normal_tangent_transforms[3]; + vec4 g_esm_param; + vec4 g_self_shadow_receivers[6]; + vec4 g_shadow_ambient; + vec4 g_shadow_ambient1; + vec4 g_framebuffer_size; + vec4 g_light_reflect_dir; + vec4 g_clip_plane; + vec4 g_npr_cloth_spec_color; + vec4 g_view[3]; + vec4 g_view_inverse[3]; + vec4 g_projection_view[4]; + vec4 g_view_position; + vec4 g_light_projection[4]; + + void reset(); + }; + + struct obj_batch_data { + vec4 g_transforms[4]; + vec4 g_worlds[3]; + vec4 g_worlds_invtrans[3]; + vec4 g_worldview[3]; + vec4 g_worldview_inverse[3]; + vec4 g_joint[3]; + vec4 g_joint_inverse[3]; + vec4 g_texcoord_transforms[4]; + vec4 g_blend_color; + vec4 g_offset_color; + vec4 g_material_state_diffuse; + vec4 g_material_state_ambient; + vec4 g_material_state_emission; + vec4 g_material_state_shininess; + vec4 g_material_state_specular; + vec4 g_fresnel_coefficients; + vec4 g_texture_color_coefficients; + vec4 g_texture_color_offset; + vec4 g_texture_specular_coefficients; + vec4 g_texture_specular_offset; + vec4 g_shininess; + vec4 g_max_alpha; + vec4 g_morph_weight; + vec4 g_sss_param; + vec4 g_bump_depth; + vec4 g_intensity; + vec4 g_reflect_uv_scale; + + void reset(); + }; + + struct obj_skinning_data { + vec4 g_joint_transforms[768]; + }; + + render_data_flags flags; + int32_t shader_index; + obj_shader_data buffer_shader_data; + obj_scene_data buffer_scene_data; + obj_batch_data buffer_batch_data; + obj_skinning_data buffer_skinning_data; + GL::UniformBuffer buffer_shader; + GL::UniformBuffer buffer_scene; + GL::UniformBuffer buffer_batch; + GL::ShaderStorageBuffer buffer_skinning; + + void init(); + void free(); + void set(render_context* rctx); + void set_shader(uint32_t index); +}; + struct render_context { + struct fog_params { + vec4 depth_color; + vec4 height_params; + vec4 height_color; + vec4 bump_params; + float_t density; + float_t start; + float_t end; + }; + mat4 view_mat; mat4 proj_mat; mat4 vp_mat; @@ -405,14 +432,7 @@ struct render_context { GL::UniformBuffer tone_map_ubo; GL::UniformBuffer transparency_batch_ubo; - obj_shader_shader_data obj_shader; - obj_scene_shader_data obj_scene; - obj_batch_shader_data obj_batch; - obj_skinning_shader_data obj_skinning; - GL::UniformBuffer obj_shader_ubo; - GL::UniformBuffer obj_scene_ubo; - GL::UniformBuffer obj_batch_ubo; - GL::ShaderStorageBuffer obj_skinning_ssbo; + render_data data; texture* empty_texture_2d; texture* empty_texture_cube_map; @@ -432,6 +452,51 @@ struct render_context { void ctrl(bool change_res = true); void free(); void init(); + + void get_scene_fog_params(render_context::fog_params& value); + void get_scene_light(vec4* light_env_stage_diffuse, + vec4* light_env_stage_specular, vec4* light_chara_dir, vec4* light_chara_luce, + vec4* light_env_chara_diffuse, vec4* light_env_chara_specular); + void set_batch_alpha_threshold(const float_t value); + void set_batch_blend_color(const vec4& blend_color); + void set_batch_blend_color_offset_color(const vec4& blend_color, const vec4& offset_color); + void set_batch_joint(const mat4& mat); + void set_batch_material_color(const vec4& diffuse, const vec4& ambient, + const vec4& emission, const float_t material_shininess, const vec4& specular, + const vec4& fresnel_coefficients, const vec4& texture_color_coefficients, + const vec4& texture_color_offset, const vec4& texture_specular_coefficients, + const vec4& texture_specular_offset, const float_t shininess); + void set_batch_material_color_emission(const vec4& emission); + void set_batch_material_parameter(const vec4* specular, const vec4& bump_depth, + const vec4& intensity, const float_t reflect_uv_scale, const float_t refract_uv_scale); + void set_batch_min_alpha(const float_t value); + void set_batch_morph_weight(const float_t value); + void set_batch_offset_color(const vec4& offset_color); + void set_batch_sss_param(const vec4& sss_param); + void set_batch_texcoord_transforms(const mat4 mats[2]); + void set_batch_worlds(const mat4& mat); + void set_glitter_render_data(); + void set_render_data(); + void set_scene_fog_params(const render_context::fog_params& value); + void set_scene_framebuffer_size(const int32_t width, const int32_t height, + const int32_t render_width, const int32_t render_height); + void set_scene_light(const mat4& irradiance_r_transforms, const mat4& irradiance_g_transforms, + const mat4& irradiance_b_transforms, const vec4& light_env_stage_diffuse, + const vec4& light_env_stage_specular, const vec4& light_env_chara_diffuse, + const vec4& light_env_chara_ambient, const vec4& light_env_chara_specular, + const vec4& light_env_reflect_diffuse, const vec4& light_env_reflect_ambient, + const vec4& light_env_proj_diffuse, const vec4& light_env_proj_specular, + const vec4& light_env_proj_position, const vec4& light_stage_dir, const vec4& light_stage_diff, + const vec4& light_stage_spec, const vec4& light_chara_dir, const vec4& light_chara_spec, + const vec4& light_chara_luce, const vec4& light_chara_back, const vec4& light_face_diff, + const vec4& chara_color0, const vec4& chara_color1, const vec4& chara_f_dir, const vec4& chara_f_ambient, + const vec4& chara_f_diffuse, const vec4& chara_tc_param, const mat4& normal_tangent_transforms, + const vec4& light_reflect_dir, const vec4& clip_plane, const vec4& npr_cloth_spec_color); + void set_scene_light_projection(const mat4& light_projection); + void set_scene_projection_view(const mat4& view, const mat4& proj, const vec3& view_position); + void set_scene_shadow_params(const float_t esm_param, + const mat4 mats[2], const vec4& shadow_ambient, const vec4& shadow_ambient1); + void set_shader(uint32_t index); }; extern draw_state_struct& draw_state; diff --git a/src/DivaGL/render_manager.cpp b/src/DivaGL/render_manager.cpp index 80bf6d0..fbbe883 100644 --- a/src/DivaGL/render_manager.cpp +++ b/src/DivaGL/render_manager.cpp @@ -252,12 +252,8 @@ namespace rndr { gl_state_bind_framebuffer(0); glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - rctx->obj_scene.g_framebuffer_size = { - 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] - }; + rctx->set_scene_framebuffer_size(render->render_width[0], + render->render_height[0], render->render_width[0], render->render_height[0]); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_state_enable_depth_test(); @@ -358,8 +354,6 @@ namespace rndr { gl_state_begin_event("pass_shadow"); gl_state_begin_event("texproj"); if (draw_pass_shadow_litproj_set()) { - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); @@ -374,8 +368,6 @@ namespace rndr { for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) light_set_data[i].data_set((light_set_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); @@ -389,8 +381,6 @@ namespace rndr { } gl_state_end_event(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - bool v3 = false; int32_t v10[2]; for (int32_t i = 0; i < 2; i++) { @@ -471,8 +461,6 @@ namespace rndr { else draw_pass_3d_shadow_reset(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - draw_state.shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); @@ -489,8 +477,6 @@ namespace rndr { draw_pass_sss_contour(rend); } else if (npr) { - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rend->rend_texture[0].Bind(); rend->rend_texture[0].SetViewport(); glClearDLL(GL_DEPTH_BUFFER_BIT); @@ -557,8 +543,6 @@ namespace rndr { for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) fog_data[i].data_set((fog_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -627,8 +611,6 @@ namespace rndr { for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) fog_data[i].data_set((fog_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - vec4 clear_color; glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); @@ -760,8 +742,6 @@ namespace rndr { else draw_pass_3d_shadow_reset(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - if (effect_texture) gl_state_active_bind_texture_2d(14, effect_texture->glid); else @@ -893,8 +873,6 @@ namespace rndr { camera_data->fov = 32.2673416137695f; draw_pass_set_camera(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - disp_manager->draw(mdl::OBJ_TYPE_OPAQUE_LOCAL); disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT_LOCAL); gl_state_enable_blend(); @@ -1109,9 +1087,9 @@ void draw_pass_set_camera() { mat4_transpose(&camera_data->view, &rctx->view_mat); mat4_transpose(&camera_data->projection, &rctx->proj_mat); mat4_transpose(&camera_data->view_projection, &rctx->vp_mat); - rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat); - camera_data->get_view_point(rctx->obj_scene.g_view_position); - rctx->obj_scene.g_view_position.w = 0.0f; + vec3 view_point; + camera_data->get_view_point(view_point); + rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point); float_t max_distance = camera_data->max_distance; float_t min_distance = camera_data->min_distance; @@ -1278,6 +1256,8 @@ static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, i -shadow_range, shadow_range, shad->z_near, shad->z_far, &proj); mat4_mul(&proj, &temp, &rctx->proj_mat); mat4_look_at(view_point, interest, &rctx->view_mat); + mat4_mul(&rctx->view_mat, &rctx->proj_mat, &rctx->vp_mat); + rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, *view_point); draw_state.shader_index = SHADER_FT_SIL; uniform->arr[U_DEPTH] = 0; @@ -1528,14 +1508,14 @@ static bool draw_pass_shadow_litproj_set_mat(bool set_mat) { mat4 mat; mat4_mul(&view, &proj, &mat); - rctx->obj_scene.set_g_light_projection(mat); + rctx->set_scene_light_projection(mat); } else { mat4_persp(fov, 4.0f, 0.1f, 10.0f, &rctx->proj_mat); vec3 up = { 0.0f, 1.0f, 0.0f }; mat4_look_at(&position, &interest, &up, &rctx->view_mat); - rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat); + rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, position); } return true; } @@ -1655,7 +1635,7 @@ static void draw_pass_sss_filter(sss_data* sss) { float_t v34 = (float_t)(1.0 / clamp_def(v31 * v29, 0.25f, 100.0f)); if (v34 < 0.145f) v33 = max_def(v34 - 0.02f, 0.0f) * 8.0f * 0.6f; - rctx->obj_batch.g_sss_param = { v33, 0.0f, 0.0f, 0.0f }; + rctx->set_batch_sss_param({ v33, 0.0f, 0.0f, 0.0f }); gl_state_active_texture(0); if (sss->npr_contour) { @@ -1720,31 +1700,35 @@ static int32_t draw_pass_3d_get_translucent_count() { static void draw_pass_3d_shadow_reset() { gl_state_active_bind_texture_2d(6, 0); 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); draw_state.self_shadow = false; draw_state.shadow = false; } static void draw_pass_3d_shadow_set(Shadow* shad) { + float_t esm_param; if (shad->self_shadow && shad->num_shadow > 0) { gl_state_active_bind_texture_2d(19, shad->render_textures[3].GetColorTex()); gl_state_active_bind_texture_2d(20, shad->render_textures[5].GetColorTex()); 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 }; + esm_param = (shad->field_2D8 * shad->field_208 * 2.0f) * 1.442695f; draw_state.self_shadow = true; } else { gl_state_active_bind_texture_2d(19, rctx->empty_texture_2d->glid); gl_state_active_bind_texture_2d(20, rctx->empty_texture_2d->glid); gl_state_active_texture(0); + esm_param = 0.0f; draw_state.self_shadow = false; } gl_state_bind_sampler(19, rctx->render_samplers[0]); gl_state_bind_sampler(20, rctx->render_samplers[0]); + mat4 mats[2]; + mats[0] = mat4_identity; + mats[1] = mat4_identity; + vec4 shadow_ambient; + vec4 shadow_ambient1; if (shad->num_shadow > 0) { draw_state.shadow = true; uniform->arr[U_STAGE_SHADOW2] = shad->num_shadow > 1 ? 1 : 0; @@ -1778,8 +1762,7 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { mat4 view; mat4_look_at(view_point, interest, &view); - mat4_mul(&view, &proj, &view); - rctx->obj_scene.set_g_self_shadow_receivers(i, view); + mat4_mul(&view, &proj, &mats[i]); } int32_t j = 0; @@ -1803,8 +1786,8 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { else *(vec3*)&ambient.x = shad->shadow_ambient; - rctx->obj_scene.g_shadow_ambient = { ambient.x, ambient.y, ambient.z, 1.0f }; - rctx->obj_scene.g_shadow_ambient1 = { 1.0f - ambient.x, 1.0f - ambient.y, 1.0f - ambient.z, 0.0f }; + shadow_ambient = { ambient.x, ambient.y, ambient.z, 1.0f }; + shadow_ambient1 = { 1.0f - ambient.x, 1.0f - ambient.y, 1.0f - ambient.z, 0.0f }; } else { draw_state.shadow = false; @@ -1813,10 +1796,12 @@ static void draw_pass_3d_shadow_set(Shadow* shad) { gl_state_active_bind_texture_2d(6 + i, shad->curr_render_textures[1 + i]->GetColorTex()); gl_state_active_texture(0); - rctx->obj_scene.g_shadow_ambient = 1.0f; - rctx->obj_scene.g_shadow_ambient1 = 0.0f; + shadow_ambient = 1.0f; + shadow_ambient1 = 0.0f; } + rctx->set_scene_shadow_params(esm_param, mats, shadow_ambient, shadow_ambient1); + gl_state_bind_sampler(6, 0); gl_state_bind_sampler(7, 0); } @@ -1838,12 +1823,12 @@ static void draw_pass_3d_translucent(bool opaque_enable, int32_t alpha = alpha_array[i]; rend->transparency_copy(); if (opaque_enable && disp_manager->get_obj_count(opaque)) - disp_manager->draw_translucent(opaque, alpha); + disp_manager->draw(opaque, 0, true, alpha); if (transparent_enable && disp_manager->get_obj_count(transparent)) - disp_manager->draw_translucent(transparent, alpha); + disp_manager->draw(transparent, 0, true, alpha); if (translucent_enable && disp_manager->get_obj_count(translucent)) { gl_state_enable_blend(); - disp_manager->draw_translucent(translucent, alpha); + disp_manager->draw(translucent, 0, true, alpha); gl_state_disable_blend(); } rend->transparency_combine((float_t)alpha * (float_t)(1.0 / 255.0)); diff --git a/src/DivaGL/shader_ft.cpp b/src/DivaGL/shader_ft.cpp index 3d66d03..1210e70 100644 --- a/src/DivaGL/shader_ft.cpp +++ b/src/DivaGL/shader_ft.cpp @@ -1486,7 +1486,7 @@ static void shader_bind_hair(shader_set_data* set, shader* shad) { } static void shader_bind_glass_eye(shader_set_data* set, shader* shad) { - uniform->arr[U_EYEBALL] = 0; + uniform->arr[U_EYE_LENS] = 0; if (set->shaders[SHADER_FT_GLASEYE].bind(set, SHADER_FT_SUB_GLASS_EYE) >= 0) { glass_eye_calc(&glass_eye); glass_eye_set(&glass_eye); diff --git a/src/DivaGL/uniform.hpp b/src/DivaGL/uniform.hpp index 95cb425..c446360 100644 --- a/src/DivaGL/uniform.hpp +++ b/src/DivaGL/uniform.hpp @@ -32,7 +32,7 @@ enum uniform_name { U_FOG_CHARA = 0x15, U16 = 0x16, U_GAUSS = 0x17, - U_EYEBALL = 0x18, + U_EYE_LENS = 0x18, U_IMAGE_FILTER = 0x19, U_INSTANCE = 0x1A, U_TONE_CURVE = 0x1B,