fedora
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 qt_TexCoord0;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D source;
|
||||
|
||||
layout(std140, binding = 0) uniform buf {
|
||||
mat4 qt_Matrix;
|
||||
float qt_Opacity;
|
||||
// Custom properties with non-conflicting names
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
float sourceWidth;
|
||||
float sourceHeight;
|
||||
float cornerRadius;
|
||||
float imageOpacity;
|
||||
int fillMode;
|
||||
} ubuf;
|
||||
|
||||
// Function to calculate the signed distance from a point to a rounded box
|
||||
float roundedBoxSDF(vec2 centerPos, vec2 boxSize, float radius) {
|
||||
vec2 d = abs(centerPos) - boxSize + radius;
|
||||
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0) - radius;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Get size from uniforms
|
||||
vec2 itemSize = vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 sourceSize = vec2(ubuf.sourceWidth, ubuf.sourceHeight);
|
||||
float cornerRadius = ubuf.cornerRadius;
|
||||
float itemOpacity = ubuf.imageOpacity;
|
||||
int fillMode = ubuf.fillMode;
|
||||
|
||||
// Work in pixel space for accurate rounded rectangle calculation
|
||||
vec2 pixelPos = qt_TexCoord0 * itemSize;
|
||||
|
||||
// Calculate UV coordinates based on fill mode
|
||||
vec2 imageUV = qt_TexCoord0;
|
||||
|
||||
// fillMode constants from Qt:
|
||||
// Image.Stretch = 0
|
||||
// Image.PreserveAspectFit = 1
|
||||
// Image.PreserveAspectCrop = 2
|
||||
// Image.Tile = 3
|
||||
// Image.TileVertically = 4
|
||||
// Image.TileHorizontally = 5
|
||||
// Image.Pad = 6
|
||||
|
||||
// Rounded corners always apply to full item bounds
|
||||
vec2 roundedSize = itemSize;
|
||||
vec2 roundedCenter = itemSize * 0.5;
|
||||
|
||||
// Track if pixel is in letterbox area (for PreserveAspectFit)
|
||||
bool inLetterbox = false;
|
||||
|
||||
if (fillMode == 1) { // PreserveAspectFit
|
||||
float itemAspect = itemSize.x / itemSize.y;
|
||||
float sourceAspect = sourceSize.x / sourceSize.y;
|
||||
|
||||
if (sourceAspect > itemAspect) {
|
||||
// Image is wider than item, letterbox top/bottom
|
||||
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
|
||||
} else {
|
||||
// Image is taller than item, letterbox left/right
|
||||
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
|
||||
}
|
||||
|
||||
// Check if in letterbox area
|
||||
inLetterbox = (imageUV.x < 0.0 || imageUV.x > 1.0 || imageUV.y < 0.0 || imageUV.y > 1.0);
|
||||
} else if (fillMode == 2) { // PreserveAspectCrop
|
||||
float itemAspect = itemSize.x / itemSize.y;
|
||||
float sourceAspect = sourceSize.x / sourceSize.y;
|
||||
|
||||
if (sourceAspect > itemAspect) {
|
||||
// Image is wider than item, crop left/right.
|
||||
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
|
||||
} else {
|
||||
// Image is taller than item, crop top/bottom.
|
||||
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
|
||||
}
|
||||
}
|
||||
// For Stretch (0) or other modes, use qt_TexCoord0 as-is
|
||||
|
||||
// Calculate distance to rounded rectangle edge using the correct bounds
|
||||
vec2 centerOffset = pixelPos - roundedCenter;
|
||||
float distance = roundedBoxSDF(centerOffset, roundedSize * 0.5, cornerRadius);
|
||||
|
||||
// Create smooth alpha mask for edge with anti-aliasing
|
||||
float alpha = 1.0 - smoothstep(-0.5, 0.5, distance);
|
||||
|
||||
// Sample the texture (or use transparent for letterbox)
|
||||
// Clamp UV to prevent texture wrapping artifacts from floating-point imprecision
|
||||
vec4 color = inLetterbox ? vec4(0.0) : texture(source, clamp(imageUV, vec2(0.0), vec2(1.0)));
|
||||
|
||||
// Apply the rounded mask and opacity
|
||||
// Qt textures use premultiplied alpha (color.rgb already contains rgb * alpha),
|
||||
// so we only multiply by the external mask factors, not by color.a again
|
||||
float mask = alpha * itemOpacity * ubuf.qt_Opacity;
|
||||
fragColor = color * mask;
|
||||
}
|
||||
Reference in New Issue
Block a user