mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-07 14:18:30 +03:00
Ripple
This commit is contained in:
+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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user