@@ -4,21 +4,13 @@ layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
44
55layout (rgba8, binding = 0 ) writeonly uniform image2D canvas;
66layout (std430, binding = 1 ) readonly buffer ComputeInputs {
7- ivec2 center;
8- float radius;
97 vec4 color;
10-
11- // 0 - Brush
12- // 1 - Eraser
13- // 2 - Fill
14- // 3 - Line
15- // 4 - Rectangle
16- // 5 - Circle
17- int tool;
18-
198 vec2 selectTopLeft;
209 vec2 selectBottomRight;
10+ ivec2 center;
2111 ivec2 lineEnd;
12+ float radius;
13+ int tool;
2214};
2315
2416float colorDistance(vec3 color1, vec3 color2) {
@@ -45,98 +37,99 @@ void main() {
4537 return ;
4638 }
4739
48- imageStore(canvas, pixelCoords, vec4 (0.0 , 1.0 , 0.0 , 1.0 ));
49-
50- // if (tool == 0) {
51- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
52- // } else if (tool == 1) {
53- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), vec4(0.0, 0.0, 0.0, 0.0));
54- // } else if (tool == 3) {
55- // // Line drawing using Bresenham-like distance check
56- // vec2 lineStart = vec2(center);
57- // vec2 lineEndPos = vec2(lineEnd);
58- // vec2 pixelPos = vec2(pixelCoords);
59-
60- // vec2 lineVec = lineEndPos - lineStart;
61- // float lineLen = length(lineVec);
62-
63- // if (lineLen < 0.001) return;
64-
65- // vec2 lineDir = lineVec / lineLen;
66- // vec2 toPixel = pixelPos - lineStart;
67-
68- // float proj = dot(toPixel, lineDir);
69- // proj = clamp(proj, 0.0, lineLen);
70-
71- // vec2 closest = lineStart + lineDir * proj;
72- // float dist = distance(pixelPos, closest);
73-
74- // if (dist <= radius) {
75- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
76- // }
77- // } else if (tool == 4) {
78- // // Rectangle drawing
79- // vec2 topLeft = vec2(min(center.x, lineEnd.x), min(center.y, lineEnd.y));
80- // vec2 bottomRight = vec2(max(center.x, lineEnd.x), max(center.y, lineEnd.y));
81- // vec2 pixelPos = vec2(pixelCoords);
82-
83- // float distLeft = abs(pixelPos.x - topLeft.x);
84- // float distRight = abs(pixelPos.x - bottomRight.x);
85- // float distTop = abs(pixelPos.y - topLeft.y);
86- // float distBottom = abs(pixelPos.y - bottomRight.y);
87-
88- // bool onLeft = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distLeft <= radius;
89- // bool onRight = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distRight <= radius;
90- // bool onTop = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distTop <= radius;
91- // bool onBottom = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distBottom <= radius;
92-
93- // if (onLeft || onRight || onTop || onBottom) {
94- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
95- // }
96- // } else if (tool == 5) {
97- // // Ellipse drawing with corner-to-corner bounding box
98- // vec2 corner1 = vec2(center);
99- // vec2 corner2 = vec2(lineEnd);
100- // vec2 pixelPos = vec2(pixelCoords);
101-
102- // vec2 centerPos = (corner1 + corner2) / 2.0;
103- // vec2 radii = abs(corner2 - corner1) / 2.0;
104-
105- // if (radii.x < 0.001 || radii.y < 0.001) return;
106-
107- // vec2 normalized = (pixelPos - centerPos) / radii;
108- // float distFromEllipse = length(normalized);
109-
110- // float innerDist = 1.0 - (radius / max(radii.x, radii.y));
111- // float outerDist = 1.0 + (radius / max(radii.x, radii.y));
112-
113- // if (distFromEllipse >= innerDist && distFromEllipse <= outerDist) {
114- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
115- // }
116- // } else if (tool == 2) {
117- // // At the origin - mark as filled
118- // if (center == pixelCoords) {
119- // vec4 fillColor = color;
120- // fillColor.a = 1.0; // Mark as filled
121- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
122- // } else {
123- // vec4 targetColor = imageLoad(imgOutput, ivec3(center, readLayer));
124- // vec4 currentColor = imageLoad(imgOutput, ivec3(pixelCoords, readLayer));
125-
126- // // Check if any neighbor is filled (alpha == 1)
127- // vec4 north = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, 1), readLayer));
128- // vec4 south = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, -1), readLayer));
129- // vec4 east = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(1, 0), readLayer));
130- // vec4 west = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(-1, 0), readLayer));
131-
132- // bool neighborFilled = (north.a == 1.0) || (south.a == 1.0) ||
133- // (east.a == 1.0) || (west.a == 1.0);
134-
135- // if (neighborFilled && colorDistance(currentColor.rgb, targetColor.rgb) < 0.9) {
136- // vec4 fillColor = color;
137- // fillColor.a = 1.0;
138- // imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
139- // }
140- // }
141- // }
40+ imageStore(canvas, pixelCoords, color);
41+ return ;
42+
43+ if (tool == 0 ) {
44+ imageStore(canvas, pixelCoords, vec4 (1.0 , 0.0 , 0.0 , 1.0 ));
45+ } else if (tool == 1 ) {
46+ imageStore(canvas, pixelCoords, vec4 (0.0 , 0.0 , 0.0 , 0.0 ));
47+ } else if (tool == 3 ) {
48+ // Line drawing using Bresenham-like distance check
49+ vec2 lineStart = vec2 (center);
50+ vec2 lineEndPos = vec2 (lineEnd);
51+ vec2 pixelPos = vec2 (pixelCoords);
52+
53+ vec2 lineVec = lineEndPos - lineStart;
54+ float lineLen = length (lineVec);
55+
56+ if (lineLen < 0.001 ) return ;
57+
58+ vec2 lineDir = lineVec / lineLen;
59+ vec2 toPixel = pixelPos - lineStart;
60+
61+ float proj = dot (toPixel, lineDir);
62+ proj = clamp (proj, 0.0 , lineLen);
63+
64+ vec2 closest = lineStart + lineDir * proj;
65+ float dist = distance (pixelPos, closest);
66+
67+ if (dist <= radius) {
68+ imageStore(canvas, pixelCoords, color);
69+ }
70+ } else if (tool == 4 ) {
71+ // Rectangle drawing
72+ vec2 topLeft = vec2 (min (center.x, lineEnd.x), min (center.y, lineEnd.y));
73+ vec2 bottomRight = vec2 (max (center.x, lineEnd.x), max (center.y, lineEnd.y));
74+ vec2 pixelPos = vec2 (pixelCoords);
75+
76+ float distLeft = abs (pixelPos.x - topLeft.x);
77+ float distRight = abs (pixelPos.x - bottomRight.x);
78+ float distTop = abs (pixelPos.y - topLeft.y);
79+ float distBottom = abs (pixelPos.y - bottomRight.y);
80+
81+ bool onLeft = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distLeft <= radius;
82+ bool onRight = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distRight <= radius;
83+ bool onTop = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distTop <= radius;
84+ bool onBottom = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distBottom <= radius;
85+
86+ if (onLeft || onRight || onTop || onBottom) {
87+ imageStore(canvas, pixelCoords, color);
88+ }
89+ } else if (tool == 5 ) {
90+ // Ellipse drawing with corner-to-corner bounding box
91+ vec2 corner1 = vec2 (center);
92+ vec2 corner2 = vec2 (lineEnd);
93+ vec2 pixelPos = vec2 (pixelCoords);
94+
95+ vec2 centerPos = (corner1 + corner2) / 2.0 ;
96+ vec2 radii = abs (corner2 - corner1) / 2.0 ;
97+
98+ if (radii.x < 0.001 || radii.y < 0.001 ) return ;
99+
100+ vec2 normalized = (pixelPos - centerPos) / radii;
101+ float distFromEllipse = length (normalized);
102+
103+ float innerDist = 1.0 - (radius / max (radii.x, radii.y));
104+ float outerDist = 1.0 + (radius / max (radii.x, radii.y));
105+
106+ if (distFromEllipse >= innerDist && distFromEllipse <= outerDist) {
107+ imageStore(canvas, pixelCoords, color);
108+ }
109+ // } else if (tool == 2) {
110+ // At the origin - mark as filled
111+ // if (center == pixelCoords) {
112+ // vec4 fillColor = color;
113+ // fillColor.a = 1.0; // Mark as filled
114+ // imageStore(canvas, pixelCoords, fillColor);
115+ // } else {
116+ // vec4 targetColor = imageLoad(canvas, center);
117+ // vec4 currentColor = imageLoad(canvas, pixelCoords);
118+
119+ // // Check if any neighbor is filled (alpha == 1)
120+ // vec4 north = imageLoad(canvas, pixelCoords + ivec2(0, 1));
121+ // vec4 south = imageLoad(canvas, pixelCoords + ivec2(0, -1));
122+ // vec4 east = imageLoad(canvas, pixelCoords + ivec2(1, 0));
123+ // vec4 west = imageLoad(canvas, pixelCoords + ivec2(-1, 0));
124+
125+ // bool neighborFilled = (north.a == 1.0) || (south.a == 1.0) ||
126+ // (east.a == 1.0) || (west.a == 1.0);
127+
128+ // if (neighborFilled && colorDistance(currentColor.rgb, targetColor.rgb) < 0.9) {
129+ // vec4 fillColor = color;
130+ // fillColor.a = 1.0;
131+ // imageStore(canvas, pixelCoords, fillColor);
132+ // }
133+ // }
134+ }
142135}
0 commit comments