mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-12 17:18:10 +03:00
293 lines
9.9 KiB
C++
293 lines
9.9 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "shader_table.hpp"
|
|
#include "../KKdLib/mat.hpp"
|
|
#include "gl.hpp"
|
|
|
|
enum uniform_name {
|
|
U_NONE = 0x00,
|
|
U01 = 0x01,
|
|
U_ALPHA_TEST = 0x02,
|
|
U_ANISO = 0x03,
|
|
U_AET_BACK = 0x04,
|
|
U_TEXTURE_BLEND = 0x05,
|
|
U_CHARA_COLOR = 0x06,
|
|
U_CLIP_PLANE = 0x07,
|
|
U08 = 0x08,
|
|
U_DEPTH_PEEL = 0x09,
|
|
U0A = 0x0A,
|
|
U0B = 0x0B,
|
|
U_ALPHA_BLEND = 0x0C,
|
|
U_RIPPLE_EMIT = 0x0D,
|
|
U_ESM_FILTER = 0x0E,
|
|
U_EXPOSURE = 0x0F,
|
|
U_SCENE_FADE = 0x10,
|
|
U_FADE = 0x11,
|
|
U12 = 0x12,
|
|
U_FLARE = 0x13,
|
|
U_FOG_HEIGHT = 0x14,
|
|
U_FOG = 0x15,
|
|
U16 = 0x16,
|
|
U_GAUSS = 0x17,
|
|
U18 = 0x18,
|
|
U_IMAGE_FILTER = 0x19,
|
|
U_INSTANCE = 0x1A,
|
|
U_TONE_CURVE = 0x1B,
|
|
U_LIGHT_PROJ = 0x1C,
|
|
U_MAGNIFY = 0x1D,
|
|
U_MEMBRANE = 0x1E,
|
|
U_MLAA = 0x1F,
|
|
U20 = 0x20,
|
|
U_MORPH_COLOR = 0x21,
|
|
U_MORPH = 0x22,
|
|
U_MOVIE = 0x23,
|
|
U24 = 0x24,
|
|
U25 = 0x25,
|
|
U26 = 0x26,
|
|
U_NPR = 0x27,
|
|
U_LIGHT_1 = 0x28,
|
|
U_REFLECT = 0x29,
|
|
U_REDUCE = 0x2A,
|
|
U_SELF_SHADOW = 0x2B,
|
|
U_SHADOW = 0x2C,
|
|
U2D = 0x2D,
|
|
U2E = 0x2E,
|
|
U_SHOW_VECTOR = 0x2F,
|
|
U_BONE_MAT = 0x30,
|
|
U_SNOW_PARTICLE = 0x31,
|
|
U_SPECULAR_IBL = 0x32,
|
|
U_SPRITE_BLEND = 0x33,
|
|
U_TEX_0_TYPE = 0x34,
|
|
U_TEX_1_TYPE = 0x35,
|
|
U_SSS_FILTER = 0x36,
|
|
U37 = 0x37,
|
|
U_STAR = 0x38,
|
|
U_TEXTURE_COUNT = 0x39,
|
|
U_ENV_MAP = 0x3A,
|
|
U_RIPPLE = 0x3B,
|
|
U_TRANSLUCENCY = 0x3C,
|
|
U_NORMAL = 0x3D,
|
|
U_TRANSPARENCY = 0x3E,
|
|
U_WATER_REFLECT = 0x3F,
|
|
U40 = 0x40,
|
|
U41 = 0x41,
|
|
U_LIGHT_0 = 0x42,
|
|
U_SPECULAR = 0x43,
|
|
U_TONE_MAP = 0x44,
|
|
U45 = 0x45,
|
|
U_MAX = 0x46,
|
|
U_INVALID = 0xFFFFFFFF,
|
|
};
|
|
|
|
struct uniform_array {
|
|
int32_t array[70];
|
|
};
|
|
|
|
extern uniform_array* uniform;
|
|
|
|
shader* shaders = (shader*)0x000000014CC57C10;
|
|
shader_table_struct* shader_table = (shader_table_struct*)0x0000000140A41D20;
|
|
shader_bind_func* shader_name_bind_func_table = (shader_bind_func*)0x0000000140A40F50;
|
|
uniform_array* uniform = (uniform_array*)0x000000014CC57AF0;
|
|
int32_t* current_vp = (int32_t*)0x000000014CC587B0;
|
|
int32_t* current_fp = (int32_t*)0x000000014CC587B4;
|
|
|
|
#define GL_VERTEX_PROGRAM_ARB 0x8620
|
|
#define GL_FRAGMENT_PROGRAM_ARB 0x8804
|
|
typedef void (GLAPIENTRY* PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
|
|
typedef void (GLAPIENTRY* PFNGLPROGRAMLOCALPARAMETER4FARBPROC)
|
|
(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
|
typedef void (GLAPIENTRY* PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs);
|
|
|
|
void FASTCALL shader_set(shader_enum name) {
|
|
if (name == shader_enum::SHADER_FFP) {
|
|
shader_unbind();
|
|
return;
|
|
}
|
|
|
|
PFNGLPROGRAMLOCALPARAMETER4FARBPROC _glProgramEnvParameter4fARB
|
|
= *(PFNGLPROGRAMLOCALPARAMETER4FARBPROC*)0x00000001411A4A88;
|
|
_glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 24,
|
|
(float_t)uniform->array[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f);
|
|
|
|
shader* shad = &shaders[(size_t)name];
|
|
void (FASTCALL * bind_func)(shader*) = (void (*)(shader*))shad->bind_func;
|
|
if (bind_func)
|
|
bind_func(shad);
|
|
else
|
|
shader_bind(shad, shad->subs->sub_name);
|
|
}
|
|
|
|
void FASTCALL shader_bind_blinn(shader* shad) {
|
|
shader_bind(shad, uniform->array[U_NORMAL]
|
|
? shader_sub_enum::BLINN_FRAG : shader_sub_enum::BLINN_VERT);
|
|
}
|
|
|
|
void FASTCALL shader_bind_cloth(shader* shad) {
|
|
shader_bind(shad, uniform->array[U_NPR] ? shader_sub_enum::CLOTH_NPR1
|
|
: (uniform->array[U_ANISO] ? shader_sub_enum::CLOTH_ANISO : shader_sub_enum::CLOTH_DEFAULT));
|
|
}
|
|
|
|
void FASTCALL shader_bind_hair(shader* shad) {
|
|
shader_bind(shad, uniform->array[U_NPR] ? shader_sub_enum::HAIR_NPR1
|
|
: (uniform->array[U_ANISO] ? shader_sub_enum::HAIR_ANISO : shader_sub_enum::HAIR_DEFAULT));
|
|
}
|
|
|
|
void FASTCALL shader_bind_membrane(shader* shad) {
|
|
uniform->array[U_MEMBRANE] = 3;
|
|
if (shader_bind(shad, shader_sub_enum::MEMBRANE) < 0)
|
|
return;
|
|
|
|
uint32_t(FASTCALL * sub_140192E00)() = (uint32_t(*)())0x0000000140192E00;
|
|
uint32_t v1 = sub_140192E00();
|
|
mat4 mat = mat4_identity;
|
|
mat4_rotate_x_mult(&mat, (float_t)((v1 & 0x1FF) * (M_PI / 256.0)), &mat);
|
|
mat4_rotate_z_mult(&mat, (float_t)((v1 % 0x168) * (M_PI / 180.0)), &mat);
|
|
|
|
vec4 vec = { 1.0f, 0.0f, 0.0f, 0.0f };
|
|
mat4_mult_vec(&mat, &vec, &vec);
|
|
|
|
PFNGLPROGRAMLOCALPARAMETER4FARBPROC _glProgramLocalParameter4fARB
|
|
= *(PFNGLPROGRAMLOCALPARAMETER4FARBPROC*)0x00000001411A4AA8;
|
|
_glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, vec.x, vec.y, vec.z, 0.0);
|
|
}
|
|
|
|
void FASTCALL shader_bind_eye_ball(shader* shader) {
|
|
uniform->array[U18] = 0;
|
|
if (shader_bind(&shaders[(size_t)shader_enum::_GLASEYE], shader_sub_enum::GLASS_EYE) >= 0) {
|
|
float_t* glass_eye = (float_t*)0x0000000140CA2D70;
|
|
void (FASTCALL * glass_eye_calc)(float_t * glass_eye) = (void (*)(float_t*))0x00000001405E53D0;
|
|
void (FASTCALL * glass_eye_set)(float_t * glass_eye) = (void (*)(float_t*))0x00000001405E4750;
|
|
glass_eye_calc(glass_eye);
|
|
glass_eye_set(glass_eye);
|
|
}
|
|
}
|
|
|
|
void FASTCALL shader_bind_tone_map(shader* shader) {
|
|
shader_bind(shader, uniform->array[U_NPR] == 1
|
|
? shader_sub_enum::TONEMAP_NPR1 : shader_sub_enum::TONEMAP);
|
|
}
|
|
|
|
int32_t FASTCALL shader_bind(shader* shader, shader_sub_enum name) {
|
|
int32_t num_sub = shader->num_sub;
|
|
int32_t subshader_index = 0;
|
|
if (num_sub < 1)
|
|
return -1;
|
|
|
|
for (shader_sub* i = shader->subs; i->sub_name != name; i++) {
|
|
subshader_index++;
|
|
if (subshader_index >= num_sub)
|
|
return -1;
|
|
}
|
|
|
|
shader_sub* subshader = &shader->subs[subshader_index];
|
|
if (!subshader)
|
|
return -1;
|
|
|
|
int32_t use_unis_count = shader->num_uniform;
|
|
int32_t unival_vp_curr = 1;
|
|
int32_t unival_fp_curr = 1;
|
|
int32_t unival_vp = 0;
|
|
int32_t unival_fp = 0;
|
|
if (use_unis_count > 0) {
|
|
int32_t* vp_unival_max = subshader->vp_unival_max;
|
|
int32_t* fp_unival_max = subshader->fp_unival_max;
|
|
for (size_t i = 0; i < use_unis_count; i++) {
|
|
int32_t unival = uniform->array[shader->use_uniform[i]];
|
|
unival_vp += unival_vp_curr * min(unival, vp_unival_max[i]);
|
|
unival_fp += unival_fp_curr * min(unival, fp_unival_max[i]);
|
|
unival_vp_curr *= vp_unival_max[i] + 1;
|
|
unival_fp_curr *= fp_unival_max[i] + 1;
|
|
}
|
|
}
|
|
|
|
int32_t vp = subshader->vp[unival_vp];
|
|
int32_t fp = subshader->fp[unival_fp];
|
|
|
|
PFNGLBINDPROGRAMARBPROC _glBindProgramARB = *(PFNGLBINDPROGRAMARBPROC*)0x00000001411A4A60;
|
|
if (*current_vp != vp) {
|
|
_glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vp);
|
|
*current_vp = vp;
|
|
}
|
|
|
|
if (*current_fp != fp) {
|
|
_glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fp);
|
|
*current_fp = fp;
|
|
}
|
|
|
|
_glEnable(GL_VERTEX_PROGRAM_ARB);
|
|
_glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
|
return 0;
|
|
}
|
|
|
|
void FASTCALL shader_unbind() {
|
|
if (current_vp)
|
|
_glDisable(GL_VERTEX_PROGRAM_ARB);
|
|
if (current_fp)
|
|
_glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
|
current_fp = 0;
|
|
current_vp = 0;
|
|
}
|
|
|
|
void FASTCALL shader_load_all_shaders() {
|
|
PFNGLGENPROGRAMSARBPROC _glGenProgramsARB = *(PFNGLGENPROGRAMSARBPROC*)0x00000001411A4A70;
|
|
void (FASTCALL * shader_load_program_file)(GLuint program, const char* file_name, bool vertex_program)
|
|
= (void (*)(GLuint, const char*, bool))0x00000001405E52D0;
|
|
|
|
shader_table_struct* shaders_table = &shader_table[(int32_t)shader_enum::_BLINN];
|
|
shader* shader = &shaders[(int32_t)shader_enum::_BLINN];
|
|
int32_t curr_shader = (int32_t)shader_enum::SHADER_END - 1;
|
|
do {
|
|
shader->name = shaders_table->name;
|
|
shader->name_enum = shaders_table->name_enum;
|
|
shader->num_sub = shaders_table->num_sub;
|
|
int32_t num_sub = shaders_table->num_sub;
|
|
void* v9 = force_malloc(sizeof(shader_sub) * num_sub + 8);
|
|
*(int64_t*)v9 = num_sub;
|
|
|
|
const shader_sub_table_struct* sub = shaders_table->sub;
|
|
shader_sub* subs = (shader_sub*)((char*)v9 + 8);
|
|
for (int32_t i = 0; i < num_sub; i++)
|
|
subs[i] = { };
|
|
|
|
shader->subs = subs;
|
|
shader->num_uniform = shaders_table->num_uniform;
|
|
shader->use_uniform = shaders_table->use_uniform;
|
|
|
|
for (int32_t i = 0; i < num_sub; i++, sub++, subs++) {
|
|
subs->sub_name = sub->sub_name;
|
|
subs->vp_unival_max = (int32_t*)sub->vp_unival_max;
|
|
subs->fp_unival_max = (int32_t*)sub->fp_unival_max;
|
|
subs->num_vp = sub->num_vp;
|
|
subs->num_fp = sub->num_fp;
|
|
subs->vp = force_malloc_s(int32_t, sub->num_vp);
|
|
subs->fp = force_malloc_s(int32_t, sub->num_fp);
|
|
|
|
_glGenProgramsARB(sub->num_vp, (GLuint*)subs->vp);
|
|
_glGenProgramsARB(sub->num_fp, (GLuint*)subs->fp);
|
|
|
|
for (int32_t j = 0; j < sub->num_vp; j++)
|
|
shader_load_program_file(subs->vp[j], sub->vp[j], true);
|
|
|
|
for (int32_t j = 0; j < sub->num_fp; j++)
|
|
shader_load_program_file(subs->fp[j], sub->fp[j], false);
|
|
}
|
|
shader->bind_func = 0;
|
|
|
|
shader_bind_func* bind_func_table = shader_name_bind_func_table;
|
|
shader_enum bind_func_name = shader_enum::_BLINN;
|
|
while (shader->name_enum != bind_func_name) {
|
|
bind_func_name = (++bind_func_table)->name;
|
|
if (bind_func_table->name == shader_enum::SHADER_END)
|
|
break;
|
|
}
|
|
shader->bind_func = bind_func_table->bind_func;
|
|
shader++;
|
|
shaders_table++;
|
|
curr_shader--;
|
|
} while (curr_shader);
|
|
}
|