Skip to content

Commit b63ed0a

Browse files
committed
Misc changes
- Add STORAGE_BINDING usage to texture manager - Comment out compute shader code. Currently debugging it.
1 parent f17568f commit b63ed0a

File tree

4 files changed

+130
-123
lines changed

4 files changed

+130
-123
lines changed

packages/arisu-gfx/compute_pipeline/gl.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ end
3232
function GLComputePipeline:genForCurrentContext()
3333
local pipeline = gl.genProgramPipelines(1)[1]
3434

35+
-- todo: destroy when pipeline is destroyed
3536
local program = GLProgram.new(gl.ShaderType.COMPUTE, self.module.source)
3637
gl.useProgramStages(pipeline, gl.COMPUTE_SHADER_BIT, program.id)
3738

packages/arisu/shaders/brush.compute.glsl

Lines changed: 126 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -29,125 +29,130 @@ float colorDistance(vec3 color1, vec3 color2) {
2929
}
3030

3131
void main() {
32-
ivec2 pixelCoords;
33-
34-
if (tool == 2) {
35-
// Fill uses direct coordinates
36-
pixelCoords = ivec2(gl_GlobalInvocationID.xy);
37-
} else if (tool == 3) {
38-
// Line uses direct coordinates
39-
pixelCoords = ivec2(gl_GlobalInvocationID.xy);
40-
} else if (tool == 4) {
41-
// Rectangle uses direct coordinates
42-
pixelCoords = ivec2(gl_GlobalInvocationID.xy);
43-
} else if (tool == 5) {
44-
// Circle uses direct coordinates
45-
pixelCoords = ivec2(gl_GlobalInvocationID.xy);
46-
} else {
47-
// Brush/eraser use radius-based coords
48-
ivec2 localCoords = ivec2(gl_GlobalInvocationID.xy);
49-
pixelCoords = center + localCoords - ivec2(radius);
50-
51-
float dist = distance(vec2(localCoords), vec2(radius));
52-
if (dist > radius) return;
53-
}
54-
55-
// Check if pixel is within selected area
56-
if (selectTopLeft.x != -1 && (pixelCoords.x < selectTopLeft.x || pixelCoords.x > selectBottomRight.x ||
57-
pixelCoords.y < selectTopLeft.y || pixelCoords.y > selectBottomRight.y)) {
58-
return;
59-
}
60-
61-
if (tool == 0) {
62-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
63-
} else if (tool == 1) {
64-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), vec4(0.0, 0.0, 0.0, 0.0));
65-
} else if (tool == 3) {
66-
// Line drawing using Bresenham-like distance check
67-
vec2 lineStart = vec2(center);
68-
vec2 lineEndPos = vec2(lineEnd);
69-
vec2 pixelPos = vec2(pixelCoords);
70-
71-
vec2 lineVec = lineEndPos - lineStart;
72-
float lineLen = length(lineVec);
73-
74-
if (lineLen < 0.001) return;
75-
76-
vec2 lineDir = lineVec / lineLen;
77-
vec2 toPixel = pixelPos - lineStart;
78-
79-
float proj = dot(toPixel, lineDir);
80-
proj = clamp(proj, 0.0, lineLen);
81-
82-
vec2 closest = lineStart + lineDir * proj;
83-
float dist = distance(pixelPos, closest);
84-
85-
if (dist <= radius) {
86-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
87-
}
88-
} else if (tool == 4) {
89-
// Rectangle drawing
90-
vec2 topLeft = vec2(min(center.x, lineEnd.x), min(center.y, lineEnd.y));
91-
vec2 bottomRight = vec2(max(center.x, lineEnd.x), max(center.y, lineEnd.y));
92-
vec2 pixelPos = vec2(pixelCoords);
93-
94-
float distLeft = abs(pixelPos.x - topLeft.x);
95-
float distRight = abs(pixelPos.x - bottomRight.x);
96-
float distTop = abs(pixelPos.y - topLeft.y);
97-
float distBottom = abs(pixelPos.y - bottomRight.y);
98-
99-
bool onLeft = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distLeft <= radius;
100-
bool onRight = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distRight <= radius;
101-
bool onTop = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distTop <= radius;
102-
bool onBottom = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distBottom <= radius;
103-
104-
if (onLeft || onRight || onTop || onBottom) {
105-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
106-
}
107-
} else if (tool == 5) {
108-
// Ellipse drawing with corner-to-corner bounding box
109-
vec2 corner1 = vec2(center);
110-
vec2 corner2 = vec2(lineEnd);
111-
vec2 pixelPos = vec2(pixelCoords);
112-
113-
vec2 centerPos = (corner1 + corner2) / 2.0;
114-
vec2 radii = abs(corner2 - corner1) / 2.0;
115-
116-
if (radii.x < 0.001 || radii.y < 0.001) return;
117-
118-
vec2 normalized = (pixelPos - centerPos) / radii;
119-
float distFromEllipse = length(normalized);
120-
121-
float innerDist = 1.0 - (radius / max(radii.x, radii.y));
122-
float outerDist = 1.0 + (radius / max(radii.x, radii.y));
123-
124-
if (distFromEllipse >= innerDist && distFromEllipse <= outerDist) {
125-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
126-
}
127-
} else if (tool == 2) {
128-
// At the origin - mark as filled
129-
if (center == pixelCoords) {
130-
vec4 fillColor = color;
131-
fillColor.a = 1.0; // Mark as filled
132-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
133-
} else {
134-
vec4 targetColor = imageLoad(imgOutput, ivec3(center, readLayer));
135-
vec4 currentColor = imageLoad(imgOutput, ivec3(pixelCoords, readLayer));
136-
137-
// Check if any neighbor is filled (alpha == 1)
138-
vec4 north = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, 1), readLayer));
139-
vec4 south = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, -1), readLayer));
140-
vec4 east = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(1, 0), readLayer));
141-
vec4 west = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(-1, 0), readLayer));
142-
143-
bool neighborFilled = (north.a == 1.0) || (south.a == 1.0) ||
144-
(east.a == 1.0) || (west.a == 1.0);
145-
146-
if (neighborFilled && colorDistance(currentColor.rgb, targetColor.rgb) < 0.9) {
147-
vec4 fillColor = color;
148-
fillColor.a = 1.0;
149-
imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
150-
}
151-
}
152-
}
32+
if (gl_GlobalInvocationID.xy != uvec2(0, 0)) return;
33+
34+
// Write a bright red pixel at the center position to verify it's reading correctly
35+
imageStore(imgOutput, ivec3(center, writeLayer), vec4(1.0, 0.0, 0.0, 1.0));
36+
37+
// ivec2 pixelCoords;
38+
39+
// if (tool == 2) {
40+
// // Fill uses direct coordinates
41+
// pixelCoords = ivec2(gl_GlobalInvocationID.xy);
42+
// } else if (tool == 3) {
43+
// // Line uses direct coordinates
44+
// pixelCoords = ivec2(gl_GlobalInvocationID.xy);
45+
// } else if (tool == 4) {
46+
// // Rectangle uses direct coordinates
47+
// pixelCoords = ivec2(gl_GlobalInvocationID.xy);
48+
// } else if (tool == 5) {
49+
// // Circle uses direct coordinates
50+
// pixelCoords = ivec2(gl_GlobalInvocationID.xy);
51+
// } else {
52+
// // Brush/eraser use radius-based coords
53+
// ivec2 localCoords = ivec2(gl_GlobalInvocationID.xy);
54+
// pixelCoords = center + localCoords - ivec2(radius);
55+
56+
// float dist = distance(vec2(localCoords), vec2(radius));
57+
// if (dist > radius) return;
58+
// }
59+
60+
// // Check if pixel is within selected area
61+
// if (selectTopLeft.x != -1 && (pixelCoords.x < selectTopLeft.x || pixelCoords.x > selectBottomRight.x ||
62+
// pixelCoords.y < selectTopLeft.y || pixelCoords.y > selectBottomRight.y)) {
63+
// return;
64+
// }
65+
66+
// if (tool == 0) {
67+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
68+
// } else if (tool == 1) {
69+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), vec4(0.0, 0.0, 0.0, 0.0));
70+
// } else if (tool == 3) {
71+
// // Line drawing using Bresenham-like distance check
72+
// vec2 lineStart = vec2(center);
73+
// vec2 lineEndPos = vec2(lineEnd);
74+
// vec2 pixelPos = vec2(pixelCoords);
75+
76+
// vec2 lineVec = lineEndPos - lineStart;
77+
// float lineLen = length(lineVec);
78+
79+
// if (lineLen < 0.001) return;
80+
81+
// vec2 lineDir = lineVec / lineLen;
82+
// vec2 toPixel = pixelPos - lineStart;
83+
84+
// float proj = dot(toPixel, lineDir);
85+
// proj = clamp(proj, 0.0, lineLen);
86+
87+
// vec2 closest = lineStart + lineDir * proj;
88+
// float dist = distance(pixelPos, closest);
89+
90+
// if (dist <= radius) {
91+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
92+
// }
93+
// } else if (tool == 4) {
94+
// // Rectangle drawing
95+
// vec2 topLeft = vec2(min(center.x, lineEnd.x), min(center.y, lineEnd.y));
96+
// vec2 bottomRight = vec2(max(center.x, lineEnd.x), max(center.y, lineEnd.y));
97+
// vec2 pixelPos = vec2(pixelCoords);
98+
99+
// float distLeft = abs(pixelPos.x - topLeft.x);
100+
// float distRight = abs(pixelPos.x - bottomRight.x);
101+
// float distTop = abs(pixelPos.y - topLeft.y);
102+
// float distBottom = abs(pixelPos.y - bottomRight.y);
103+
104+
// bool onLeft = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distLeft <= radius;
105+
// bool onRight = (pixelPos.y >= topLeft.y && pixelPos.y <= bottomRight.y) && distRight <= radius;
106+
// bool onTop = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distTop <= radius;
107+
// bool onBottom = (pixelPos.x >= topLeft.x && pixelPos.x <= bottomRight.x) && distBottom <= radius;
108+
109+
// if (onLeft || onRight || onTop || onBottom) {
110+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
111+
// }
112+
// } else if (tool == 5) {
113+
// // Ellipse drawing with corner-to-corner bounding box
114+
// vec2 corner1 = vec2(center);
115+
// vec2 corner2 = vec2(lineEnd);
116+
// vec2 pixelPos = vec2(pixelCoords);
117+
118+
// vec2 centerPos = (corner1 + corner2) / 2.0;
119+
// vec2 radii = abs(corner2 - corner1) / 2.0;
120+
121+
// if (radii.x < 0.001 || radii.y < 0.001) return;
122+
123+
// vec2 normalized = (pixelPos - centerPos) / radii;
124+
// float distFromEllipse = length(normalized);
125+
126+
// float innerDist = 1.0 - (radius / max(radii.x, radii.y));
127+
// float outerDist = 1.0 + (radius / max(radii.x, radii.y));
128+
129+
// if (distFromEllipse >= innerDist && distFromEllipse <= outerDist) {
130+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), color);
131+
// }
132+
// } else if (tool == 2) {
133+
// // At the origin - mark as filled
134+
// if (center == pixelCoords) {
135+
// vec4 fillColor = color;
136+
// fillColor.a = 1.0; // Mark as filled
137+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
138+
// } else {
139+
// vec4 targetColor = imageLoad(imgOutput, ivec3(center, readLayer));
140+
// vec4 currentColor = imageLoad(imgOutput, ivec3(pixelCoords, readLayer));
141+
142+
// // Check if any neighbor is filled (alpha == 1)
143+
// vec4 north = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, 1), readLayer));
144+
// vec4 south = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(0, -1), readLayer));
145+
// vec4 east = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(1, 0), readLayer));
146+
// vec4 west = imageLoad(imgOutput, ivec3(pixelCoords + ivec2(-1, 0), readLayer));
147+
148+
// bool neighborFilled = (north.a == 1.0) || (south.a == 1.0) ||
149+
// (east.a == 1.0) || (west.a == 1.0);
150+
151+
// if (neighborFilled && colorDistance(currentColor.rgb, targetColor.rgb) < 0.9) {
152+
// vec4 fillColor = color;
153+
// fillColor.a = 1.0;
154+
// imageStore(imgOutput, ivec3(pixelCoords, writeLayer), fillColor);
155+
// }
156+
// }
157+
// }
153158
}

packages/arisu/tools/compute.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function Compute.new(textureManager, canvas, device)
4848
local inputs = ffi.new("ComputeInputs")
4949

5050
local inputsBuffer = device:createBuffer({
51-
size = assert(sizeofComputeInputs),
51+
size = sizeofComputeInputs,
5252
usages = { "UNIFORM", "COPY_DST" }
5353
})
5454

@@ -122,6 +122,7 @@ function Compute:stamp(x, y, radius, color)
122122
self.inputs.color[2] = color.b
123123
self.inputs.color[3] = color.a
124124
self.inputs.tool = TOOL_BRUSH
125+
self:updateInputs()
125126

126127
local diameter = radius * 2
127128
local groupsX = math.ceil(diameter / WORK_GROUP_SIZE)

packages/arisu/util/texture_manager.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function TextureManager.new(device)
2929
local texture = device:createTexture({
3030
extents = { dim = "2d", width = maxWidth, height = maxHeight, count = maxLayers },
3131
format = gfx.TextureFormat.Rgba8UNorm,
32-
usages = { "TEXTURE_BINDING", "COPY_DST", "COPY_SRC" },
32+
usages = { "TEXTURE_BINDING", "STORAGE_BINDING", "COPY_DST", "COPY_SRC" },
3333
})
3434

3535
local sampler = device:createSampler({

0 commit comments

Comments
 (0)