jak-project/game/graphics/opengl_renderer/shaders/sprite3_3d.vert
Fabian Bergström 40e2f113e6
Make Jak1 playable on macOS (intel) (#2811)
## 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)
2023-07-08 11:53:43 -04:00

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;
}