Init render data by DivaGL

This commit is contained in:
korenkonder
2024-04-02 23:51:10 +03:00
parent 17e78dd81f
commit e5418a847b
9 changed files with 566 additions and 2 deletions
+1
View File
@@ -56,6 +56,7 @@ HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) {
render_manager_patch();
rob_patch();
pv_game_patch();
shadow_patch();
sprite_patch();
stage_patch();
texture_patch();
+10
View File
@@ -1014,6 +1014,16 @@ namespace rndr {
}
}
void Render::set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height) {
screen_x_offset = x_offset;
screen_y_offset = y_offset;
screen_width = min_def(width, this->width);
screen_height = min_def(height, this->height);
update_res(false, -1);
update = 1;
}
void Render::take_ss(texture* tex, bool vertical, float_t horizontal_offset) {
int32_t index = render_texture_set(tex, true);
if (index < 0)
+1
View File
@@ -191,6 +191,7 @@ namespace rndr {
int32_t render_texture_set(texture* render_texture, bool task_photo);
void render_texture_free(texture* render_texture, bool task_photo);
void resize(int32_t width, int32_t height);
void set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height);
void take_ss(texture* tex, bool vertical, float_t horizontal_offset);
void transparency_combine(float_t alpha);
void transparency_copy();
+19
View File
@@ -23,6 +23,25 @@ void draw_state_stats::reset() {
field_1C = 0;
}
void sss_data::free() {
if (init_data)
for (RenderTexture& i : textures)
i.Free();
}
void sss_data::init() {
if (init_data)
return;
textures[0].Init(640, 360, 0, GL_RGBA16F, GL_ZERO /*GL_DEPTH_COMPONENT32F*/);
textures[1].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
textures[2].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
textures[3].Init(320, 180, 0, GL_RGBA16F, GL_ZERO);
param = { 0.0f, 0.0f, 0.0f, 1.0f };
init_data = true;
}
void sss_data::set_texture(int32_t texture_index) {
gl_state_active_bind_texture_2d(16, textures[texture_index].GetColorTex());
gl_state_active_texture(0);
+2
View File
@@ -39,6 +39,8 @@ struct sss_data {
RenderTexture textures[4];
vec4 param;
void free();
void init();
void set_texture(int32_t);
};
+180
View File
@@ -44,6 +44,9 @@ static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type);
static void blur_filter_apply(RenderTexture* dst, RenderTexture* src,
blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset);
static void render_manager_free_render_textures();
static void render_manager_init_render_textures(int32_t multisample);
extern render_context* rctx;
RenderTexture* litproj_shadow = (RenderTexture*)0x0000000141194DA0;
@@ -51,6 +54,26 @@ RenderTexture* litproj_texture = (RenderTexture*)0x0000000141194E00;
rndr::RenderManager* render_manager = (rndr::RenderManager*)0x00000001411AD320;
namespace rndr {
struct RenderTextureData {
GLenum type;
int32_t width;
int32_t height;
int32_t max_level;
GLenum color_format;
GLenum depth_format;
};
static const RenderTextureData render_manager_render_texture_data_array[] = {
{ GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA8 , GL_DEPTH_COMPONENT24 },
{ GL_TEXTURE_2D, 0x200, 0x100, 0, GL_RGBA16F, GL_DEPTH_COMPONENT24 },
{ GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO },
{ GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO },
{ GL_TEXTURE_2D, 0x400, 0x400, 0, GL_RGBA8 , GL_ZERO },
{ GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO },
{ GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA32F, GL_ZERO },
{ GL_TEXTURE_2D, 0x100, 0x100, 0, GL_RGBA8 , GL_ZERO },
};
static const int32_t render_manager_render_texture_index_array[][3] = {
{ 1, 1, 1 },
{ 0, 0, 0 },
@@ -81,6 +104,65 @@ namespace rndr {
return render_textures[render_manager_render_texture_index_array[index][tex_index[index]]];
}
void RenderManager::reset() {
for (int32_t i = 0; i < RND_PASSID_NUM; i++) {
pass_sw[i] = true;
cpu_time[i] = 0.0;
gpu_time[i] = 0.0;
}
set_pass_sw(RND_PASSID_2, 0);
set_pass_sw(RND_PASSID_REFLECT, 0);
set_pass_sw(RND_PASSID_REFRACT, 0);
set_pass_sw(RND_PASSID_PRE_PROCESS, 0);
set_pass_sw(RND_PASSID_SHOW_VECTOR, 0);
shadow_ptr = 0;
sync_gpu = false;
time.get_timestamp();
shadow = true;
opaque_z_sort = true;
alpha_z_sort = true;
field_11F = false;
field_120 = false;
reflect_blur_num = 1;
reflect_blur_filter = BLUR_FILTER_4;
show_ref_map = false;
reflect_type = STAGE_DATA_REFLECT_DISABLE;
check_state = false;
show_vector_flags = 0;
show_vector_length = 0.05f;
show_vector_z_offset = 0.0f;
show_stage_shadow = false;
effect_texture = 0;
reflect = false;
refract = false;
npr_param = 0;
field_31C = false;
field_31D = false;
field_31E = false;
field_31F = false;
field_320 = false;
for (bool& i : draw_pass_3d)
i = true;
field_11E = false;
clear = false;
width = 0;
height = 0;
multisample_framebuffer = 0;
multisample_renderbuffer = 0;
multisample = true;
npr = false;
}
void RenderManager::resize(int32_t width, int32_t height) {
if (this->width == width && this->height == height)
return;
@@ -1093,6 +1175,15 @@ HOOK(void, FASTCALL, render_manager_init_render_textures, 0x0000000140502560, in
gl_state_bind_framebuffer(0);
}
HOOK(void, FASTCALL, render_manager_free_data, 0x0000000140502770) {
render_manager_free_render_textures();
render_manager->render->free();
shadow_ptr_free();
sss_data_get()->free();
}
HOOK(void, FASTCALL, render_manager_free_render_textures, 0x00000001405027A0) {
rndr::RenderManager& render_manager = *::render_manager;
@@ -1110,9 +1201,40 @@ HOOK(void, FASTCALL, render_manager_free_render_textures, 0x00000001405027A0) {
i.Free();
}
HOOK(void, FASTCALL, render_manager_init_data, 0x0000000140502A10, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask, bool npr) {
rndr::RenderManager& render_manager = *::render_manager;
render_manager.reset();
render_manager.npr = npr;
render_texture_counter_reset();
resolution_struct* res_wind = res_window_get();
resolution_struct* res_wind_int = res_window_internal_get();
render_manager.render = render_get();
render_manager.render->init_render_buffers(res_wind_int->width, res_wind_int->height, ssaa, hd_res, ss_alpha_mask);
render_manager.render->set_screen_res(res_wind_int->x_offset,
res_wind_int->y_offset, res_wind_int->width, res_wind_int->height);
render_manager.width = res_wind->width;
render_manager.height = res_wind->height;
render_manager_init_render_textures(1);
render_manager.render->init_tone_map_buffers();
shadow_ptr_init();
render_manager.shadow_ptr = shadow_ptr_get();
render_manager.shadow_ptr->init();
sss_data_get()->init();
void(FASTCALL * sub_1403B6CC0)() = (void(FASTCALL*)())0x00000001403B6CC0;
sub_1403B6CC0();
glGetErrorDLL();
}
void render_manager_patch() {
INSTALL_HOOK(render_manager_init_render_textures);
INSTALL_HOOK(render_manager_free_render_textures);
INSTALL_HOOK(render_manager_init_data);
}
static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) {
@@ -1790,3 +1912,61 @@ static void blur_filter_apply(RenderTexture* dst, RenderTexture* src,
gl_state_bind_sampler(0, rctx->render_samplers[0]);
shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4);
}
static void render_manager_free_render_textures() {
rndr::RenderManager& render_manager = *::render_manager;
if (render_manager.multisample_renderbuffer) {
glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer);
render_manager.multisample_renderbuffer = 0;
}
if (render_manager.multisample_framebuffer) {
glDeleteFramebuffers(1, &render_manager.multisample_framebuffer);
render_manager.multisample_framebuffer = 0;
}
for (RenderTexture& i : render_manager.render_textures)
i.Free();
}
static void render_manager_init_render_textures(int32_t multisample) {
rndr::RenderManager& render_manager = *::render_manager;
if (multisample) {
glGenFramebuffers(1, &render_manager.multisample_framebuffer);
glGenRenderbuffers(1, &render_manager.multisample_renderbuffer);
gl_state_bind_framebuffer(render_manager.multisample_framebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, render_manager.multisample_renderbuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8,
GL_RGBA8, render_manager.width, render_manager.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, render_manager.multisample_renderbuffer);
glDrawBufferDLL(GL_COLOR_ATTACHMENT0);
glDrawBufferDLL(GL_COLOR_ATTACHMENT0);
gl_state_bind_framebuffer(0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (glGetErrorDLL()) {
glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer);
render_manager.multisample_renderbuffer = 0;
glDeleteFramebuffers(1, &render_manager.multisample_framebuffer);
render_manager.multisample_framebuffer = 0;
}
}
for (int32_t i = 0; i < 9; i++) {
const rndr::RenderTextureData* tex_data = &rndr::render_manager_render_texture_data_array[i];
if (tex_data->type != GL_TEXTURE_2D)
continue;
RenderTexture& rt = render_manager.render_textures[i];
rt.Init(tex_data->width, tex_data->height, tex_data->max_level,
tex_data->color_format, tex_data->depth_format);
rt.Bind();
glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f);
glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
gl_state_bind_framebuffer(0);
}
+1
View File
@@ -103,6 +103,7 @@ namespace rndr {
void add_pre_process(int32_t type, void(*func)(void*), void* data);
void clear_pre_process(int32_t type);
RenderTexture& get_render_texture(int32_t index);
void reset();
void resize(int32_t width, int32_t height);
void set_clear(bool value);
void set_effect_texture(texture* value);
+344 -2
View File
@@ -4,16 +4,358 @@
*/
#include "shadow.hpp"
#include "render_context.hpp"
#include "render_manager.hpp"
#include <Helpers.h>
Shadow** shadow_ptr = (Shadow**)0x000000014CC587B8;
Shadow*& shadow_ptr = *(Shadow**)0x000000014CC587B8;
void(FASTCALL* sub_1405E8A20)(Shadow* shad, int32_t index, vec3* pos)
= (void(FASTCALL*)(Shadow* shad, int32_t index, vec3 * pos))0x00000001405E8A20;
void(FASTCALL* shadow_ptr_free)() = (void(FASTCALL*)())0x00000001405E8610;
void(FASTCALL* shadow_ptr_init)() = (void(FASTCALL*)())0x00000001405E8890;
void Shadow::ctrl() {
for (int32_t i = 0; i < 2; i++)
light_enable[i] = false;
if (render_manager->shadow) {
view_mat[0] = camera_data->view;
view_mat[1] = camera_data->inv_view;
light_data& light_chara = light_set_data[LIGHT_SET_MAIN].lights[LIGHT_CHARA];
vec3 position;
light_chara.get_position(position);
float_t length = vec3::length(position);
if (length < 0.000001f)
direction = { 0.0f, 1.0f, 0.0f };
else
direction = -position * (1.0f / length);
for (int32_t i = 0; i < 2; i++)
if (disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + i)))
light_enable[i] = true;
}
int32_t count = 0;
num_light = 0;
for (int32_t i = 0; i < 2; i++)
if (light_enable[i] && field_1D0[i].size() > 0) {
num_light++;
count += (int32_t)field_1D0[i].size();
}
else
light_enable[i] = false;
if (count < 3) {
for (int32_t i = 0; i < 2; i++) {
field_1A8[i] = 0.0f;
field_1C8[i] = 0.0f;
if (!light_enable[i] || field_1D0[i].size() < 1)
continue;
vec3 v7 = 0.0f;
for (vec3& j : field_1D0[i])
v7 += j;
float_t v14 = (float_t)(int64_t)field_1D0[i].size();
if (v14 < 0.0f)
v14 += (float_t)UINT64_MAX;
v7 *= 1.0f / v14;
float_t v15 = 0.0f;
for (vec3& j : field_1D0[i]) {
vec3 v22 = v7 - j;
vec3 v25 = direction * vec3::dot(v22, direction);
float_t v24 = vec3::distance(v25, v22);
v24 -= 0.25f;
if (v24 < 0.0f)
v24 = 0.0f;
if (v15 < v24)
v15 = v24;
}
field_1A8[i] = v7;
field_1C8[i] = v15;
}
if (num_light > 0) {
vec3 view_point = 0.0f;
vec3 interest = 0.0f;
for (int32_t i = 0; i < 2; i++) {
if (!light_enable[i])
continue;
vec3 v11 = field_1A8[i] - direction * field_208;
float_t v9 = vec3::distance(this->view_point[i], v11);
float_t v12 = vec3::distance(this->interest[i], field_1A8[i]);
if (v9 > 0.1f || v12 > 0.1f) {
this->view_point[i] = v11;
this->interest[i] = field_1A8[i];
}
view_point += this->view_point[i];
interest += this->interest[i];
}
view_point_shared = view_point * (1.0f / (float_t)num_light);
interest_shared = interest * (1.0f / (float_t)num_light);
}
float_t v2 = max_def(field_1C8[0], field_1C8[1]);
separate = false;
shadow_range = v2 + 1.2f;
field_200[0] = 0;
field_200[1] = 1;
if (num_light >= 2) {
vec3 v12 = field_1A8[0] - interest_shared;
vec3 v14 = field_1A8[1] - interest_shared;
float_t v6 = vec3::length(direction * vec3::dot(v12, direction) - v12);
float_t v16 = v6 - 0.25f;
if (v16 < 0.0f)
v16 = 0.0f;
if (v16 > 1.2f) {
shadow_range = v2 + 2.4f;
separate = true;
}
else
shadow_range = v2 + 1.2f + v16;
if (vec3::dot(v12, direction) < vec3::dot(v14, direction)) {
field_200[1] = 0;
field_200[0] = 1;
}
}
}
else {
vec3 v3;
vec3 v86;
if (direction.y * direction.y < 0.99f) {
v86 = vec3::cross(direction, vec3(0.0f, 1.0f, 0.0f));
v3 = vec3::normalize(vec3::cross(v86, direction));
v86 = vec3::normalize(v86);
}
else {
v3 = { 0.0f, 0.0f, 1.0f };
v86 = { 1.0f, 0.0f, 0.0f };
}
for (int32_t i = 0; i < 2; i++) {
field_1A8[i] = 0.0f;
field_1C8[i] = 0.0;
if (!light_enable[i] || field_1D0[i].size() < 1)
continue;
vec3 v22 = 0.0f;
for (vec3& j : field_1D0[i])
v22 += j;
float_t v29 = (float_t)(int64_t)field_1D0[i].size();
if (v29 < 0.0f)
v29 += (float_t)UINT64_MAX;
float_t v30 = 0.0f;
vec3 v31 = v22 * (1.0f / v29);
for (vec3& j : field_1D0[i]) {
vec3 v34 = v31 - j;
float_t v38 = fabsf(vec3::dot(v34, v3));
float_t v39 = fabsf(vec3::dot(v34, v86));
if (v39 >= v38)
v38 = v39;
if (v30 < v38)
v30 = v38;
}
field_1A8[i] = v31;
field_1C8[i] = v30;
}
if (num_light > 0) {
for (int32_t i = 0; i < 2; i++) {
if (!light_enable[i])
continue;
vec3 v53 = field_1A8[i] - direction * field_208;
float_t v51 = vec3::distance(view_point[i], v53);
float_t v54 = vec3::distance(interest[i], field_1A8[i]);
if (v51 > 0.1f || v54 > 0.1f) {
view_point[i] = v53;
interest[i] = field_1A8[i];
}
}
vec3 view_point = 0.0f;
vec3 interest = 0.0f;
int32_t count = 0;
for (int32_t i = 0; i < 2; i++) {
int32_t c = (int32_t)field_1D0[i].size();
view_point += this->view_point[i] * (float_t)c;
interest += this->interest[i] * (float_t)c;
count += c;
}
view_point_shared = view_point * (1.0f / (float_t)count);
interest_shared = interest * (1.0f / (float_t)count);
}
float_t v2 = 0.0f;
float_t v67 = max_def(field_1C8[0], field_1C8[1]);
separate = false;
shadow_range = v67 + 1.2f;
field_200[0] = 0;
field_200[1] = 1;
if (num_light >= 2) {
float_t v68 = 0.0f;
float_t v69 = 0.0f;
float_t v70 = 0.0f;
for (int32_t i = 0; i < 2; i++) {
if (!light_enable[i])
continue;
for (vec3& j : field_1D0[i]) {
vec3 v74 = j - interest_shared;
float_t v77 = vec3::dot(v74, v86);
if (v2 > v77)
v2 = v77;
else if (v69 < v77)
v69 = v77;
float_t v78 = vec3::dot(v74, v3);
if (v68 > v78)
v68 = v78;
else if (v70 < v78)
v70 = v78;
}
}
float_t v79 = -v2;
if (v79 < v69)
v79 = v69;
if (v79 < -v68)
v79 = -v68;
if (v79 < v70)
v79 = v70;
if (v79 > v67 + 1.2f) {
shadow_range = v67 + 2.4f;
separate = true;
}
else
shadow_range = v79 + 1.2f;
if (vec3::dot(field_1A8[0] - interest_shared, direction)
< vec3::dot(field_1A8[1] - interest_shared, direction)) {
field_200[1] = 0;
field_200[0] = 1;
}
}
}
for (prj::vector<vec3>& i : field_1D0)
i.clear();
}
void Shadow::free() {
for (RenderTexture& i : render_textures)
i.Free();
reset();
}
float_t Shadow::get_shadow_range() {
return shadow_range * shadow_range_factor;
}
int32_t Shadow::init() {
struct shadow_texture_init_params {
int32_t width;
int32_t height;
int32_t max_level;
GLenum color_format;
GLenum depth_format;
} init_params[] = {
{ 0x800, 0x800, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F },
{ 0x200, 0x200, 3, GL_RGBA8, GL_ZERO },
{ 0x200, 0x200, 3, GL_RGBA8, GL_ZERO },
{ 0x800, 0x800, 0, GL_R32F , GL_ZERO },
{ 0x800, 0x800, 0, GL_R32F , GL_ZERO },
{ 0x200, 0x200, 0, GL_R32F , GL_ZERO },
{ 0x200, 0x200, 0, GL_R32F , GL_ZERO },
};
shadow_texture_init_params* v3 = init_params;
for (int32_t i = 0; i < 7; i++, v3++)
if (render_textures[i].Init(v3->width, v3->height,
v3->max_level, v3->color_format, v3->depth_format) < 0)
return -1;
for (int32_t i = 0; i < 3; i++) {
gl_state_bind_texture_2d(render_textures[i].GetColorTex());
glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
static const vec4 border_color = 1.0f;
glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color);
}
gl_state_bind_texture_2d(0);
gl_state_get_error();
return 0;
}
void Shadow::reset() {
shadow_range = 1.2f;
shadow_range_factor = 1.0f;
for (int32_t i = 0; i < 2; i++) {
view_point[i] = 1.0f;
field_1C0[i] = 0.0f;
field_1C8[i] = 0.0f;
field_200[i] = i;
}
for (RenderTexture*& i : curr_render_textures)
i = 0;
view_mat[0] = mat4_identity;
view_mat[1] = mat4_identity;
blur_filter = BLUR_FILTER_9;
near_blur = 1;
field_2BC = 2;
far_blur = 1;
distance = 4.0f;
field_2C4 = 0.4f;
z_near = 0.1f;
z_far = 20.0f;
field_2D0 = 1.4f;
field_2D4 = 10000.0f;
field_2D8 = 80.0f;
field_2DC = 2.0f;
field_2E0 = 0.05f;
shadow_ambient = 0.4f;
num_light = 0;
direction = vec3(0.0f, -1.0f, -1.0f) * (1.0f / sqrtf(2.0f));
show_texture = false;
self_shadow = true;
separate = false;
field_208 = (z_far - z_near) * 0.5f;
}
Shadow* shadow_ptr_get() {
return *shadow_ptr;
return shadow_ptr;
}
HOOK(void, FASTCALL, shadow_ctrl, 0x0000000140502390) {
shadow_ptr_get()->ctrl();
}
HOOK(void, FASTCALL, Shadow__free, 0x00000001405E8350, Shadow* This) {
This->free();
}
void shadow_patch() {
INSTALL_HOOK(shadow_ctrl);
INSTALL_HOOK(Shadow__free);
}
+8
View File
@@ -57,11 +57,19 @@ struct Shadow {
bool blur_filter_enable[2];
bool separate;
void ctrl();
void free();
float_t get_shadow_range();
int32_t init();
void reset();
};
static_assert(sizeof(Shadow) == 0x2F8, "\"Shadow\" struct should have a size of 0x2F8");
extern void(FASTCALL* sub_1405E8A20)(Shadow* shad, int32_t index, vec3* pos);
extern void(FASTCALL* shadow_ptr_free)();
extern void(FASTCALL* shadow_ptr_init)();
extern Shadow* shadow_ptr_get();
extern void shadow_patch();