mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-09 07:35:41 +12:00
Rather than declaring a big C++ literal for these strings, they are now proper `.vert` and `.frag` files that will become embedded into the application at build-time. It also allows for clang-format to format the glsl files the same as our C++ code. CMake will also automatically track and re-embed the file if it detects that the glsl source files have changed since the last build. Ex, making a change to `opengl_display.frag` and compiling will automatically recompile and link the resource-target that it is associated with.
97 lines
No EOL
3.2 KiB
GLSL
97 lines
No EOL
3.2 KiB
GLSL
#version 410 core
|
|
|
|
layout(location = 0) in vec4 a_coords;
|
|
layout(location = 1) in vec4 a_quaternion;
|
|
layout(location = 2) in vec4 a_vertexColour;
|
|
layout(location = 3) in vec2 a_texcoord0;
|
|
layout(location = 4) in vec2 a_texcoord1;
|
|
layout(location = 5) in float a_texcoord0_w;
|
|
layout(location = 6) in vec3 a_view;
|
|
layout(location = 7) in vec2 a_texcoord2;
|
|
|
|
out vec3 v_normal;
|
|
out vec3 v_tangent;
|
|
out vec3 v_bitangent;
|
|
out vec4 v_colour;
|
|
out vec3 v_texcoord0;
|
|
out vec2 v_texcoord1;
|
|
out vec3 v_view;
|
|
out vec2 v_texcoord2;
|
|
flat out vec4 v_textureEnvColor[6];
|
|
flat out vec4 v_textureEnvBufferColor;
|
|
|
|
out float gl_ClipDistance[2];
|
|
|
|
// TEV uniforms
|
|
uniform uint u_textureEnvColor[6];
|
|
uniform uint u_picaRegs[0x200 - 0x48];
|
|
|
|
// Helper so that the implementation of u_pica_regs can be changed later
|
|
uint readPicaReg(uint reg_addr) { return u_picaRegs[reg_addr - 0x48]; }
|
|
|
|
vec4 abgr8888ToVec4(uint abgr) {
|
|
const float scale = 1.0 / 255.0;
|
|
|
|
return scale * vec4(float(abgr & 0xffu), float((abgr >> 8) & 0xffu), float((abgr >> 16) & 0xffu), float(abgr >> 24));
|
|
}
|
|
|
|
vec3 rotateVec3ByQuaternion(vec3 v, vec4 q) {
|
|
vec3 u = q.xyz;
|
|
float s = q.w;
|
|
return 2.0 * dot(u, v) * u + (s * s - dot(u, u)) * v + 2.0 * s * cross(u, v);
|
|
}
|
|
|
|
// Convert an arbitrary-width floating point literal to an f32
|
|
float decodeFP(uint hex, uint E, uint M) {
|
|
uint width = M + E + 1u;
|
|
uint bias = 128u - (1u << (E - 1u));
|
|
uint exponent = (hex >> M) & ((1u << E) - 1u);
|
|
uint mantissa = hex & ((1u << M) - 1u);
|
|
uint sign = (hex >> (E + M)) << 31u;
|
|
|
|
if ((hex & ((1u << (width - 1u)) - 1u)) != 0) {
|
|
if (exponent == (1u << E) - 1u)
|
|
exponent = 255u;
|
|
else
|
|
exponent += bias;
|
|
hex = sign | (mantissa << (23u - M)) | (exponent << 23u);
|
|
} else {
|
|
hex = sign;
|
|
}
|
|
|
|
return uintBitsToFloat(hex);
|
|
}
|
|
|
|
void main() {
|
|
gl_Position = a_coords;
|
|
v_colour = a_vertexColour;
|
|
|
|
// Flip y axis of UVs because OpenGL uses an inverted y for texture sampling compared to the PICA
|
|
v_texcoord0 = vec3(a_texcoord0.x, 1.0 - a_texcoord0.y, a_texcoord0_w);
|
|
v_texcoord1 = vec2(a_texcoord1.x, 1.0 - a_texcoord1.y);
|
|
v_texcoord2 = vec2(a_texcoord2.x, 1.0 - a_texcoord2.y);
|
|
v_view = a_view;
|
|
|
|
v_normal = normalize(rotateVec3ByQuaternion(vec3(0.0, 0.0, 1.0), a_quaternion));
|
|
v_tangent = normalize(rotateVec3ByQuaternion(vec3(1.0, 0.0, 0.0), a_quaternion));
|
|
v_bitangent = normalize(rotateVec3ByQuaternion(vec3(0.0, 1.0, 0.0), a_quaternion));
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
v_textureEnvColor[i] = abgr8888ToVec4(u_textureEnvColor[i]);
|
|
}
|
|
|
|
v_textureEnvBufferColor = abgr8888ToVec4(readPicaReg(0xFD));
|
|
|
|
// Parse clipping plane registers
|
|
// The plane registers describe a clipping plane in the form of Ax + By + Cz + D = 0
|
|
// With n = (A, B, C) being the normal vector and D being the origin point distance
|
|
// Therefore, for the second clipping plane, we can just pass the dot product of the clip vector and the input coordinates to gl_ClipDistance[1]
|
|
vec4 clipData = vec4(
|
|
decodeFP(readPicaReg(0x48) & 0xffffffu, 7, 16), decodeFP(readPicaReg(0x49) & 0xffffffu, 7, 16),
|
|
decodeFP(readPicaReg(0x4A) & 0xffffffu, 7, 16), decodeFP(readPicaReg(0x4B) & 0xffffffu, 7, 16)
|
|
);
|
|
|
|
// There's also another, always-on clipping plane based on vertex z
|
|
gl_ClipDistance[0] = -a_coords.z;
|
|
gl_ClipDistance[1] = dot(clipData, a_coords);
|
|
} |