mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-12 00:58:20 +03:00
Ripple
This commit is contained in:
@@ -1135,6 +1135,8 @@ namespace mdl {
|
||||
uniform_value_reset();
|
||||
shader::unbind();
|
||||
gl_state_set_blend_func(GL_ONE, GL_ZERO);
|
||||
for (int32_t i = 0; i < 5; i++)
|
||||
gl_state_bind_sampler(i, 0);
|
||||
}
|
||||
|
||||
void DispManager::draw_translucent(ObjType type, int32_t alpha) {
|
||||
@@ -2157,11 +2159,17 @@ namespace rndr {
|
||||
field_31C(), field_31D(), field_31E(), field_31F(), field_320(), npr(), samplers(), sprite_samplers() {
|
||||
for (bool& i : pass_sw)
|
||||
i = true;
|
||||
reflect = true;
|
||||
refract = true;
|
||||
|
||||
set_pass_sw(RND_PASSID_2, false);
|
||||
set_pass_sw(RND_PASSID_REFLECT, false);
|
||||
set_pass_sw(RND_PASSID_REFRACT, false);
|
||||
set_pass_sw(RND_PASSID_USER, false);
|
||||
set_pass_sw(RND_PASSID_SHOW_VECTOR, false);
|
||||
|
||||
shadow = true;
|
||||
opaque_z_sort = true;
|
||||
alpha_z_sort = true;
|
||||
|
||||
for (bool& i : draw_pass_3d)
|
||||
i = true;
|
||||
|
||||
@@ -2265,11 +2273,11 @@ namespace rndr {
|
||||
delete shadow_ptr;
|
||||
}
|
||||
|
||||
void RenderManager::add_user(int32_t type, void(*func)(void*), void* data) {
|
||||
void RenderManager::add_user_func(int32_t type, void(*func)(void*), void* data) {
|
||||
user.push_back({ type, func, data });
|
||||
}
|
||||
|
||||
void RenderManager::clear_user(int32_t type) {
|
||||
void RenderManager::clear_user_func(int32_t type) {
|
||||
for (std::list<draw_user>::iterator i = user.begin(); i != user.end(); i++)
|
||||
if (i->type == type) {
|
||||
user.erase(i);
|
||||
|
||||
@@ -614,8 +614,8 @@ namespace rndr {
|
||||
RenderManager();
|
||||
~RenderManager();
|
||||
|
||||
void add_user(int32_t type, void(*func)(void*), void* data);
|
||||
void clear_user(int32_t type);
|
||||
void add_user_func(int32_t type, void(*func)(void*), void* data);
|
||||
void clear_user_func(int32_t type);
|
||||
render_texture& get_render_texture(int32_t index);
|
||||
void resize(int32_t width, int32_t height);
|
||||
void set_effect_texture(texture* value);
|
||||
@@ -795,10 +795,6 @@ struct obj_skinning_shader_data {
|
||||
vec4 g_joint_transforms[768];
|
||||
};
|
||||
|
||||
struct transparency_batch_shader_data {
|
||||
vec4 g_opacity;
|
||||
};
|
||||
|
||||
struct quad_shader_data {
|
||||
vec4 g_texcoord_modifier;
|
||||
vec4 g_texel_size;
|
||||
@@ -816,6 +812,10 @@ struct sss_filter_gaussian_coef_shader_data {
|
||||
vec4 g_coef[64];
|
||||
};
|
||||
|
||||
struct transparency_batch_shader_data {
|
||||
vec4 g_opacity;
|
||||
};
|
||||
|
||||
struct render_context {
|
||||
::camera* camera;
|
||||
draw_state draw_state;
|
||||
@@ -848,6 +848,8 @@ struct render_context {
|
||||
GL::UniformBuffer imgfilter_batch_ubo;
|
||||
GL::UniformBuffer glass_eye_batch_ubo;
|
||||
GL::UniformBuffer quad_ubo;
|
||||
GL::UniformBuffer ripple_ubo;
|
||||
GL::UniformBuffer ripple_emit_ubo;
|
||||
GL::UniformBuffer sprite_scene_ubo;
|
||||
GL::UniformBuffer sss_filter_gaussian_coef_ubo;
|
||||
GL::UniformBuffer transparency_batch_ubo;
|
||||
|
||||
+30
-77
@@ -19,11 +19,6 @@
|
||||
#include "task_effect.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
struct texture_param {
|
||||
GLint width;
|
||||
GLint height;
|
||||
};
|
||||
|
||||
static void blur_filter_apply(render_context* rctx, GLuint tex_0, GLuint tex_1,
|
||||
blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset);
|
||||
static void draw_pass_shadow_begin_make_shadowmap(render_context* rctx,
|
||||
@@ -47,11 +42,6 @@ static int32_t draw_pass_3d_translucent_count_layers(render_context* rctx,
|
||||
int32_t* alpha_array, mdl::ObjType opaque,
|
||||
mdl::ObjType transparent, mdl::ObjType translucent);
|
||||
static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr, mdl::ObjType type);
|
||||
static void draw_pass_set_camera(render_context* rctx);
|
||||
static void texture_params_get(GLuint tex_0, texture_param* tex_0_param,
|
||||
GLuint tex_1, texture_param* tex_1_param, GLuint tex_2, texture_param* tex_2_param);
|
||||
static void texture_params_restore(texture_param* tex_0_param,
|
||||
texture_param* tex_1_param, texture_param* tex_2_param);
|
||||
|
||||
extern bool draw_grid_3d;
|
||||
extern void draw_pass_3d_grid(render_context* rctx);
|
||||
@@ -875,7 +865,7 @@ void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4
|
||||
return;
|
||||
|
||||
texture_param tex_params[2];
|
||||
texture_params_get(dst, &tex_params[0], src, &tex_params[1], 0, 0);
|
||||
texture_params_get(dst, &tex_params[0], src, &tex_params[1]);
|
||||
|
||||
filter_scene_shader_data filter_scene = {};
|
||||
filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
@@ -894,7 +884,24 @@ void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4
|
||||
rctx->imgfilter_batch_ubo.Bind(1);
|
||||
gl_state_active_bind_texture_2d(0, src);
|
||||
render_texture::draw_custom();
|
||||
texture_params_restore(&tex_params[0], &tex_params[1], 0);
|
||||
|
||||
texture_params_restore(&tex_params[0], &tex_params[1]);
|
||||
}
|
||||
|
||||
void draw_pass_set_camera(render_context* rctx) {
|
||||
camera* cam = rctx->camera;
|
||||
cam->update_data();
|
||||
rctx->view_mat = cam->view;
|
||||
rctx->proj_mat = cam->projection;
|
||||
rctx->vp_mat = cam->view_projection;
|
||||
rctx->obj_scene.set_projection_view(cam->view, cam->projection);
|
||||
cam->get_view_point(rctx->obj_scene.g_view_position);
|
||||
|
||||
rctx->g_near_far = {
|
||||
(float_t)(cam->max_distance / (cam->max_distance - cam->min_distance)),
|
||||
(float_t)(-(cam->max_distance * cam->min_distance) / (cam->max_distance - cam->min_distance)),
|
||||
0.0f, 0.0f
|
||||
};
|
||||
}
|
||||
|
||||
static void draw_pass_shadow_begin_make_shadowmap(render_context* rctx,
|
||||
@@ -1003,7 +1010,7 @@ static void draw_pass_shadow_filter(render_context* rctx, render_texture* a1, re
|
||||
return;
|
||||
|
||||
texture_param tex_params[2];
|
||||
texture_params_get(v7, &tex_params[0], v9, &tex_params[1], 0, 0);
|
||||
texture_params_get(v7, &tex_params[0], v9, &tex_params[1]);
|
||||
if (tex_params[0].width != tex_params[1].width
|
||||
|| tex_params[0].height != tex_params[1].height)
|
||||
return;
|
||||
@@ -1048,7 +1055,8 @@ static void draw_pass_shadow_filter(render_context* rctx, render_texture* a1, re
|
||||
gl_state_active_bind_texture_2d(0, v9);
|
||||
render_texture::draw_custom();
|
||||
shader::unbind();
|
||||
texture_params_restore(&tex_params[0], &tex_params[1], 0);
|
||||
|
||||
texture_params_restore(&tex_params[0], &tex_params[1]);
|
||||
}
|
||||
|
||||
static void draw_pass_shadow_esm_filter(render_context* rctx,
|
||||
@@ -1093,6 +1101,7 @@ static void draw_pass_shadow_esm_filter(render_context* rctx,
|
||||
shaders_ft.set(SHADER_FT_ESMFILT);
|
||||
gl_state_active_bind_texture_2d(0, buf_tex);
|
||||
render_texture::draw(&shaders_ft);
|
||||
|
||||
texture_params_restore(&tex_params[0], &tex_params[1], &tex_params[2]);
|
||||
}
|
||||
|
||||
@@ -1342,8 +1351,12 @@ static void draw_pass_3d_shadow_set(shadow* shad, render_context* rctx) {
|
||||
rctx->obj_scene.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f };
|
||||
rctx->draw_state.self_shadow = true;
|
||||
}
|
||||
else
|
||||
else {
|
||||
gl_state_active_bind_texture_2d(19, rctx->empty_texture_2d);
|
||||
gl_state_active_bind_texture_2d(20, rctx->empty_texture_2d);
|
||||
gl_state_active_texture(0);
|
||||
rctx->draw_state.self_shadow = false;
|
||||
}
|
||||
|
||||
if (shad->field_2EC > 0) {
|
||||
rctx->draw_state.light = true;
|
||||
@@ -1495,73 +1508,13 @@ static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_pass_set_camera(render_context* rctx) {
|
||||
camera* cam = rctx->camera;
|
||||
cam->update_data();
|
||||
rctx->view_mat = cam->view;
|
||||
rctx->proj_mat = cam->projection;
|
||||
rctx->vp_mat = cam->view_projection;
|
||||
rctx->obj_scene.set_projection_view(cam->view, cam->projection);
|
||||
cam->get_view_point(rctx->obj_scene.g_view_position);
|
||||
|
||||
rctx->g_near_far = {
|
||||
(float_t)(cam->max_distance / (cam->max_distance - cam->min_distance)),
|
||||
(float_t)(-(cam->max_distance * cam->min_distance) / (cam->max_distance - cam->min_distance)),
|
||||
0.0f, 0.0f
|
||||
};
|
||||
}
|
||||
|
||||
static void texture_params_get(GLuint tex_0, texture_param* tex_0_param,
|
||||
GLuint tex_1, texture_param* tex_1_param, GLuint tex_2, texture_param* tex_2_param) {
|
||||
gl_state_disable_depth_test();
|
||||
if (tex_0_param) {
|
||||
tex_0_param->width = 0;
|
||||
tex_0_param->height = 0;
|
||||
if (tex_0) {
|
||||
gl_state_bind_texture_2d(tex_0);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_0_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_0_param->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_1_param) {
|
||||
tex_1_param->width = 0;
|
||||
tex_1_param->height = 0;
|
||||
if (tex_1) {
|
||||
gl_state_bind_texture_2d(tex_1);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_1_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_1_param->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_2_param) {
|
||||
tex_2_param->width = 0;
|
||||
tex_2_param->height = 0;
|
||||
if (tex_2) {
|
||||
gl_state_bind_texture_2d(tex_2);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_2_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_2_param->height);
|
||||
}
|
||||
}
|
||||
gl_state_bind_texture_2d(0);
|
||||
|
||||
if (tex_0_param)
|
||||
glViewport(0, 0, tex_0_param->width, tex_0_param->height);
|
||||
}
|
||||
|
||||
static void texture_params_restore(texture_param* tex_0_param,
|
||||
texture_param* tex_1_param, texture_param* tex_2_param) {
|
||||
for (int32_t i = 0; i < 4; i++)
|
||||
gl_state_active_bind_texture_2d(i, 0);
|
||||
}
|
||||
|
||||
static void blur_filter_apply(render_context* rctx, GLuint dst, GLuint src,
|
||||
blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset) {
|
||||
if (!dst || !src)
|
||||
return;
|
||||
|
||||
texture_param tex_params[2];
|
||||
texture_params_get(dst, &tex_params[0], src, &tex_params[1], 0, 0);
|
||||
texture_params_get(dst, &tex_params[0], src, &tex_params[1]);
|
||||
|
||||
filter_scene_shader_data filter_scene = {};
|
||||
float_t w = res_scale.x / (float_t)tex_params[1].width;
|
||||
@@ -1587,5 +1540,5 @@ static void blur_filter_apply(render_context* rctx, GLuint dst, GLuint src,
|
||||
gl_state_active_bind_texture_2d(0, src);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4);
|
||||
|
||||
texture_params_restore(&tex_params[0], &tex_params[1], 0);
|
||||
texture_params_restore(&tex_params[0], &tex_params[1]);
|
||||
}
|
||||
|
||||
@@ -11,3 +11,5 @@
|
||||
#include "render_context.hpp"
|
||||
|
||||
extern void image_filter_scale(render_context* rctx, GLuint dst, GLuint src, const vec4 scale);
|
||||
|
||||
extern void draw_pass_set_camera(render_context* rctx);
|
||||
|
||||
+8
-8
@@ -2407,13 +2407,6 @@ static void rob_chara_item_equip_ctrl(rob_chara_item_equip* rob_itm_equip) {
|
||||
rob_chara_item_equip_object_ctrl(&rob_itm_equip->item_equip_object[i]);
|
||||
}
|
||||
|
||||
static float_t rob_chara_get_trans_scale(rob_chara* rob_chr, int32_t bone, vec3* trans) {
|
||||
if (bone > 26)
|
||||
return 0.0f;
|
||||
*trans = rob_chr->data.field_1E68.field_DF8[bone].trans;
|
||||
return rob_chr->data.field_1E68.field_DF8[bone].scale;
|
||||
}
|
||||
|
||||
mat4* rob_chara_bone_data_get_mats_mat(rob_chara_bone_data* rob_bone_data, size_t index) {
|
||||
if (index < rob_bone_data->mats.size())
|
||||
return &rob_bone_data->mats[index];
|
||||
@@ -2522,6 +2515,13 @@ int32_t rob_chara::get_rob_cmn_mottbl_motion_id(int32_t id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float_t rob_chara::get_trans_scale(int32_t bone, vec3& trans) {
|
||||
if (bone < 0 || bone > 26)
|
||||
return 0.0f;
|
||||
trans = data.field_1E68.field_DF8[bone].trans;
|
||||
return data.field_1E68.field_DF8[bone].scale;
|
||||
}
|
||||
|
||||
bool rob_chara::is_visible() {
|
||||
return !!(data.field_0 & 0x01);
|
||||
}
|
||||
@@ -7947,7 +7947,7 @@ static void rob_disp_rob_chara_ctrl_thread_main(rob_chara* rob_chr) {
|
||||
rob_chr->item_equip->set_opd_blend_data(&rob_chr->bone_data->motion_loaded);
|
||||
|
||||
vec3 trans = 0.0f;
|
||||
rob_chara_get_trans_scale(rob_chr, 0, &trans);
|
||||
rob_chr->get_trans_scale(0, trans);
|
||||
rob_chr->item_equip->position = trans;
|
||||
rob_chara_item_equip_ctrl(rob_chr->item_equip);
|
||||
if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) {
|
||||
|
||||
@@ -3415,6 +3415,7 @@ struct rob_chara {
|
||||
float_t get_frame_count();
|
||||
float_t get_max_face_depth();
|
||||
int32_t get_rob_cmn_mottbl_motion_id(int32_t id);
|
||||
float_t get_trans_scale(int32_t bone, vec3& trans);
|
||||
bool is_visible();
|
||||
void load_motion(int32_t motion_id, bool a3, float_t frame,
|
||||
MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db);
|
||||
|
||||
@@ -2764,9 +2764,9 @@ static const bool LAMBERT_permut[] = {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false, // 8th added
|
||||
};
|
||||
|
||||
|
||||
+704
-15
@@ -9,10 +9,11 @@
|
||||
#include "GL/uniform_buffer.hpp"
|
||||
#include "auth_3d.hpp"
|
||||
#include "data.hpp"
|
||||
#include "gl_state.hpp"
|
||||
#include "random.hpp"
|
||||
#include "render_context.hpp"
|
||||
#include "render_manager.hpp"
|
||||
#include "shader_ft.hpp"
|
||||
#include "stage_param.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
struct for_ring_vertex_data {
|
||||
@@ -97,6 +98,21 @@ struct rain_particle_batch_shader_data {
|
||||
vec4 g_color;
|
||||
};
|
||||
|
||||
struct ripple_batch_shader_data {
|
||||
vec4 g_params;
|
||||
};
|
||||
|
||||
struct ripple_scene_shader_data {
|
||||
vec4 g_transform;
|
||||
vec4 g_texcoord;
|
||||
};
|
||||
|
||||
struct ripple_emit_scene_shader_data {
|
||||
vec4 g_size_in_projection;
|
||||
vec4 g_transform;
|
||||
vec4 g_framebuffer_size;
|
||||
};
|
||||
|
||||
struct struc_608 {
|
||||
const stage_effects* stage_effects;
|
||||
const stage_effects_modern* stage_effects_modern;
|
||||
@@ -160,6 +176,8 @@ static bool task_effect_array_parse_stage_param_data_star(stage_param_star* star
|
||||
|
||||
static void draw_fog_particle(render_context* rctx, TaskEffectFogRing::Data* data);
|
||||
|
||||
static void draw_ripple_emit(render_context* rctx, struc_101* data);
|
||||
|
||||
static void leaf_particle_init(bool change_stage = false);
|
||||
static void leaf_particle_ctrl();
|
||||
static int32_t leaf_particle_disp();
|
||||
@@ -177,6 +195,12 @@ static void rain_particle_init(bool change_stage);
|
||||
static void rain_particle_ctrl();
|
||||
static void rain_particle_free();
|
||||
|
||||
static void ripple_emit_init();
|
||||
static void ripple_emit_free();
|
||||
|
||||
static void sub_1403B6ED0(render_texture* a1, render_texture* a2, render_texture* a3, ripple_emit_params& params);
|
||||
static void sub_1403B6F60(GLuint a1, GLuint a2, GLuint a3, ripple_emit_params& params);
|
||||
|
||||
static TaskEffectAuth3D* task_effect_auth_3d;
|
||||
static TaskEffectLeaf* task_effect_leaf;
|
||||
static TaskEffectSnow* task_effect_snow;
|
||||
@@ -191,6 +215,8 @@ static TaskEffectStar* task_effect_star;
|
||||
|
||||
static TaskEffectParent* task_effect_parent;
|
||||
|
||||
static ripple_emit* ripple_emit_data;
|
||||
|
||||
static TaskEffectFogAnim::Data* task_effect_fog_anim_data;
|
||||
static TaskEffectFogRing::Data* task_effect_fog_ring_data;
|
||||
static TaskEffectSplash::Data* task_effect_splash_data;
|
||||
@@ -242,6 +268,14 @@ static GL::UniformBuffer rain_particle_scene_ubo;
|
||||
static GL::UniformBuffer rain_particle_batch_ubo;
|
||||
static const size_t rain_ptcl_count = 0x8000;
|
||||
|
||||
static GLuint ripple_vao;
|
||||
static GL::UniformBuffer ripple_batch_ubo;
|
||||
static GL::UniformBuffer ripple_scene_ubo;
|
||||
|
||||
static GLuint ripple_emit_vao;
|
||||
static GLuint ripple_emit_vbo;
|
||||
static GL::UniformBuffer ripple_emit_scene_ubo;
|
||||
|
||||
static TaskEffect** task_effect_data_array[] = {
|
||||
(TaskEffect**)&task_effect_auth_3d,
|
||||
0,
|
||||
@@ -249,7 +283,7 @@ static TaskEffect** task_effect_data_array[] = {
|
||||
0,
|
||||
0/*(TaskEffect**)&task_effect_snow*/,
|
||||
0,
|
||||
0/*(TaskEffect**)&task_effect_ripple*/,
|
||||
(TaskEffect**)&task_effect_ripple,
|
||||
(TaskEffect**)&task_effect_rain,
|
||||
0,
|
||||
0,
|
||||
@@ -911,7 +945,7 @@ void TaskEffectFogRing::Data::Dest() {
|
||||
}
|
||||
|
||||
rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_USER, false);
|
||||
rctx_ptr->render_manager.clear_user(0);
|
||||
rctx_ptr->render_manager.clear_user_func(0);
|
||||
rctx_ptr->draw_state.set_fog_height(false);
|
||||
}
|
||||
|
||||
@@ -985,7 +1019,7 @@ void TaskEffectFogRing::Data::Reset() {
|
||||
}
|
||||
|
||||
void TaskEffectFogRing::Data::SetStageIndices(std::vector<int32_t>& stage_indices) {
|
||||
rctx_ptr->render_manager.clear_user(0);
|
||||
rctx_ptr->render_manager.clear_user_func(0);
|
||||
rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_USER, false);
|
||||
disp = false;
|
||||
current_stage_index = -1;
|
||||
@@ -1091,7 +1125,7 @@ void TaskEffectFogRing::Data::SetStageIndices(std::vector<int32_t>& stage_indice
|
||||
InitParticleData();
|
||||
|
||||
rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_USER, true);
|
||||
rctx_ptr->render_manager.add_user(0, TaskEffectFogRing::Data::DrawStatic, this);
|
||||
rctx_ptr->render_manager.add_user_func(0, TaskEffectFogRing::Data::DrawStatic, this);
|
||||
}
|
||||
|
||||
void TaskEffectFogRing::Data::DrawStatic(void* data) {
|
||||
@@ -1596,7 +1630,6 @@ bool TaskEffectRain::Ctrl() {
|
||||
bool TaskEffectRain::Dest() {
|
||||
if (stage_param_data_rain_current) {
|
||||
rain_particle_free();
|
||||
rain_ptcl_vbo = 0;
|
||||
stage_param_data_rain_current = 0;
|
||||
stage_param_data_rain_storage_clear();
|
||||
stage_param_data_rain_set = false;
|
||||
@@ -1689,6 +1722,473 @@ void TaskEffectRain::Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
ripple_emit_draw_data::ripple_emit_draw_data() : data() {
|
||||
|
||||
}
|
||||
|
||||
struc_192::struc_192() {
|
||||
index = -1;
|
||||
}
|
||||
|
||||
struc_207::struc_207() {
|
||||
|
||||
}
|
||||
|
||||
ripple_emit_params::ripple_emit_params() {
|
||||
wake_attn = 0.56f;
|
||||
speed = 1.0f;
|
||||
field_8 = 0.0005f;
|
||||
field_C = 0.9f;
|
||||
}
|
||||
|
||||
ripple_emit::ripple_emit() : delta_frame(), update(), rain_ripple_num(),
|
||||
rain_ripple_min_value(), rain_ripple_max_value(), field_14(), emit_pos_scale(), emit_pos_ofs_x(),
|
||||
emit_pos_ofs_z(), ripple_tex_id(), use_float_ripplemap(), field_30(), rob_emitter_size(),
|
||||
emitter_num(), emitter_size(), field_4C(), field_50(), field_178(), field_2A0(), field_3C8(),
|
||||
field_4F0(), field_BB4(), counter(), field_BEC(), stage_set(), current_stage_index() {
|
||||
ground_y = -1001.0f;
|
||||
emitter_list = 0;
|
||||
}
|
||||
|
||||
ripple_emit::~ripple_emit() {
|
||||
ground_y = -1001.0f;
|
||||
}
|
||||
|
||||
void ripple_emit::add_draw_ripple_emit(struc_101* data) {
|
||||
if (data->count > 0)
|
||||
rctx_ptr->disp_manager.entry_obj_user(&mat4_identity,
|
||||
(mdl::UserArgsFunc)draw_ripple_emit, data, mdl::OBJ_TYPE_USER);
|
||||
}
|
||||
|
||||
void ripple_emit::clear_tex() {
|
||||
vec4 clear_color;
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color);
|
||||
|
||||
for (int32_t i = 0, j = 5; i < 3; i++, j++) {
|
||||
render_texture* rt;
|
||||
float_t v5;
|
||||
if (use_float_ripplemap) {
|
||||
rt = &rctx_ptr->render_manager.get_render_texture(j - 3);
|
||||
v5 = -0.3f;
|
||||
}
|
||||
else {
|
||||
rt = &rctx_ptr->render_manager.get_render_texture(j);
|
||||
v5 = 0.5f;
|
||||
}
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, v5);
|
||||
rt->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
gl_state_bind_framebuffer(0);
|
||||
}
|
||||
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
}
|
||||
|
||||
void ripple_emit::ctrl() {
|
||||
if (delta_frame > 0.0f)
|
||||
update = true;
|
||||
}
|
||||
|
||||
void ripple_emit::dest() {
|
||||
stage_param_data_ripple_storage_clear();
|
||||
rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_USER, false);
|
||||
rctx_ptr->render_manager.clear_user_func(0);
|
||||
this->ground_y = -1001.0;
|
||||
}
|
||||
|
||||
void ripple_emit::disp() {
|
||||
if (!stage_set)
|
||||
return;
|
||||
|
||||
if (use_float_ripplemap) {
|
||||
if (field_30 == 60)
|
||||
sub_140358690();
|
||||
else
|
||||
sub_14035AED0();
|
||||
if (field_30 > 0)
|
||||
field_30--;
|
||||
}
|
||||
else {
|
||||
sub_14035AED0();
|
||||
sub_14035AAE0();
|
||||
}
|
||||
}
|
||||
|
||||
void ripple_emit::draw() {
|
||||
if (!stage_set)
|
||||
return;
|
||||
|
||||
gl_state_disable_cull_face();
|
||||
|
||||
render_context* rctx = rctx_ptr;
|
||||
|
||||
render_texture* rt[3];
|
||||
for (int32_t i = 0, j = 2; i < 3; i++, j++)
|
||||
rt[i] = &rctx->render_manager.get_render_texture(
|
||||
use_float_ripplemap ? j : (j + 3));
|
||||
|
||||
if (update) {
|
||||
int32_t counter = this->counter + 1;
|
||||
if (counter >= 3)
|
||||
counter = 0;
|
||||
|
||||
rt[(counter + 1) % 3]->bind();
|
||||
|
||||
GLint v43[4];
|
||||
glGetIntegerv(GL_VIEWPORT, v43);
|
||||
|
||||
int32_t width = rt[0]->color_texture->width;
|
||||
int32_t height = rt[0]->color_texture->height;
|
||||
|
||||
glViewport(1, 1, width - 2, height - 2);
|
||||
|
||||
draw_pass_set_camera(rctx_ptr);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
if (rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_USER)) {
|
||||
gl_state_active_bind_texture_2d(7, rt[counter % 3]->color_texture->tex);
|
||||
rctx->disp_manager.draw(mdl::OBJ_TYPE_USER, 0, true);
|
||||
gl_state_active_bind_texture_2d(7, 0);
|
||||
}
|
||||
|
||||
gl_state_bind_framebuffer(0);
|
||||
|
||||
params.field_8 = 0.0005f;
|
||||
params.field_C = 0.97f;
|
||||
if (field_30 > 0) {
|
||||
params.field_8 = 0.00005f;
|
||||
params.field_C = 0.999f;
|
||||
}
|
||||
|
||||
sub_1403B6ED0(rt[(counter + 2) % 3], rt[(counter + 1) % 3], rt[counter % 3], params);
|
||||
|
||||
glViewport(v43[0], v43[1], v43[2], v43[3]);
|
||||
|
||||
sub_1403584A0(rt[(counter + 2) % 3]);
|
||||
|
||||
this->counter = counter;
|
||||
}
|
||||
|
||||
int32_t v11 = (counter + 2) % 3 + 2;
|
||||
if (!use_float_ripplemap)
|
||||
v11 += 3;
|
||||
|
||||
rctx->render_manager.set_effect_texture(
|
||||
rctx->render_manager.get_render_texture(v11).color_texture);
|
||||
|
||||
update = false;
|
||||
|
||||
gl_state_enable_cull_face();
|
||||
}
|
||||
|
||||
void ripple_emit::reset() {
|
||||
field_4F0 = 18;
|
||||
for (struc_207& i : field_4F4)
|
||||
for (int32_t j = 0; j < field_4F0; j++)
|
||||
i.field_0[j].trans = 0.0f;
|
||||
|
||||
field_30 = 60;
|
||||
|
||||
clear_tex();
|
||||
}
|
||||
|
||||
void ripple_emit::set_stage_index(int32_t stage_index) {
|
||||
if (current_stage_index == stage_index)
|
||||
return;
|
||||
|
||||
current_stage_index = stage_index;
|
||||
stage_set = false;
|
||||
if (stage_index == -1)
|
||||
return;
|
||||
|
||||
for (int32_t& i : stage_indices) {
|
||||
if (i != stage_index)
|
||||
continue;
|
||||
|
||||
stage_set = true;
|
||||
set_stage_param(stage_param_data_ripple_storage_get_value(i));
|
||||
clear_tex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ripple_emit::set_stage_indices(std::vector<int32_t>& stage_indices) {
|
||||
static const int32_t dword_1409E5330[] = {
|
||||
0, 1, 2, 4, 10, 5, 12, 7, 14, 9, 21, 15, 23, 17, 25, 19, 26, 20
|
||||
};
|
||||
|
||||
stage_set = false;
|
||||
current_stage_index = -1;
|
||||
this->stage_indices.clear();
|
||||
|
||||
stage_param_data_ripple_storage_clear();
|
||||
for (int32_t& i : stage_indices) {
|
||||
stage_param_ripple ripple;
|
||||
if (task_effect_array_parse_stage_param_data_ripple(&ripple, i)) {
|
||||
this->stage_indices.push_back(i);
|
||||
stage_param_data_ripple_storage_set_stage_data(i, &ripple);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->stage_indices.size())
|
||||
return;
|
||||
|
||||
current_stage_index = this->stage_indices.front();
|
||||
stage_param_ripple* ripple = stage_param_data_ripple_storage_get_value(this->stage_indices.front());
|
||||
if (!ripple)
|
||||
return;
|
||||
|
||||
stage_set = true;
|
||||
set_stage_param(ripple);
|
||||
|
||||
delta_frame = 1.0f;
|
||||
counter = 0;
|
||||
field_BEC = 0;
|
||||
|
||||
rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_USER, true);
|
||||
rctx_ptr->render_manager.add_user_func(0, ripple_emit::draw_static, this);
|
||||
|
||||
field_4F0 = 18;
|
||||
for (struc_207& i : field_4F4)
|
||||
for (int32_t j = 0; j < field_4F0; j++) {
|
||||
i.field_0[j].index = dword_1409E5330[j];
|
||||
i.field_0[j].trans = 0.0f;
|
||||
}
|
||||
|
||||
update = false;
|
||||
field_30 = 60;
|
||||
|
||||
clear_tex();
|
||||
}
|
||||
|
||||
void ripple_emit::set_stage_param(stage_param_ripple* ripple) {
|
||||
data_struct* aft_data = &data_list[DATA_AFT];
|
||||
texture_database* aft_tex_db = &aft_data->data_ft.tex_db;
|
||||
|
||||
params.wake_attn = ripple->wake_attn;
|
||||
params.speed = ripple->speed;
|
||||
rain_ripple_num = (int32_t)ripple->rain_ripple_num;
|
||||
rain_ripple_min_value = ripple->rain_ripple_min_value;
|
||||
rain_ripple_max_value = ripple->rain_ripple_max_value;
|
||||
ground_y = ripple->ground_y;
|
||||
emit_pos_scale = ripple->emit_pos_scale;
|
||||
emit_pos_ofs_x = ripple->emit_pos_ofs_x;
|
||||
emit_pos_ofs_z = ripple->emit_pos_ofs_z;
|
||||
ripple_tex_id = aft_tex_db->get_texture_id(ripple->ripple_tex_name.c_str());
|
||||
use_float_ripplemap = ripple->use_float_ripplemap;
|
||||
rob_emitter_size = ripple->rob_emitter_size;
|
||||
emitter_num = ripple->emitter_num;
|
||||
emitter_list = ripple->emitter_list.data();
|
||||
emitter_size = ripple->emitter_size;
|
||||
}
|
||||
|
||||
void ripple_emit::draw_static(void* data) {
|
||||
((ripple_emit*)data)->draw();
|
||||
}
|
||||
|
||||
void ripple_emit::sub_1403584A0(render_texture* rt) {
|
||||
if (ripple_tex_id == -1)
|
||||
return;
|
||||
|
||||
texture* ripple_tex = texture_storage_get_texture(ripple_tex_id);
|
||||
if (!ripple_tex)
|
||||
return;
|
||||
|
||||
field_BB8.set_color_depth_textures(ripple_tex->tex, 0, 0);
|
||||
field_BB8.bind(0);
|
||||
|
||||
image_filter_scale(rctx_ptr, ripple_tex->tex, rt->color_texture->tex, 1.0f);
|
||||
gl_state_bind_framebuffer(0);
|
||||
}
|
||||
|
||||
|
||||
void ripple_emit::sub_140358690() {
|
||||
ripple_emit_draw_data& v1 = field_178;
|
||||
v1.data.vertex = field_50.vertex;
|
||||
v1.data.color = field_50.color;
|
||||
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
v1.data.vertex[i].x = rand_state_array_get_float(4) * 1.8f - 0.9f;
|
||||
v1.data.vertex[i].y = rand_state_array_get_float(4) * 1.8f - 0.9f;
|
||||
rand_state_array_get_int(0x03, 0x07, 4);
|
||||
v1.data.vertex[i].z = (float_t)rand_state_array_get_int(0x20, 0xA0, 4);
|
||||
}
|
||||
|
||||
v1.data.count = 16;
|
||||
v1.data.ripple_uniform = 1;
|
||||
v1.data.ripple_emit_uniform = 1;
|
||||
|
||||
add_draw_ripple_emit(&v1.data);
|
||||
}
|
||||
|
||||
void ripple_emit::sub_1403587C0(const vec3 a2, const vec3 a3, float_t a4, struc_101& a5, struc_101& a6) {
|
||||
vec3 v34 = a3 - a2;
|
||||
|
||||
float_t v17 = ground_y - (a2.y - a4);
|
||||
int32_t v19 = 1 - (int32_t)(min_def(v17, a4) * -30.0f);
|
||||
int32_t v20 = v19 + 3;
|
||||
|
||||
float_t v21 = sqrtf(v34.x * v34.x + v34.z * v34.z) * 0.8f;
|
||||
if (v21 < 0.03f)
|
||||
v21 = 0.0f;
|
||||
|
||||
if (a3.y - a4 > ground_y) {
|
||||
v21 += (float_t)(v34.y * 3.0f);
|
||||
v20 += (int32_t)(float_t)(v34.y * 30.0f);
|
||||
}
|
||||
|
||||
float_t v23 = sqrtf(v34.x * v34.x + v34.z * v34.z);
|
||||
if (v23 >= 0.01f)
|
||||
v34 *= 1.0f / v23;
|
||||
else
|
||||
v34 = 0.0f;
|
||||
|
||||
float_t v24 = min_def(v21, 0.2f);
|
||||
if (v23 > 0.5f) {
|
||||
v23 = 0.01f;
|
||||
v24 = 0.0f;
|
||||
}
|
||||
|
||||
int32_t v33 = v20 - (int32_t)(v23 * -20.0f);
|
||||
int32_t v37 = (int32_t)(a4 * 60.0f);
|
||||
int32_t v27 = v33 >= v37 ? v37 : v33;
|
||||
|
||||
vec4u8 v19a = { 0x08, 0x00, 0x00, (uint8_t)v19 };
|
||||
vec4u8 v29 = { (uint8_t)v27, 0x00, 0x00, (uint8_t)(int32_t)(v24 * 1275.0f) };
|
||||
|
||||
for (float_t i = 0.0f; i < v23; i += 0.03f) {
|
||||
if (v24 > 0.0f) {
|
||||
int32_t count = a6.count;
|
||||
if (count < 16) {
|
||||
a6.vertex[count].x = (a2.x - v34.x * 0.2f + i * v34.x) * emit_pos_scale;
|
||||
a6.vertex[count].y = 0.0;
|
||||
a6.vertex[count].z = (a2.z - v34.z * 0.2f + i * v34.z) * emit_pos_scale;
|
||||
a6.color[count] = v29;
|
||||
a6.count++;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t count = a5.count;
|
||||
if (count < 16) {
|
||||
a5.vertex[count].x = (a2.x + i * v34.x) * emit_pos_scale;
|
||||
a5.vertex[count].y = 0.0f;
|
||||
a5.vertex[count].z = (a2.z + i * v34.z) * emit_pos_scale;
|
||||
a6.color[count] = v19a;
|
||||
a5.count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ripple_emit::sub_14035AAE0() {
|
||||
ripple_emit_draw_data& v1 = field_3C8;
|
||||
|
||||
field_3C8.data.count = 0;
|
||||
field_3C8.data.vertex = field_3C8.vertex;
|
||||
field_3C8.data.color = field_3C8.color;
|
||||
field_3C8.data.size = emitter_size;
|
||||
|
||||
if (!update)
|
||||
return;
|
||||
|
||||
if (rain_ripple_num) {
|
||||
int32_t min_value = (int32_t)(rain_ripple_min_value * 127.0f);
|
||||
int32_t max_value = (int32_t)(rain_ripple_max_value * 127.0f - rain_ripple_min_value * 127.0f);
|
||||
|
||||
max_value = max_def(max_value, 1);
|
||||
min_value = min_def(min_value, 126);
|
||||
|
||||
for (int32_t i = 0; i < rain_ripple_num; i++) {
|
||||
v1.data.vertex[i].x = (float_t)(rand_state_array_get_int(4) % 1000) * 0.001f * 2.0f - 1.0f;
|
||||
v1.data.vertex[i].y = 0.0f;
|
||||
v1.data.vertex[i].y = (float_t)(rand_state_array_get_int(4) % 1000) * 0.001f * 2.0f - 1.0f;
|
||||
v1.data.color[i] = { 0x00, 0x00, 0x00,
|
||||
(uint8_t)(0x7F - rand_state_array_get_int(4) % max_value - min_value) };
|
||||
v1.data.count++;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < emitter_num; i++) {
|
||||
float_t v10 = emitter_list[i].z;
|
||||
v1.data.vertex[i].x = ((rand_state_array_get_float(4) - 0.5f)
|
||||
* v10 + emitter_list[i].x) * emit_pos_scale;
|
||||
v1.data.vertex[i].y = 0.0f;
|
||||
v1.data.vertex[i].z = ((rand_state_array_get_float(4) - 0.5f)
|
||||
* v10 + emitter_list[i].y) * emit_pos_scale;
|
||||
v1.data.color[i] = rand_state_array_get_float(4) < 0.5f
|
||||
? vec4u8(0x00, 0x00, 0x00, 0xFF) : vec4u8(0x00, 0x00, 0x00, 0xFF);
|
||||
v1.data.count++;
|
||||
}
|
||||
|
||||
v1.data.ripple_uniform = use_float_ripplemap ? 1 : 0;
|
||||
v1.data.ripple_emit_uniform = 0;
|
||||
|
||||
add_draw_ripple_emit(&v1.data);
|
||||
}
|
||||
|
||||
void ripple_emit::sub_14035AED0() {
|
||||
field_178.data.count = 0;
|
||||
field_178.data.vertex = field_178.vertex;
|
||||
field_178.data.color = field_178.color;
|
||||
field_178.data.size = rob_emitter_size;
|
||||
|
||||
field_2A0.data.count = 0;
|
||||
field_2A0.data.vertex = field_2A0.vertex;
|
||||
field_2A0.data.color = field_2A0.color;
|
||||
field_2A0.data.size = rob_emitter_size;
|
||||
|
||||
if (!update)
|
||||
return;
|
||||
|
||||
ripple_emit_draw_data& v2 = field_178;
|
||||
ripple_emit_draw_data& v3 = field_2A0;
|
||||
|
||||
int32_t chara_id = 0;
|
||||
for (struc_207& i : field_4F4) {
|
||||
if (!rob_chara_array_check_visibility(chara_id)) {
|
||||
chara_id++;
|
||||
continue;
|
||||
}
|
||||
|
||||
rob_chara* rob_chr = rob_chara_array_get(chara_id);
|
||||
if (!rob_chr) {
|
||||
chara_id++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < field_4F0; j++) {
|
||||
struc_192& v4 = i.field_0[j];
|
||||
vec3 trans = 0.0f;
|
||||
float_t scale = rob_chr->get_trans_scale(v4.index, trans);
|
||||
if (trans.y - ground_y < scale) {
|
||||
if (use_float_ripplemap)
|
||||
sub_1403587C0(trans, v4.trans, scale, v2.data, v3.data);
|
||||
else if (v2.data.count < 16) {
|
||||
v2.data.vertex[v2.data.count].x = ((rand_state_array_get_float(4) - 0.5f)
|
||||
* 0.02f + trans.x) * emit_pos_scale + emit_pos_ofs_x;
|
||||
v2.data.vertex[v2.data.count].y = trans.y;
|
||||
v2.data.vertex[v2.data.count].z = ((rand_state_array_get_float(4) - 0.5f)
|
||||
* 0.02f + trans.z) * emit_pos_scale + emit_pos_ofs_z;
|
||||
v2.data.color[v2.data.count] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
v2.data.count++;
|
||||
}
|
||||
}
|
||||
v4.trans = trans;
|
||||
}
|
||||
|
||||
chara_id++;
|
||||
}
|
||||
|
||||
if (use_float_ripplemap) {
|
||||
v3.data.ripple_uniform = !!use_float_ripplemap;
|
||||
v3.data.ripple_emit_uniform = 1;
|
||||
add_draw_ripple_emit(&v3.data);
|
||||
}
|
||||
|
||||
v2.data.ripple_uniform = !!use_float_ripplemap;
|
||||
v2.data.ripple_emit_uniform = 0;
|
||||
add_draw_ripple_emit(&v2.data);
|
||||
}
|
||||
|
||||
TaskEffectRipple::TaskEffectRipple() : field_68(), frame_rate_control(), emit() {
|
||||
|
||||
}
|
||||
@@ -1698,24 +2198,26 @@ TaskEffectRipple::~TaskEffectRipple() {
|
||||
}
|
||||
|
||||
bool TaskEffectRipple::Init() {
|
||||
ripple_emit_init();
|
||||
//sub_1400DE640("TaskEffectRipple::init()\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskEffectRipple::Ctrl() {
|
||||
emit->delta_frame = frame_rate_control->GetDeltaFrame();
|
||||
//emit->ctrl();
|
||||
emit->ctrl();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TaskEffectRipple::Dest() {
|
||||
//emit->dest();
|
||||
emit->dest();
|
||||
//sub_1400DE640("TaskEffectRipple::dest()\n");
|
||||
ripple_emit_free();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TaskEffectRipple::Disp() {
|
||||
//emit->disp();
|
||||
emit->disp();
|
||||
}
|
||||
|
||||
void TaskEffectRipple::PreInit(int32_t stage_index) {
|
||||
@@ -1724,12 +2226,12 @@ void TaskEffectRipple::PreInit(int32_t stage_index) {
|
||||
|
||||
void TaskEffectRipple::SetStageIndices(std::vector<int32_t>& stage_indices) {
|
||||
SetFrameRateControl(0);
|
||||
//emit = &ripple_emit_data;
|
||||
//emit->set_stage_indices(stage_indices);
|
||||
emit = ripple_emit_data;
|
||||
emit->set_stage_indices(stage_indices);
|
||||
}
|
||||
|
||||
void TaskEffectRipple::SetCurrentStageIndex(int32_t value) {
|
||||
//emit->set_stage_index(value);
|
||||
emit->set_stage_index(value);
|
||||
}
|
||||
|
||||
void TaskEffectRipple::SetFrameRateControl(FrameRateControl* value) {
|
||||
@@ -1740,9 +2242,9 @@ void TaskEffectRipple::SetFrameRateControl(FrameRateControl* value) {
|
||||
}
|
||||
|
||||
void TaskEffectRipple::Reset() {
|
||||
//if (!emit->use_float_ripplemap)
|
||||
// ripple_emit_data.clear_tex();
|
||||
//ripple_emit_data.reset();
|
||||
if (!emit->use_float_ripplemap)
|
||||
ripple_emit_data->clear_tex();
|
||||
ripple_emit_data->reset();
|
||||
}
|
||||
|
||||
void leaf_particle_draw() {
|
||||
@@ -1930,6 +2432,9 @@ void task_effect_init() {
|
||||
|
||||
if (!task_effect_parent)
|
||||
task_effect_parent = new TaskEffectParent;
|
||||
|
||||
if (!ripple_emit_data)
|
||||
ripple_emit_data = new ripple_emit;
|
||||
|
||||
task_effect_fog_anim_data = 0;
|
||||
task_effect_fog_ring_data = 0;
|
||||
@@ -1997,6 +2502,11 @@ void task_effect_free() {
|
||||
task_effect_parent = 0;
|
||||
}
|
||||
|
||||
if (ripple_emit_data) {
|
||||
delete ripple_emit_data;
|
||||
ripple_emit_data = 0;
|
||||
}
|
||||
|
||||
task_effect_fog_anim_data = 0;
|
||||
task_effect_fog_ring_data = 0;
|
||||
task_effect_splash_data = 0;
|
||||
@@ -2527,6 +3037,71 @@ static void draw_fog_particle(render_context* rctx, TaskEffectFogRing::Data* dat
|
||||
gl_state_disable_blend();
|
||||
}
|
||||
|
||||
static void draw_ripple_emit(render_context* rctx, struc_101* data) {
|
||||
gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
|
||||
{
|
||||
size_t count = data->count;
|
||||
vec3* vertex = data->vertex;
|
||||
vec4u8* color = data->color;
|
||||
|
||||
const size_t vtx_count = (size_t)count * 0x06;
|
||||
vec3* vtx_data = force_malloc_s(vec3, vtx_count);
|
||||
|
||||
for (size_t i = count; i; i--, vtx_data += 6, vertex++, color++) {
|
||||
vtx_data[0] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
vtx_data[1] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
vtx_data[2] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
vtx_data[3] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
vtx_data[4] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
vtx_data[5] = { vertex->x, vertex->z, (float_t)color->w };
|
||||
}
|
||||
|
||||
vtx_data -= vtx_count;
|
||||
|
||||
if (GLAD_GL_VERSION_4_5)
|
||||
glNamedBufferSubData(ripple_emit_vbo, 0, sizeof(vec3) * vtx_count, vtx_data);
|
||||
else {
|
||||
gl_state_bind_array_buffer(ripple_emit_vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3) * vtx_count, vtx_data);
|
||||
gl_state_bind_array_buffer(0);
|
||||
}
|
||||
free_def(vtx_data);
|
||||
}
|
||||
|
||||
int32_t size = (int32_t)(data->size + 0.5f);
|
||||
|
||||
render_texture& rt = rctx->render_manager.get_render_texture(
|
||||
ripple_emit_data->use_float_ripplemap ? 2 : 5);
|
||||
int32_t width = rt.color_texture->width;
|
||||
int32_t height = rt.color_texture->height;
|
||||
|
||||
ripple_emit_scene_shader_data shader_data = {};
|
||||
shader_data.g_size_in_projection = {
|
||||
(float_t)size / (float_t)width,
|
||||
(float_t)size / (float_t)height,
|
||||
0.0f, 0.0f
|
||||
};
|
||||
shader_data.g_transform.x = (float_t)width / (float_t)(width - 2);
|
||||
shader_data.g_transform.y = (float_t)height / (float_t)(height - 2);
|
||||
shader_data.g_transform.z = 0.0079498291f / (float_t)(width - 2);
|
||||
shader_data.g_transform.w = -0.0079498291f / (float_t)(height - 2);
|
||||
shader_data.g_framebuffer_size = {
|
||||
1.0f / (float_t)width,
|
||||
1.0f / (float_t)height,
|
||||
0.0f, 0.0f };
|
||||
ripple_emit_scene_ubo.WriteMapMemory(shader_data);
|
||||
|
||||
uniform_value[U_RIPPLE] = data->ripple_uniform;
|
||||
uniform_value[U_RIPPLE_EMIT] = data->ripple_emit_uniform;
|
||||
gl_state_bind_vertex_array(ripple_emit_vao);
|
||||
shaders_ft.set(SHADER_FT_RIPEMIT);
|
||||
ripple_emit_scene_ubo.Bind(0);
|
||||
shaders_ft.draw_arrays(GL_TRIANGLES, 0, data->count * 6);
|
||||
|
||||
gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
|
||||
static void leaf_particle_init(bool change_stage) {
|
||||
leaf_particle_emit_timer = 0.0f;
|
||||
leaf_particle_emit_interval = stage_param_data_leaf_current->emit_interval;
|
||||
@@ -3179,3 +3754,117 @@ static void rain_particle_free() {
|
||||
rain_particle_scene_ubo.Destroy();
|
||||
rain_particle_batch_ubo.Destroy();
|
||||
}
|
||||
|
||||
static void ripple_emit_init() {
|
||||
if (!ripple_vao)
|
||||
glGenVertexArrays(1, &ripple_vao);
|
||||
|
||||
ripple_batch_ubo.Create(sizeof(ripple_batch_shader_data));
|
||||
ripple_scene_ubo.Create(sizeof(ripple_scene_shader_data));
|
||||
|
||||
if (!ripple_emit_vao)
|
||||
glGenVertexArrays(1, &ripple_emit_vao);
|
||||
|
||||
if (!ripple_emit_vbo)
|
||||
glGenBuffers(1, &ripple_emit_vbo);
|
||||
|
||||
size_t max_count = 16;
|
||||
|
||||
const size_t max_vtx_count = (size_t)max_count * 0x06;
|
||||
|
||||
static const GLsizei buffer_size = sizeof(vec3);
|
||||
|
||||
gl_state_bind_array_buffer(ripple_emit_vbo, true);
|
||||
if (GLAD_GL_VERSION_4_4)
|
||||
glBufferStorage(GL_ARRAY_BUFFER,
|
||||
(GLsizeiptr)(buffer_size * max_vtx_count),
|
||||
0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT);
|
||||
else
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
(GLsizeiptr)(buffer_size * max_vtx_count),
|
||||
0, GL_DYNAMIC_DRAW);
|
||||
|
||||
gl_state_bind_vertex_array(ripple_emit_vao);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, 0);
|
||||
|
||||
gl_state_bind_vertex_array(0);
|
||||
gl_state_bind_array_buffer(0);
|
||||
|
||||
ripple_emit_scene_ubo.Create(sizeof(ripple_emit_scene_shader_data));
|
||||
}
|
||||
|
||||
static void ripple_emit_free() {
|
||||
if (ripple_vao) {
|
||||
glDeleteVertexArrays(1, &ripple_vao);
|
||||
ripple_vao = 0;
|
||||
}
|
||||
|
||||
ripple_batch_ubo.Destroy();
|
||||
ripple_scene_ubo.Destroy();
|
||||
|
||||
if (ripple_emit_vao) {
|
||||
glDeleteVertexArrays(1, &ripple_emit_vao);
|
||||
ripple_emit_vao = 0;
|
||||
}
|
||||
|
||||
if (ripple_emit_vbo) {
|
||||
glDeleteBuffers(1, &ripple_emit_vbo);
|
||||
ripple_emit_vbo = 0;
|
||||
}
|
||||
|
||||
ripple_emit_scene_ubo.Destroy();
|
||||
}
|
||||
|
||||
static void sub_1403B6ED0(render_texture* a1, render_texture* a2, render_texture* a3, ripple_emit_params& params) {
|
||||
a1->bind();
|
||||
if (a1->color_texture->internal_format == GL_RGBA32F
|
||||
|| a1->color_texture->internal_format == GL_RGBA16F)
|
||||
uniform_value[U_RIPPLE] = 1;
|
||||
else
|
||||
uniform_value[U_RIPPLE] = 0;
|
||||
sub_1403B6F60(a1->color_texture->tex, a2->color_texture->tex, a3->color_texture->tex, params);
|
||||
gl_state_bind_framebuffer(0);
|
||||
}
|
||||
|
||||
static void sub_1403B6F60(GLuint a1, GLuint a2, GLuint a3, ripple_emit_params& params) {
|
||||
if (!a1 || !a2 || !a3)
|
||||
return;
|
||||
|
||||
texture_param tex_params[2];
|
||||
texture_params_get(0, 0, a1, &tex_params[0], a2, &tex_params[1]);
|
||||
|
||||
int32_t width = tex_params[1].width;
|
||||
int32_t height = tex_params[1].height;
|
||||
|
||||
GLint v43[4];
|
||||
glGetIntegerv(GL_VIEWPORT, v43);
|
||||
glViewport(1, 1, width - 2, height - 2);
|
||||
|
||||
ripple_scene_shader_data ripple_scene = {};
|
||||
ripple_scene.g_transform = {
|
||||
params.speed / (float_t)width, params.speed / (float_t)height,
|
||||
(float_t)width / (float_t)(width - 2), (float_t)height / (float_t)(height - 2)
|
||||
};
|
||||
ripple_scene.g_texcoord = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
ripple_scene_ubo.WriteMapMemory(ripple_scene);
|
||||
|
||||
ripple_batch_shader_data ripple_batch = {};
|
||||
ripple_batch.g_params = { params.wake_attn, params.speed, params.field_8, params.field_C };
|
||||
ripple_batch_ubo.WriteMapMemory(ripple_batch);
|
||||
|
||||
gl_state_bind_vertex_array(ripple_vao);
|
||||
shaders_ft.set(SHADER_FT_RIPPLE);
|
||||
ripple_scene_ubo.Bind(0);
|
||||
ripple_batch_ubo.Bind(1);
|
||||
gl_state_active_bind_texture_2d(0, a2);
|
||||
gl_state_active_bind_texture_2d(1, a3);
|
||||
shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
gl_state_active_bind_texture_2d(0, 0);
|
||||
gl_state_active_bind_texture_2d(1, 0);
|
||||
gl_state_active_texture(0);
|
||||
|
||||
glViewport(v43[0], v43[1], v43[2], v43[3]);
|
||||
|
||||
texture_params_restore(&tex_params[0], &tex_params[1]);
|
||||
}
|
||||
|
||||
+48
-20
@@ -14,6 +14,7 @@
|
||||
#include "frame_rate_control.hpp"
|
||||
#include "render_texture.hpp"
|
||||
#include "stage.hpp"
|
||||
#include "stage_param.hpp"
|
||||
#include "task.hpp"
|
||||
|
||||
enum TaskEffectType {
|
||||
@@ -361,19 +362,12 @@ public:
|
||||
virtual void Reset() override;
|
||||
};
|
||||
|
||||
struct color4u8 {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
|
||||
struct struc_101 {
|
||||
int32_t ripple_uniform;
|
||||
int32_t ripple_emit_uniform;
|
||||
int32_t count;
|
||||
vec3* vertex;
|
||||
color4u8* color;
|
||||
vec4u8* color;
|
||||
float_t size;
|
||||
int32_t field_24;
|
||||
};
|
||||
@@ -381,21 +375,36 @@ struct struc_101 {
|
||||
struct ripple_emit_draw_data {
|
||||
struc_101 data;
|
||||
vec3 vertex[16];
|
||||
color4u8 color[16];
|
||||
vec4u8 color[16];
|
||||
|
||||
ripple_emit_draw_data();
|
||||
};
|
||||
|
||||
struct struc_192 {
|
||||
int32_t field_0;
|
||||
vec3 field_4;
|
||||
int32_t index;
|
||||
vec3 trans;
|
||||
|
||||
struc_192();
|
||||
};
|
||||
|
||||
struct struc_207 {
|
||||
struc_192 field_0[18];
|
||||
|
||||
struc_207();
|
||||
};
|
||||
|
||||
struct ripple_emit_params {
|
||||
float_t wake_attn;
|
||||
float_t speed;
|
||||
float_t field_8;
|
||||
float_t field_C;
|
||||
|
||||
ripple_emit_params();
|
||||
};
|
||||
|
||||
struct ripple_emit {
|
||||
float_t delta_frame;
|
||||
int8_t field_4;
|
||||
bool update;
|
||||
int32_t rain_ripple_num;
|
||||
float_t rain_ripple_min_value;
|
||||
float_t rain_ripple_max_value;
|
||||
@@ -409,7 +418,7 @@ struct ripple_emit {
|
||||
int32_t field_30;
|
||||
float_t rob_emitter_size;
|
||||
size_t emitter_num;
|
||||
vec3* emitter_list;
|
||||
const vec3* emitter_list;
|
||||
float_t emitter_size;
|
||||
int32_t field_4C;
|
||||
ripple_emit_draw_data field_50;
|
||||
@@ -420,15 +429,34 @@ struct ripple_emit {
|
||||
struc_207 field_4F4[6];
|
||||
int32_t field_BB4;
|
||||
render_texture field_BB8;
|
||||
int32_t field_BE8;
|
||||
int32_t counter;
|
||||
int8_t field_BEC;
|
||||
float_t wake_attn;
|
||||
float_t speed;
|
||||
float_t field_BF8;
|
||||
float_t field_BFC;
|
||||
int8_t field_C00;
|
||||
ripple_emit_params params;
|
||||
bool stage_set;
|
||||
int32_t current_stage_index;
|
||||
std::vector<int32_t> stage_indices;
|
||||
|
||||
ripple_emit();
|
||||
~ripple_emit();
|
||||
|
||||
void add_draw_ripple_emit(struc_101* data);
|
||||
void clear_tex();
|
||||
void ctrl();
|
||||
void dest();
|
||||
void disp();
|
||||
void draw();
|
||||
void reset();
|
||||
void set_stage_index(int32_t stage_index);
|
||||
void set_stage_indices(std::vector<int32_t>& stage_indices);
|
||||
void set_stage_param(stage_param_ripple* ripple);
|
||||
|
||||
static void draw_static(void* data);
|
||||
|
||||
void sub_1403584A0(render_texture* rt);
|
||||
void sub_140358690();
|
||||
void sub_1403587C0(const vec3 a2, const vec3 a3, float_t a4, struc_101& a5, struc_101& a6);
|
||||
void sub_14035AAE0();
|
||||
void sub_14035AED0();
|
||||
};
|
||||
|
||||
struct TaskEffectRipple : public TaskEffect {
|
||||
@@ -541,7 +569,7 @@ struct water_particle {
|
||||
int32_t tex_id;
|
||||
bool blink;
|
||||
std::vector<vec3> field_48;
|
||||
std::vector<color4u8> field_60;
|
||||
std::vector<vec4u8> field_60;
|
||||
struc_101 field_78;
|
||||
float_t ripple_emission;
|
||||
};
|
||||
|
||||
@@ -203,6 +203,50 @@ void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_a
|
||||
glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
|
||||
}
|
||||
|
||||
void texture_params_get(GLuint tex_0, texture_param* tex_0_param,
|
||||
GLuint tex_1, texture_param* tex_1_param, GLuint tex_2, texture_param* tex_2_param) {
|
||||
gl_state_disable_depth_test();
|
||||
if (tex_0_param) {
|
||||
tex_0_param->width = 0;
|
||||
tex_0_param->height = 0;
|
||||
if (tex_0) {
|
||||
gl_state_bind_texture_2d(tex_0);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_0_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_0_param->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_1_param) {
|
||||
tex_1_param->width = 0;
|
||||
tex_1_param->height = 0;
|
||||
if (tex_1) {
|
||||
gl_state_bind_texture_2d(tex_1);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_1_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_1_param->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_2_param) {
|
||||
tex_2_param->width = 0;
|
||||
tex_2_param->height = 0;
|
||||
if (tex_2) {
|
||||
gl_state_bind_texture_2d(tex_2);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_2_param->width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_2_param->height);
|
||||
}
|
||||
}
|
||||
gl_state_bind_texture_2d(0);
|
||||
|
||||
if (tex_0_param)
|
||||
glViewport(0, 0, tex_0_param->width, tex_0_param->height);
|
||||
}
|
||||
|
||||
void texture_params_restore(texture_param* tex_0_param,
|
||||
texture_param* tex_1_param, texture_param* tex_2_param) {
|
||||
for (int32_t i = 0; i < 4; i++)
|
||||
gl_state_active_bind_texture_2d(i, 0);
|
||||
}
|
||||
|
||||
bool texture_txp_set_load(txp_set* t, texture*** texs, uint32_t* ids) {
|
||||
if (!t || !texs || !ids)
|
||||
return false;
|
||||
|
||||
@@ -72,6 +72,11 @@ struct texture {
|
||||
uint32_t get_width_align_mip_level(uint8_t mip_level = 0);
|
||||
};
|
||||
|
||||
struct texture_param {
|
||||
GLint width;
|
||||
GLint height;
|
||||
};
|
||||
|
||||
extern texture* texture_init(texture_id id);
|
||||
extern void texture_apply_color_tone(texture* chg_tex,
|
||||
texture* org_tex, const color_tone* col_tone);
|
||||
@@ -87,6 +92,11 @@ extern void texture_array_free(texture** arr);
|
||||
|
||||
extern void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy);
|
||||
|
||||
extern void texture_params_get(GLuint tex_0 = 0, texture_param* tex_0_param = 0,
|
||||
GLuint tex_1 = 0, texture_param* tex_1_param = 0, GLuint tex_2 = 0, texture_param* tex_2_param = 0);
|
||||
extern void texture_params_restore(texture_param* tex_0_param = 0,
|
||||
texture_param* tex_1_param = 0, texture_param* tex_2_param = 0);
|
||||
|
||||
extern bool texture_txp_set_load(txp_set* t, texture*** texs, uint32_t* ids);
|
||||
extern bool texture_txp_set_load(txp_set* t, texture*** texs, texture_id* ids);
|
||||
|
||||
|
||||
@@ -158,9 +158,9 @@ static void stage_param_ripple_read_inner(stage_param_ripple* ripple, stream& s)
|
||||
|
||||
ripple->ripple_tex_name.assign(buf + 16);
|
||||
}
|
||||
else if (!str_utils_compare_length(buf, sizeof(buf), "use_float_ripplemap", 4)) {
|
||||
else if (!str_utils_compare_length(buf, sizeof(buf), "use_float_ripplemap", 19)) {
|
||||
int32_t use_float_ripplemap = 0;
|
||||
if (buf[4] != ' ' || sscanf_s(buf + 5, "%d", &use_float_ripplemap) != 1)
|
||||
if (buf[19] != ' ' || sscanf_s(buf + 20, "%d", &use_float_ripplemap) != 1)
|
||||
goto End;
|
||||
|
||||
ripple->use_float_ripplemap = !!use_float_ripplemap;
|
||||
|
||||
Reference in New Issue
Block a user