mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
40e2f113e6
## Problem OpenGOAL uses OpenGL 4.3. Apple stopped upgrading OpenGL after 4.1, so the way OpenGOAL currently works will never be playable on Macs using OpenGL. ## Solution Luckily, downgrading to OpenGL 4.1 is not a huge change (at least it doesn't seem like it to my untrained eyes). ## Changes * set hints for OpenGL 4.1 instead of 4.3 for __APPLE__ * skip the OpenGL debugging callback setup for macOS (requires 4.3) * bump down the version string for all shaders * stop using the `binding` layout qualifier in shader code * move the `flat` qualifier first (not sure if this is a 4.1 thing or just Macs being more strict) * don't mix signed and unsigned ints in shaders (not sure if this is a 4.1 thing or just Macs being more strict) * add some hacky CPP to the Shader constructor for binding texture units and bones buffers based on variable names in the shader code ## Results ![image](https://github.com/open-goal/jak-project/assets/33322/dd487c2a-61ac-4e36-a595-976204302977) ![Skärmavbild 2023-07-07 kl 13 10 30](https://github.com/open-goal/jak-project/assets/33322/7976d411-0604-4046-9e8a-123106cedf57) ![Skärmavbild 2023-07-07 kl 13 13 48](https://github.com/open-goal/jak-project/assets/33322/78db4f0c-da31-4889-995c-8f54e56deb5c)
178 lines
5.2 KiB
GLSL
178 lines
5.2 KiB
GLSL
#version 410 core
|
|
|
|
layout (location = 0) in vec4 xyz_sx;
|
|
layout (location = 1) in vec4 quat_sy;
|
|
layout (location = 2) in vec4 rgba;
|
|
layout (location = 3) in uvec2 flags_matrix;
|
|
layout (location = 4) in uvec4 tex_info_in;
|
|
|
|
uniform vec4 hvdf_offset;
|
|
uniform mat4 camera;
|
|
uniform mat4 hud_matrix;
|
|
uniform vec4 hud_hvdf_offset;
|
|
uniform vec4 hud_hvdf_user[75];
|
|
uniform float pfog0;
|
|
uniform float fog_min;
|
|
uniform float fog_max;
|
|
uniform float min_scale;
|
|
uniform float max_scale;
|
|
uniform float deg_to_rad;
|
|
uniform float inv_area;
|
|
uniform vec4 basis_x;
|
|
uniform vec4 basis_y;
|
|
uniform vec4 xy_array[8];
|
|
uniform vec4 xyz_array[4];
|
|
uniform vec4 st_array[4];
|
|
|
|
flat out vec4 fragment_color;
|
|
out vec3 tex_coord;
|
|
flat out uvec2 tex_info;
|
|
|
|
vec4 matrix_transform(mat4 mtx, vec3 pt) {
|
|
return mtx[3]
|
|
+ mtx[0] * pt.x
|
|
+ mtx[1] * pt.y
|
|
+ mtx[2] * pt.z;
|
|
}
|
|
|
|
mat3 sprite_quat_to_rot(vec3 quat) {
|
|
mat3 result;
|
|
float qr = sqrt(abs(1.0 - (quat.x * quat.x + quat.y * quat.y + quat.z * quat.z)));
|
|
result[0][0] = 1.0 - 2.0 * (quat.y * quat.y + quat.z * quat.z);
|
|
result[1][0] = 2.0 * (quat.x * quat.y - quat.z * qr);
|
|
result[2][0] = 2.0 * (quat.x * quat.z + quat.y * qr);
|
|
result[0][1] = 2.0 * (quat.x * quat.y + quat.z * qr);
|
|
result[1][1] = 1.0 - 2.0 * (quat.x * quat.x + quat.z * quat.z);
|
|
result[2][1] = 2.0 * (quat.y * quat.z - quat.x * qr);
|
|
result[0][2] = 2.0 * (quat.x * quat.z - quat.y * qr);
|
|
result[1][2] = 2.0 * (quat.y * quat.z + quat.x * qr);
|
|
result[2][2] = 1.0 - 2.0 * (quat.x * quat.x + quat.y * quat.y);
|
|
return result;
|
|
}
|
|
|
|
vec4 sprite_transform2(vec3 root, vec4 off, mat3 sprite_rot, float sx, float sy) {
|
|
vec3 pos = root;
|
|
|
|
vec3 offset = sprite_rot[0] * off.x * sx + sprite_rot[1] * off.y + sprite_rot[2] * off.z * sy;
|
|
|
|
pos += offset;
|
|
vec4 transformed_pos = -matrix_transform(camera, pos);
|
|
float Q = pfog0 / transformed_pos.w;
|
|
transformed_pos.xyz *= Q;
|
|
transformed_pos.xyz += hvdf_offset.xyz;
|
|
|
|
return transformed_pos;
|
|
}
|
|
|
|
void main() {
|
|
|
|
// STEP 1: UNPACK DATA AND CREATE READABLE VARIABLES
|
|
|
|
vec3 position = xyz_sx.xyz;
|
|
float sx = xyz_sx.w;
|
|
float sy = quat_sy.w;
|
|
fragment_color = rgba;
|
|
uint vert_id = tex_info_in.z;
|
|
uint rendermode = tex_info_in.w; // 2D, HUD, 3D
|
|
vec3 quat = quat_sy.xyz;
|
|
uint matrix = flags_matrix.y;
|
|
|
|
vec4 transformed;
|
|
|
|
// STEP 2: perspective transform for distance
|
|
vec4 transformed_pos_vf02 = matrix_transform(rendermode == 2 ? hud_matrix : camera, position);
|
|
float Q = pfog0 / transformed_pos_vf02.w;
|
|
|
|
|
|
// STEP 3: fade out sprite!
|
|
vec4 scales_vf01 = xyz_sx; // now used for something else.
|
|
scales_vf01.z = sy; // start building the scale vector
|
|
scales_vf01.zw *= Q; // sy sx
|
|
scales_vf01.x = scales_vf01.z; // = sy
|
|
scales_vf01.x *= scales_vf01.w; // x = sx * sy
|
|
scales_vf01.x *= inv_area; // x = sx * sy * inv_area (area ratio)
|
|
fragment_color.w *= min(scales_vf01.x, 1.0); // is this right? doesn't this stall??
|
|
|
|
|
|
// STEP 4: actual vertex transformation
|
|
if (rendermode == 3) { // 3D sprites
|
|
|
|
mat3 rot = sprite_quat_to_rot(quat);
|
|
transformed = sprite_transform2(position, xyz_array[vert_id], rot, sx, sy);
|
|
|
|
} else if (rendermode == 1) { // 2D sprites
|
|
|
|
transformed_pos_vf02.xyz *= Q;
|
|
vec4 offset_pos_vf10 = transformed_pos_vf02 + hvdf_offset;
|
|
offset_pos_vf10.w = max(offset_pos_vf10.w, fog_min);
|
|
|
|
/* transformed_pos_vf02.w = offset_pos_vf10.w - fog_max;
|
|
int fge = matrix == 0;
|
|
if (transformed_pos_vf02.w != 0) {
|
|
fge = false;
|
|
} */
|
|
|
|
scales_vf01.z = clamp(scales_vf01.z, min_scale, max_scale);
|
|
scales_vf01.w = clamp(scales_vf01.w, min_scale, max_scale);
|
|
|
|
quat.z *= deg_to_rad;
|
|
float sp_sin = sin(quat.z);
|
|
float sp_cos = cos(quat.z);
|
|
|
|
vec4 xy0_vf19 = xy_array[vert_id + flags_matrix.x];
|
|
vec4 vf12_rotated = (basis_x * sp_cos) - (basis_y * sp_sin);
|
|
vec4 vf13_rotated_trans = (basis_x * sp_sin) + (basis_y * sp_cos);
|
|
|
|
vf12_rotated *= scales_vf01.w;
|
|
vf13_rotated_trans *= scales_vf01.z;
|
|
|
|
transformed = offset_pos_vf10 + vf12_rotated * xy0_vf19.x + vf13_rotated_trans * xy0_vf19.y;
|
|
|
|
} else if (rendermode == 2) { // hud sprites
|
|
|
|
transformed_pos_vf02.xyz *= Q;
|
|
vec4 offset_pos_vf10 = transformed_pos_vf02 + (matrix == 0 ? hud_hvdf_offset : hud_hvdf_user[matrix - 1]);
|
|
|
|
// NOTE: no max scale for hud
|
|
scales_vf01.z = max(scales_vf01.z, min_scale);
|
|
scales_vf01.w = max(scales_vf01.w, min_scale);
|
|
|
|
quat.z *= deg_to_rad;
|
|
float sp_sin = sin(quat.z);
|
|
float sp_cos = cos(quat.z);
|
|
|
|
vec4 xy0_vf19 = xy_array[vert_id + flags_matrix.x];
|
|
vec4 vf12_rotated = (basis_x * sp_cos) - (basis_y * sp_sin);
|
|
vec4 vf13_rotated_trans = (basis_x * sp_sin) + (basis_y * sp_cos);
|
|
|
|
vf12_rotated *= scales_vf01.w;
|
|
vf13_rotated_trans *= scales_vf01.z;
|
|
|
|
transformed = offset_pos_vf10 + vf12_rotated * xy0_vf19.x + vf13_rotated_trans * xy0_vf19.y;
|
|
|
|
}
|
|
|
|
tex_coord = st_array[vert_id].xyz;
|
|
|
|
|
|
// STEP 5: final adjustments
|
|
// correct xy offset
|
|
transformed.xy -= (2048.);
|
|
// correct z scale
|
|
transformed.z /= (8388608);
|
|
transformed.z -= 1;
|
|
// correct xy scale
|
|
transformed.x /= (256);
|
|
transformed.y /= -(128);
|
|
// hack
|
|
transformed.xyz *= transformed.w;
|
|
// scissoring area adjust
|
|
transformed.y *= SCISSOR_ADJUST * HEIGHT_SCALE;
|
|
gl_Position = transformed;
|
|
|
|
fragment_color *= 2;
|
|
fragment_color.w *= 2;
|
|
|
|
tex_info = tex_info_in.xy;
|
|
}
|