Files
jak-project/game/graphics/opengl_renderer/shaders/collision.vert
T
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

122 lines
3.5 KiB
GLSL

#version 410 core
layout (location = 0) in vec3 position_in;
layout (location = 1) in uint flags;
layout (location = 2) in vec3 normal_in;
layout (location = 3) in uint pat;
uniform vec4 hvdf_offset;
uniform mat4 camera;
uniform vec4 camera_position;
uniform float fog_constant;
uniform float fog_min;
uniform float fog_max;
uniform int wireframe;
uniform int mode;
uniform int version;
out vec4 fragment_color;
const int PAT_MOD_COUNT = 3;
const int PAT_EVT_COUNT = 7;
const int PAT_MAT_COUNT = 23;
uniform uint collision_mode_mask[(PAT_MOD_COUNT + 31) / 32];
uniform uint collision_event_mask[(PAT_EVT_COUNT + 31) / 32];
uniform uint collision_material_mask[(PAT_MAT_COUNT + 31) / 32];
uniform uint collision_skip_mask;
const int MODE_NONE = 0;
const int MODE_MODE = 1;
const int MODE_EVENT = 2;
const int MODE_MATERIAL = 3;
uint pat_get_mode(uint p) { return version == 2 ? (p >> 7) & 0x7u : (p >> 3) & 0x7u; }
uint pat_get_material(uint p) { return version == 2 ? (p >> 10) & 0x3fu : (p >> 6) & 0x3fu; }
uint pat_get_event(uint p) { return version == 2 ? (p >> 18) & 0x3fu : (p >> 14) & 0x3fu; }
bool logtest(uint a, uint b) { return (a & b) != 0; }
bool logtesta(uint a, uint b) { return (a & b) == b; }
layout(std140) uniform PatColors {
vec4 pat_mode_colors[0x8];
vec4 pat_material_colors[0x40];
vec4 pat_event_colors[0x40];
};
void main() {
// Step 3, the camera transform
vec4 transformed = -camera[3].xyzw;
transformed += -camera[0] * position_in.x;
transformed += -camera[1] * position_in.y;
transformed += -camera[2] * position_in.z;
// compute Q
float Q = fog_constant / transformed[3];
// perspective divide!
transformed.xyz *= Q;
// offset
transformed.xyz += hvdf_offset.xyz;
// 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;
gl_Position = transformed;
// scissoring area adjust
gl_Position.y *= SCISSOR_ADJUST;
// wireframe check
if (wireframe == 0) {
// lighting check
vec3 to_cam = camera_position.xyz - position_in;
float dist_from_cam = length(to_cam);
vec3 to_cam_n = to_cam / dist_from_cam;
float cam_dot = abs(dot(to_cam_n, normal_in));
// base colors
fragment_color = vec4(0.5, 0.5, 0.5, 1);
fragment_color.xyz *= (pow(cam_dot, 2) * 0.5 + 0.5);
// pat checks
uint pMode = pat_get_mode(pat);
uint pMat = pat_get_material(pat);
uint pEvent = pat_get_event(pat);
if (logtest(collision_mode_mask[pMode/32], 1 << (pMode & 0x1fu)) &&
logtest(collision_material_mask[pMat/32], 1 << (pMat & 0x1fu)) &&
logtest(collision_event_mask[pEvent/32], 1 << (pEvent & 0x1fu)) &&
logtesta(collision_skip_mask, pat)) {
// fancy colors
if (mode == MODE_MODE) {
fragment_color.rgb *= pat_mode_colors[pMode].rgb;
} else if (mode == MODE_EVENT) {
fragment_color.rgb *= pat_event_colors[pEvent].rgb;
} else if (mode == MODE_MATERIAL) {
fragment_color.rgb *= pat_material_colors[pMat].rgb;
} else {
fragment_color = vec4((normal_in + 1)*.5, 1);
fragment_color.rgb *= (pow(cam_dot, 2) * 0.5 + 0.5);
}
if (fragment_color.r < 0 || fragment_color.g < 0 || fragment_color.b < 0) {
fragment_color.rgb = vec3(1, 0, 1);
}
} else {
// filtered out. goodbye!
fragment_color.rgba = vec4(0);
}
} else {
fragment_color = vec4(0.12, 0.12, 0.12, 0.5);
}
}