diff --git a/assets/Shaders/default.vert b/assets/Shaders/default.vert index fb37ec317..b594811c3 100644 --- a/assets/Shaders/default.vert +++ b/assets/Shaders/default.vert @@ -99,15 +99,8 @@ vec4 getLightResult() vec3 transformVector(vec3 initialVector, int matrixIndex) { - float X = (initialVector.x * modelMatricies[matrixIndex][0].x) + (initialVector.y * modelMatricies[matrixIndex][1].x) + (initialVector.z * modelMatricies[matrixIndex][2].x); - float Y = (initialVector.x * modelMatricies[matrixIndex][0].y) + (initialVector.y * modelMatricies[matrixIndex][1].y) + (initialVector.z * modelMatricies[matrixIndex][2].y); - float Z = (initialVector.x * modelMatricies[matrixIndex][0].z) + (initialVector.y * modelMatricies[matrixIndex][1].z) + (initialVector.z * modelMatricies[matrixIndex][2].z); - // ignoreW per DirectX - - X += 1 * modelMatricies[matrixIndex][3].x; - Y += 1 * modelMatricies[matrixIndex][3].y; - Z += 1 * modelMatricies[matrixIndex][3].z; - return vec3(X, Y, Z); + // ignoreW per DirectX by casting vec4 result to vec3 + return vec3(modelMatricies[matrixIndex] * vec4(initialVector, 1.0)); } void main() @@ -115,91 +108,26 @@ void main() vec3 pos = vec3(iPosition); oColor = iColor; - if(iMatrixChain.x != 0) - { - // unpack packed matrix indicies - int m0 = (iMatrixChain.x & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.x >> 16) & 0xff; - int m2 = (iMatrixChain.x & 0xff00) >> 8; - int m3 = (iMatrixChain.x & 0xff); - - if(m0 >=0 && m0 < 255) - { - pos = transformVector(pos, m0); - } - - if(m1 >=0 && m1 < 255) - { - pos = transformVector(pos, m1); - } - - if(m2 >=0 && m2 < 255) - { - pos = transformVector(pos, m2); - } - - if(m3 >=0 && m3 < 255) - { - pos = transformVector(pos, m3); - } - } - - if(iMatrixChain.y != 0) - { - // unpack packed matrix indicies - int m0 = (iMatrixChain.y & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.y >> 16) & 0xff; - int m2 = (iMatrixChain.y & 0xff00) >> 8; - int m3 = (iMatrixChain.y & 0xff); - - if(m0 >=0 && m0 < 255) - { - pos = transformVector(pos, m0); - } - - if(m1 >=0 && m1 < 255) - { - pos = transformVector(pos, m1); - } - - if(m2 >=0 && m2 < 255) - { - pos = transformVector(pos, m2); - } - - if(m3 >=0 && m3 < 255) - { - pos = transformVector(pos, m3); - } - } - - if(iMatrixChain.z != 0) - { - // unpack packed matrix indicies - int m0 = (iMatrixChain.z & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.z >> 16) & 0xff; - int m2 = (iMatrixChain.z & 0xff00) >> 8; - int m3 = (iMatrixChain.z & 0xff); - - if(m0 >=0 && m0 < 255) - { - pos = transformVector(pos, m0); - } - - if(m1 >=0 && m1 < 255) - { - pos = transformVector(pos, m1); - } - - if(m2 >=0 && m2 < 255) + // Unpack matrix indices from iMatrixChain (packed as 4 bytes per int component) + // and sequentially transform the vertex position. + for (int i = 0; i < 3; ++i) + { + int chain = iMatrixChain[i]; + // Skip empty (0) and default static/unanimated (-1) matrix chain components + if (chain != 0 && chain != -1) { - pos = transformVector(pos, m2); + // Extract individual matrix index bytes (0-254) + int m0 = (chain >> 24) & 0xff; + int m1 = (chain >> 16) & 0xff; + int m2 = (chain >> 8) & 0xff; + int m3 = chain & 0xff; + + // Transform using active bone matrix + if (m0 >= 0 && m0 < 255) pos = transformVector(pos, m0); + if (m1 >= 0 && m1 < 255) pos = transformVector(pos, m1); + if (m2 >= 0 && m2 < 255) pos = transformVector(pos, m2); + if (m3 >= 0 && m3 < 255) pos = transformVector(pos, m3); } - - if(m3 >=0 && m3 < 255) - { - pos = transformVector(pos, m3); - } } pos.z = -pos.z; diff --git a/assets/Shaders/picking.frag b/assets/Shaders/picking.frag index bafa4e2e3..3c19750d3 100644 --- a/assets/Shaders/picking.frag +++ b/assets/Shaders/picking.frag @@ -1,8 +1,9 @@ -#version 150 core +#version 150 core uniform int uObjectIndex; out vec4 fragColor; void main(void) { - fragColor.r = float(uObjectIndex); + // Write object index to red channel and write 0/1 to other channels to avoid undefined behavior + fragColor = vec4(float(uObjectIndex), 0.0, 0.0, 1.0); } diff --git a/assets/Shaders/rectangle.vert b/assets/Shaders/rectangle.vert index 49ece19d9..ff7b5a444 100644 --- a/assets/Shaders/rectangle.vert +++ b/assets/Shaders/rectangle.vert @@ -5,40 +5,22 @@ uniform vec2 uPoint; uniform vec2 uSize; uniform vec2 uCoordinates; out vec2 textureCoord; -vec4 viewPos = vec4(0,0,0,0); + +// Offset lookup table to map gl_VertexID to quad corners without branching +const vec2 offsets[6] = vec2[]( + vec2(0.0, 0.0), // Top-left + vec2(1.0, 0.0), // Top-right + vec2(1.0, 1.0), // Bottom-right + vec2(0.0, 0.0), // Top-left (second triangle) + vec2(0.0, 1.0), // Bottom-left + vec2(1.0, 1.0) // Bottom-right +); void main() { - if(gl_VertexID == 0) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0); - textureCoord = vec2(0,0); - } - else if (gl_VertexID == 1) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y, 0), 1.0); - textureCoord = vec2(uCoordinates.x,0); - } - else if (gl_VertexID == 2) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = uCoordinates; - } - else if (gl_VertexID == 3) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0); - textureCoord = vec2(0,0); - } - else if (gl_VertexID == 4) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = vec2(0, uCoordinates.y); - } - else if (gl_VertexID == 5) - { - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = uCoordinates; - } - + // Calculate vertex position and texture coordinates based on current vertex ID offsets + vec2 offset = offsets[gl_VertexID]; + vec4 viewPos = uCurrentModelViewMatrix * vec4(uPoint + offset * uSize, 0.0, 1.0); + textureCoord = offset * uCoordinates; gl_Position = uCurrentProjectionMatrix * viewPos; } diff --git a/assets/Shaders/shadow_depth.vert b/assets/Shaders/shadow_depth.vert index 18117b507..365b1a5dd 100644 --- a/assets/Shaders/shadow_depth.vert +++ b/assets/Shaders/shadow_depth.vert @@ -48,43 +48,26 @@ void main() { vec3 pos = iPosition; - if(iMatrixChain.x != 0) - { - int m0 = (iMatrixChain.x & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.x >> 16) & 0xff; - int m2 = (iMatrixChain.x & 0xff00) >> 8; - int m3 = (iMatrixChain.x & 0xff); - - if(m0 >=0 && m0 < 255) pos = transformVector(pos, m0); - if(m1 >=0 && m1 < 255) pos = transformVector(pos, m1); - if(m2 >=0 && m2 < 255) pos = transformVector(pos, m2); - if(m3 >=0 && m3 < 255) pos = transformVector(pos, m3); - } - - if(iMatrixChain.y != 0) - { - int m0 = (iMatrixChain.y & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.y >> 16) & 0xff; - int m2 = (iMatrixChain.y & 0xff00) >> 8; - int m3 = (iMatrixChain.y & 0xff); - - if(m0 >=0 && m0 < 255) pos = transformVector(pos, m0); - if(m1 >=0 && m1 < 255) pos = transformVector(pos, m1); - if(m2 >=0 && m2 < 255) pos = transformVector(pos, m2); - if(m3 >=0 && m3 < 255) pos = transformVector(pos, m3); - } + // Unpack matrix indices from iMatrixChain (packed as 4 bytes per int component) + // and sequentially transform the vertex position. + for (int i = 0; i < 3; ++i) + { + int chain = iMatrixChain[i]; + // Skip empty (0) and default static/unanimated (-1) matrix chain components + if (chain != 0 && chain != -1) + { + // Extract individual matrix index bytes (0-254) + int m0 = (chain >> 24) & 0xff; + int m1 = (chain >> 16) & 0xff; + int m2 = (chain >> 8) & 0xff; + int m3 = chain & 0xff; - if(iMatrixChain.z != 0) - { - int m0 = (iMatrixChain.z & (0xff << 24)) >> 24; - int m1 = (iMatrixChain.z >> 16) & 0xff; - int m2 = (iMatrixChain.z & 0xff00) >> 8; - int m3 = (iMatrixChain.z & 0xff); - - if(m0 >=0 && m0 < 255) pos = transformVector(pos, m0); - if(m1 >=0 && m1 < 255) pos = transformVector(pos, m1); - if(m2 >=0 && m2 < 255) pos = transformVector(pos, m2); - if(m3 >=0 && m3 < 255) pos = transformVector(pos, m3); + // Transform using active bone matrix + if (m0 >= 0 && m0 < 255) pos = transformVector(pos, m0); + if (m1 >= 0 && m1 < 255) pos = transformVector(pos, m1); + if (m2 >= 0 && m2 < 255) pos = transformVector(pos, m2); + if (m3 >= 0 && m3 < 255) pos = transformVector(pos, m3); + } } // OpenBVE explicitly negates Z for world geometry. diff --git a/assets/Shaders/text.vert b/assets/Shaders/text.vert index 8e64a5de8..ce83092d8 100644 --- a/assets/Shaders/text.vert +++ b/assets/Shaders/text.vert @@ -6,36 +6,22 @@ uniform vec2 uPoint; uniform vec2 uSize; uniform vec4 uAtlasLocation; out vec2 textureCoord; -vec4 viewPos = vec4(0,0,0,0); + +// Offset lookup table to map gl_VertexID to quad corners without branching +const vec2 offsets[6] = vec2[]( + vec2(0.0, 0.0), // Top-left + vec2(1.0, 0.0), // Top-right + vec2(1.0, 1.0), // Bottom-right + vec2(0.0, 0.0), // Top-left (second triangle) + vec2(0.0, 1.0), // Bottom-left + vec2(1.0, 1.0) // Bottom-right +); void main() { - switch(gl_VertexID) - { - case 0: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x, uAtlasLocation.y); - break; - case 1: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x + uAtlasLocation.z, uAtlasLocation.y); - break; - case 2: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x + uAtlasLocation.z, uAtlasLocation.y + uAtlasLocation.w); - break; - case 3: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x, uAtlasLocation.y); - break; - case 4: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x, uAtlasLocation.y + uAtlasLocation.w); - break; - case 5: - viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0); - textureCoord = vec2(uAtlasLocation.x + uAtlasLocation.z, uAtlasLocation.y + uAtlasLocation.w); - break; - } + // Calculate vertex position and UVs from atlas location using lookup offsets + vec2 offset = offsets[gl_VertexID]; + vec4 viewPos = uCurrentModelViewMatrix * vec4(uPoint + offset * uSize, 0.0, 1.0); + textureCoord = uAtlasLocation.xy + offset * uAtlasLocation.zw; gl_Position = uCurrentProjectionMatrix * viewPos; }