diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index 69925e1b..76a03d97 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -1041,12 +1041,8 @@ namespace Glitter { break; } - rctx_ptr->obj_shader.set_shader_flags(uniform_value); - rctx_ptr->obj_shader_ubo.WriteMemory(rctx_ptr->obj_shader); - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx_ptr->obj_shader_ubo.Bind(0); - rctx_ptr->obj_scene_ubo.Bind(1); + rctx_ptr->set_glitter_render_data(); rctx_ptr->glitter_batch_ubo.Bind(3); switch (rend_group->type) { case PARTICLE_QUAD: @@ -2134,12 +2130,8 @@ namespace Glitter { else gl_state_disable_cull_face(); - rctx_ptr->obj_shader.set_shader_flags(uniform_value); - rctx_ptr->obj_shader_ubo.WriteMemory(rctx_ptr->obj_shader); - shaders_ft.set(SHADER_FT_GLITTER_PT); - rctx_ptr->obj_shader_ubo.Bind(0); - rctx_ptr->obj_scene_ubo.Bind(1); + rctx_ptr->set_glitter_render_data(); rctx_ptr->glitter_batch_ubo.Bind(3); switch (rend_group->type) { case PARTICLE_QUAD: diff --git a/src/CRE/effect.cpp b/src/CRE/effect.cpp index 53d6fff4..186c7ed7 100644 --- a/src/CRE/effect.cpp +++ b/src/CRE/effect.cpp @@ -1270,8 +1270,6 @@ void leaf_particle_draw() { if (!count) return; - const light_data& light_stage = rctx_ptr->light_set[LIGHT_SET_MAIN].lights[LIGHT_STAGE]; - leaf_particle_scene_shader_data shader_data = {}; mat4 temp; mat4_transpose(&rctx_ptr->vp_mat, &temp); @@ -1281,10 +1279,9 @@ void leaf_particle_draw() { shader_data.g_transform[3] = temp.row3; rctx_ptr->camera->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_ptr->obj_scene.g_light_chara_dir; - shader_data.g_lit_luce = rctx_ptr->obj_scene.g_light_chara_luce; + rctx_ptr->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/CRE/light_param/fog.cpp b/src/CRE/light_param/fog.cpp index 8b7d142c..92a885bb 100644 --- a/src/CRE/light_param/fog.cpp +++ b/src/CRE/light_param/fog.cpp @@ -73,31 +73,58 @@ void fog::data_set(fog_id id) { if (type == FOG_NONE) return; - float_t density = get_density(); - float_t start = get_start(); - float_t end = get_end(); - if (start >= end) - start = end - 0.01f; - - vec4 params; - params.x = density; - params.y = start; - params.z = end; - params.w = 1.0f / (end - start); - extern render_context* rctx_ptr; switch (id) { - case FOG_DEPTH: - get_color(rctx_ptr->obj_scene.g_fog_depth_color); - rctx_ptr->obj_scene.g_fog_state_params = params; - break; - case FOG_HEIGHT: - get_color(rctx_ptr->obj_scene.g_fog_height_color); - rctx_ptr->obj_scene.g_fog_height_params = params; - break; - case FOG_BUMP: - rctx_ptr->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_ptr->get_scene_fog_params(params); + params.density = density; + params.start = start; + params.end = end; + params.depth_color = color; + rctx_ptr->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_ptr->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_ptr->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_ptr->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_ptr->set_scene_fog_params(params); + } break; } } diff --git a/src/CRE/light_param/light.cpp b/src/CRE/light_param/light.cpp index a90cd271..2c93e4b6 100644 --- a/src/CRE/light_param/light.cpp +++ b/src/CRE/light_param/light.cpp @@ -344,28 +344,30 @@ void light_set::data_set(face& face, 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_ptr; - obj_scene_shader_data& obj_scene = rctx_ptr->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; @@ -377,10 +379,9 @@ void light_set::data_set(face& face, 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; @@ -392,42 +393,41 @@ void light_set::data_set(face& face, 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 v27 = face.get_offset(); float_t v28 = 1.0f - expf(v27 * -0.45f) * 2.0f; v27 = max_def(v27, 0.0f); - obj_scene.g_light_face_diff = { v28 * 0.1f, v27 * 0.06f, 1.0f, 1.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_value[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); @@ -443,18 +443,13 @@ void light_set::data_set(face& face, 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_value[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; @@ -469,24 +464,20 @@ void light_set::data_set(face& face, 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 }; + vec4 clip_plane = { 0.0f, -1.0f, 0.0f, 9999.0f }; else - obj_scene.g_clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; + vec4 clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; vec4 light_chara_ibl_direction; vec4 light_chara_position; @@ -517,8 +508,18 @@ void light_set::data_set(face& face, 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_ptr; + rctx_ptr->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/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp index 6580af8a..8590fc1f 100644 --- a/src/CRE/mdl/disp_manager.cpp +++ b/src/CRE/mdl/disp_manager.cpp @@ -1996,7 +1996,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_MAX || get_obj_count(type) < 1) return; @@ -2098,32 +2098,71 @@ namespace mdl { case OBJ_TYPE_SSS: func = draw_sub_mesh_sss; 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; case OBJ_TYPE_USER: func = draw_sub_mesh_translucent; break; default: break; } - rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + rctx->set_batch_alpha_threshold(alpha_threshold); + rctx->set_batch_min_alpha(min_alpha); uniform_value[U_ALPHA_TEST] = alpha_test; - for (ObjData*& i : obj[type]) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - draw_sub_mesh(rctx, &i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_ETC: { - draw_etc_obj(rctx, &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(rctx, i->args.translucent.sub_mesh[j], &i->mat, func); - } break; + if (alpha < 0) + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh(rctx, &i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_ETC: { + draw_etc_obj(rctx, &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(rctx, i->args.translucent.sub_mesh[j], &i->mat, func); + } break; + } + } + else + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + int32_t a = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(rctx, &i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (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(rctx, args, &i->mat, func); + } + } break; + } } - } switch (type) { case OBJ_TYPE_TRANSLUCENT: @@ -2143,6 +2182,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(); @@ -2153,86 +2202,6 @@ namespace mdl { gl_state_bind_sampler(i, 0); } - void DispManager::draw_translucent(ObjType type, int32_t alpha) { - if (get_obj_count(type) < 1) - return; - - render_context* rctx = rctx_ptr; - - int32_t alpha_test = 0; - float_t min_alpha = 1.0f; - float_t alpha_threshold = 0.0f; - bool reflect = uniform_value[U_REFLECT] == 1; - void(*func)(render_context * rctx, const ObjSubMeshArgs * args) = draw_sub_mesh_default; - - for (int32_t i = 0; i < 5; i++) - gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d->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_value[U_ALPHA_TEST] = alpha_test; - - for (ObjData*& i : obj[type]) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - int32_t a = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); - a = clamp_def(a, 0, 255); - if (a == alpha) - draw_sub_mesh(rctx, &i->args.sub_mesh, &i->mat, func); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (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(rctx, args, &i->mat, func); - } - } break; - } - } - - switch (type) { - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: - gl_state_set_depth_mask(GL_TRUE); - break; - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: - gl_state_set_cull_face_mode(GL_BACK); - break; - } - - uniform_value_reset(); - shader::unbind(); - gl_state_set_blend_func(GL_ONE, GL_ZERO); - } - /*void DispManager::draw_show_vector(ObjType type, int32_t show_vector) { if (get_obj_count(type) < 1) return; diff --git a/src/CRE/mdl/disp_manager.hpp b/src/CRE/mdl/disp_manager.hpp index c68fac30..6d595184 100644 --- a/src/CRE/mdl/disp_manager.hpp +++ b/src/CRE/mdl/disp_manager.hpp @@ -450,8 +450,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(const ::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, diff --git a/src/CRE/mdl/draw_object.cpp b/src/CRE/mdl/draw_object.cpp index 5d09b158..b9995dfd 100644 --- a/src/CRE/mdl/draw_object.cpp +++ b/src/CRE/mdl/draw_object.cpp @@ -50,13 +50,7 @@ namespace mdl { GL_UNSIGNED_INT, }; - rctx->obj_shader.set_shader_flags(uniform_value); - 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, @@ -98,33 +92,26 @@ namespace mdl { draw_object_model_mat_load(rctx, *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_value); - 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); @@ -179,13 +166,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(render_context* rctx, const ObjSubMeshArgs* args, const mat4* mat, @@ -196,9 +177,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) { @@ -208,11 +191,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_value[U_SKINNING] = 1; gl_state_bind_vertex_array(vao); @@ -246,10 +227,8 @@ namespace mdl { }*/ void draw_sub_mesh_default(render_context* rctx, 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(rctx, args); @@ -269,20 +248,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); rctx->draw_state->stats.object_draw_count++; } void draw_sub_mesh_default_instanced(render_context* rctx, 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(rctx, args); @@ -308,10 +283,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); rctx->draw_state->stats.object_draw_count++; } @@ -346,12 +319,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_value[U_SSS_CHARA] = 1; } else { const vec4& sss_param = rctx->sss_data->param; - rctx->obj_batch.g_sss_param = { sss_param.x, sss_param.y, sss_param.z, 0.5f }; + rctx->set_batch_sss_param({ sss_param.x, sss_param.y, sss_param.z, 0.5f }); uniform_value[U_SSS_CHARA] = 0; } draw_sub_mesh_default(rctx, args); @@ -410,24 +383,24 @@ namespace mdl { || args->sub_mesh->attrib.m.transparent) || attrib.punch_through) { uniform_value[U_ALPHA_TEST] = 1; - rctx->obj_batch.g_max_alpha.z = 0.5f; + rctx->set_batch_alpha_threshold(0.5f); draw_sub_mesh_translucent(rctx, args); - } - else { uniform_value[U_ALPHA_TEST] = 0; - draw_sub_mesh_translucent(rctx, args); + rctx->set_batch_alpha_threshold(0.0f); } + else + draw_sub_mesh_translucent(rctx, args); } void draw_sub_mesh_translucent(render_context* rctx, const ObjSubMeshArgs* args) { const obj_material_data* material = args->material; const std::vector* textures = args->textures; if (rctx->draw_state->shader_index != -1) { - rctx->obj_batch.g_material_state_emission = args->emission; + rctx->set_batch_material_color_specular(args->emission); draw_object_material_set_uniform(material, false); if (material->material.attrib.m.alpha_texture) uniform_value[U_TEXTURE_COUNT] = 0; - shaders_ft.set(rctx->draw_state->shader_index); + rctx->set_shader(rctx->draw_state->shader_index); } draw_object_vertex_attrib_set_default(rctx, args); @@ -775,16 +748,16 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob draw_object_chara_color_fog_set(rctx, args, disable_fog); - rctx->obj_batch.g_material_state_ambient = material->material.color.ambient; + vec4 ambient = material->material.color.ambient; if (!rctx->sss_data->enable) - rctx->obj_batch.g_material_state_ambient.w = 1.0f; - rctx->obj_batch.g_material_state_diffuse = material->material.color.diffuse; - rctx->obj_batch.g_material_state_emission = args->emission; + 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) @@ -798,34 +771,22 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob line_light = (float_t)material->material.shader_info.m.line_light * (float_t)(1.0 / 9.0); } else - line_light = 0.0; - - if (!use_shader) - shaders_ft.set(SHADER_FT_SIMPLE); - else if (rctx->draw_state->shader_index != -1) - shaders_ft.set(rctx->draw_state->shader_index); - else if (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); + line_light = 0.0f; + 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) @@ -834,45 +795,62 @@ static void draw_object_material_set_default(render_context* rctx, const mdl::Ob fresnel = rctx->draw_state->fresnel; fresnel = (fresnel - 1.0f) * 0.12f * 0.82f; - rctx->obj_batch.g_fresnel_coefficients = { fresnel, 0.18f, line_light, 0.0f }; + 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 (rctx->draw_state->shader_index != -1) + rctx->set_shader(rctx->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(rctx, material); } static void draw_object_material_set_parameter(render_context* rctx, 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 (rctx->draw_state->use_global_material) { bump_depth = rctx->draw_state->bump_depth; intensity = rctx->draw_state->intensity; @@ -880,9 +858,9 @@ static void draw_object_material_set_parameter(render_context* rctx, const obj_m refract_uv_scale = rctx->draw_state->refract_uv_scale; inv_bump_depth = (1.0f - rctx->draw_state->bump_depth) * 64.0f + 1.0f; - vec4 specular = mat_data->material.color.specular; + specular = mat_data->material.color.specular; specular.w = rctx->draw_state->reflectivity; - rctx->obj_batch.g_material_state_specular = specular; + has_specular = true; } else { bump_depth = mat_data->material.bump_depth; @@ -890,12 +868,13 @@ static void draw_object_material_set_parameter(render_context* rctx, const obj_m 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(render_context* rctx, const mdl::ObjSubMeshArgs* args) { @@ -966,11 +945,9 @@ static void draw_object_material_set_reflect(render_context* rctx, const mdl::Ob } draw_object_material_set_uniform(material, true); - shaders_ft.set(rctx->draw_state->shader_index); - rctx->obj_batch.g_material_state_ambient = ambient; - rctx->obj_batch.g_material_state_diffuse = diffuse; - rctx->obj_batch.g_material_state_emission = emission; - rctx->obj_batch.g_material_state_specular = specular; + rctx->set_shader(rctx->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(rctx, args->material); } @@ -1028,8 +1005,7 @@ static void draw_object_material_set_uniform(const obj_material_data* mat_data, } static void draw_object_model_mat_load(render_context* rctx, 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) { @@ -1069,6 +1045,9 @@ static void draw_object_vertex_attrib_set_default(render_context* rctx, const md 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; @@ -1091,18 +1070,18 @@ static void draw_object_vertex_attrib_set_default(render_context* rctx, const md uint32_t texture_id = texdata->tex_index; - 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_value[U_SKINNING] = 1; else @@ -1116,7 +1095,7 @@ static void draw_object_vertex_attrib_set_default(render_context* rctx, const md else uniform_value[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_value[U_MORPH] = 0; @@ -1133,21 +1112,24 @@ static void draw_object_vertex_attrib_set_reflect(render_context* rctx, const md 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 tex_index = material->material.texdata[0].tex_index; - 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 == tex_index) { - 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_value[U_SKINNING] = 1; else @@ -1161,7 +1143,7 @@ static void draw_object_vertex_attrib_set_reflect(render_context* rctx, const md else uniform_value[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_value[U_MORPH] = 0; diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index dc17cc91..8b6be1df 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -181,19 +181,23 @@ bool light_proj::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; } -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]; @@ -266,136 +270,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_value[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_value); + enum_or(flags, RENDER_DATA_SHADER_UPDATE); } render_context::render_context() : litproj(), chara_reflect(), chara_refract(), box_vao(), lens_ghost_vao(), @@ -489,14 +581,7 @@ sprite_width(), sprite_height(), screen_x_offset(), screen_y_offset(), screen_wi 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.init(); static const vec4 border_color = 0.0f; @@ -596,10 +681,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(); @@ -786,3 +868,312 @@ void render_context::resize(int32_t render_width, int32_t render_height, init(); } } + +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_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_specular(const vec4& specular) { + render_data* data = &this->data; + data->buffer_batch_data.g_material_state_specular = specular; + 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_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_value); + 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); +} diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 50e7ce4a..775ef08d 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -23,6 +23,12 @@ #define MATRIX_BUFFER_COUNT 320 +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; @@ -156,201 +162,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 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 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; @@ -386,7 +197,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; + }; + ::camera* camera; draw_state* draw_state; mdl::DispManager* disp_manager; @@ -439,14 +466,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; @@ -472,4 +492,47 @@ struct render_context { void resize(int32_t render_width, int32_t render_height, int32_t sprite_width, int32_t sprite_height, int32_t screen_width, int32_t screen_height); + + 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_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_specular(const vec4& specular); + 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_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); }; diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index b9eb51b0..2c45df69 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -274,12 +274,8 @@ namespace rndr { gl_state_bind_framebuffer(0); glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); - rctx_ptr->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_ptr->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(); @@ -381,8 +377,6 @@ namespace rndr { gl_state_begin_event("pass_shadow"); gl_state_begin_event("texproj"); if (rctx->litproj->set()) { - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); @@ -398,8 +392,6 @@ namespace rndr { for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) rctx->light_set[i].data_set(rctx->face, (light_set_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); @@ -413,8 +405,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++) { @@ -496,8 +486,6 @@ namespace rndr { else draw_pass_3d_shadow_reset(rctx); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->draw_state->shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); @@ -514,8 +502,6 @@ namespace rndr { draw_pass_sss_contour(rctx, rend); } else if (npr) { - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rend->rend_texture[0].Bind(); rend->rend_texture[0].SetViewport(); glClear(GL_DEPTH_BUFFER_BIT); @@ -582,8 +568,6 @@ namespace rndr { for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) rctx->fog[i].data_set((fog_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -653,8 +637,6 @@ namespace rndr { for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) rctx->fog[i].data_set((fog_id)i); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - vec4 clear_color; glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -790,8 +772,6 @@ namespace rndr { else draw_pass_3d_shadow_reset(rctx); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - if (effect_texture) gl_state_active_bind_texture_2d(14, effect_texture->glid); else @@ -927,8 +907,6 @@ namespace rndr { cam->set_fov(32.2673416137695f); draw_pass_set_camera(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - rctx->disp_manager->draw(mdl::OBJ_TYPE_OPAQUE_LOCAL); rctx->disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT_LOCAL); gl_state_enable_blend(); @@ -975,8 +953,6 @@ namespace rndr { render->bind_render_texture(); draw_pass_set_camera(); - rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); - //shaders_ft.env_vert_set(20, show_vector_length, show_vector_z_offset, 0.0f, 0.0f); for (int32_t i = 1; i < 4; i++) { if (!(show_vector_flags & (1 << (i - 1)))) @@ -1158,9 +1134,9 @@ void draw_pass_set_camera() { rctx->view_mat = cam->view; rctx->proj_mat = cam->projection; rctx->vp_mat = cam->view_projection; - rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat); - cam->get_view_point(rctx->obj_scene.g_view_position); - rctx->obj_scene.g_view_position.w = 0.0f; + vec3 view_point; + cam->get_view_point(view_point); + rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point); float_t max_distance = cam->max_distance; float_t min_distance = cam->min_distance; @@ -1245,6 +1221,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); rctx->draw_state->shader_index = SHADER_FT_SIL; uniform_value[U_DEPTH] = 0; @@ -1551,7 +1529,7 @@ static void draw_pass_sss_filter(render_context* rctx, 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) { @@ -1616,31 +1594,37 @@ static int32_t draw_pass_3d_get_translucent_count(render_context* rctx) { static void draw_pass_3d_shadow_reset(render_context* rctx) { 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); + gl_state_active_bind_texture_2d(19, 0); + gl_state_active_bind_texture_2d(20, 0); rctx->draw_state->self_shadow = false; rctx->draw_state->shadow = false; } static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { + 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; rctx->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; rctx->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) { rctx->draw_state->shadow = true; uniform_value[U_STAGE_SHADOW2] = shad->num_shadow > 1 ? 1 : 0; @@ -1674,8 +1658,7 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { 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; @@ -1699,8 +1682,8 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { 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 { rctx->draw_state->shadow = false; @@ -1709,10 +1692,12 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { 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); } @@ -1734,12 +1719,12 @@ static void draw_pass_3d_translucent(render_context* rctx, bool opaque_enable, int32_t alpha = alpha_array[i]; rend->transparency_copy(); if (opaque_enable && rctx->disp_manager->get_obj_count(opaque)) - rctx->disp_manager->draw_translucent(opaque, alpha); + rctx->disp_manager->draw(opaque, 0, true, alpha); if (transparent_enable && rctx->disp_manager->get_obj_count(transparent)) - rctx->disp_manager->draw_translucent(transparent, alpha); + rctx->disp_manager->draw(transparent, 0, true, alpha); if (translucent_enable && rctx->disp_manager->get_obj_count(translucent)) { gl_state_enable_blend(); - rctx->disp_manager->draw_translucent(translucent, alpha); + rctx->disp_manager->draw(translucent, 0, true, alpha); gl_state_disable_blend(); } rend->transparency_combine((float_t)alpha * (float_t)(1.0 / 255.0)); diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index 4a8897d0..50c25e16 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -708,14 +708,14 @@ static const int32_t transparency_fpt_unival_max[] = { { SHADER_DESCRIPTION_SAMPLER, 14, 0, U_INVALID, } #define SHADER_DESCRIPTION_COMMON_SCENE \ - { SHADER_DESCRIPTION_UNIFORM, -1, sizeof(obj_shader_shader_data), U_INVALID, }, \ - { SHADER_DESCRIPTION_UNIFORM, 1, sizeof(obj_scene_shader_data), U_INVALID, }, \ - { SHADER_DESCRIPTION_UNIFORM, 2, sizeof(obj_batch_shader_data), U_INVALID, } + { SHADER_DESCRIPTION_UNIFORM, -1, sizeof(render_data::obj_shader_data), U_INVALID, }, \ + { SHADER_DESCRIPTION_UNIFORM, 1, sizeof(render_data::obj_scene_data), U_INVALID, }, \ + { SHADER_DESCRIPTION_UNIFORM, 2, sizeof(render_data::obj_batch_data), U_INVALID, } #define SHADER_DESCRIPTION_COMMON_SKINNING \ { SHADER_DESCRIPTION_VERTEX_INPUT, 1, 4, U_SKINNING, }, \ { SHADER_DESCRIPTION_VERTEX_INPUT, 15, 4, U_SKINNING, }, \ - { SHADER_DESCRIPTION_STORAGE, 0, sizeof(obj_skinning_shader_data), U_SKINNING, } + { SHADER_DESCRIPTION_STORAGE, 0, sizeof(render_data::obj_skinning_data), U_SKINNING, } #define SHADER_DESCRIPTION_COMMON_QUAD \ { SHADER_DESCRIPTION_UNIFORM, 0, sizeof(quad_shader_data), U_INVALID, } diff --git a/src/ReDIVA/app.cpp b/src/ReDIVA/app.cpp index 483ccfa1..8c11c8db 100644 --- a/src/ReDIVA/app.cpp +++ b/src/ReDIVA/app.cpp @@ -117,9 +117,9 @@ struct common_data_struct { vec3 view_pos; }; -struct render_data { - render_data(); - ~render_data(); +struct app_render_data { + app_render_data(); + ~app_render_data(); bool load(); void unload(); @@ -141,7 +141,7 @@ struct vulkan_swapchain_support_details { common_data_struct common_data; -render_data* render; +app_render_data* render; ImFont* imgui_font_arial; @@ -506,15 +506,15 @@ void app_swap_buffers() { float_t rob_frame = 0.0f; -render_data::render_data() { +app_render_data::app_render_data() { } -render_data::~render_data() { +app_render_data::~app_render_data() { } -bool render_data::load() { +bool app_render_data::load() { glfwMakeContextCurrent(window); if (Vulkan::use) @@ -605,7 +605,7 @@ bool render_data::load() { return true; } -void render_data::unload() { +void app_render_data::unload() { #if DISPLAY_IBL cubemap_display_ubo.Destroy(); @@ -690,7 +690,7 @@ static bool app_init(const app_init_struct& ais) { if (!window) return false; - render = new render_data; + render = new app_render_data; if (!render->load()) { glfwDestroyWindow(window); return false; @@ -1335,8 +1335,6 @@ static render_context* render_context_load() { clear_color = 0xFF000000; set_clear_color = true; - rctx->obj_batch.g_blend_color = 1.0f; - rctx->obj_batch.g_offset_color = 0.0f; classes_process_init(classes, classes_count, rctx); return rctx; }