treesummaryrefslogcommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick2026-10-05 19:01:09 +0200
committerPatrick2026-10-05 19:01:09 +0200
commitbd3f5d3455ed523f58fd292b33db2cece1013cdf (patch)
tree5b3b111eda73f59befcb4b0ecd80af5105ad522d /src
parent2e19a1b44b366547563f5c5686455a1227a8fcbd (diff)
downloadsg3-bd3f5d3455ed523f58fd292b33db2cece1013cdf.tar.gz
sg3-bd3f5d3455ed523f58fd292b33db2cece1013cdf.zip
updateHEADmain
Diffstat (limited to 'src')
-rw-r--r--src/main.zig205
-rw-r--r--src/shaders/main.glsl33
2 files changed, 135 insertions, 103 deletions
diff --git a/src/main.zig b/src/main.zig
index 238785c..d0f369a 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -19,15 +19,16 @@ const shd = @import("shaders/main.glsl.zig");
const state = struct {
var alloc: std.mem.Allocator = undefined;
var io: std.Io = undefined;
+
const Width = 800;
const Height = 800;
- const offscreen = struct {
- var pass: sg.Pass = .{};
+ const SampleCount = 1;
+ var show: i32 = 0;
+
+ const raymarch = struct {
+ var pass_action: sg.PassAction = .{};
var pip: sg.Pipeline = .{};
var bind: sg.Bindings = .{};
- var vs: shd.VsParams = .{
- .position = .{ 0, 0 },
- };
var fs: shd.FsParams = .{
.resolution = .{ Width, Height },
.rayCount = 24,
@@ -39,10 +40,18 @@ const state = struct {
var pixels_updated: bool = true;
var pixels_img: sg.Image = undefined;
};
- const display = struct {
+ const nearest = struct {
var pass_action: sg.PassAction = .{};
- var pip: sg.Pipeline = .{};
+ var pass: sg.Pass = .{};
+ var pip1: sg.Pipeline = .{};
+ var pip2: sg.Pipeline = .{};
var bind: sg.Bindings = .{};
+
+ var render_tex1: sg.View = .{};
+ var render_tex2: sg.View = .{};
+ var input_tex1: sg.View = .{};
+ var input_tex2: sg.View = .{};
+ var depth_img: sg.Image = .{};
};
};
@@ -58,56 +67,65 @@ export fn init() void {
sappimgui.setup();
ig.igGetIO().*.ConfigFlags |= ig.ImGuiConfigFlags_DockingEnable;
- state.offscreen.pass.action.colors[0] = .{
+ state.raymarch.pass_action.colors[0] = .{
.load_action = .LOAD,
.store_action = .STORE,
};
- state.offscreen.pass.action.depth = .{
+ state.raymarch.pass_action.depth = .{
.load_action = .LOAD,
.store_action = .STORE,
};
- state.display.pass_action.colors[0] = .{
+ state.nearest.pass_action.colors[0] = .{
.load_action = .CLEAR,
};
- const offscreen_width = state.Width;
- const offscreen_height = state.Height;
- const offscreen_sample_count = 1;
- const color_img = sg.makeImage(.{
+ state.raymarch.pixels_img = sg.makeImage(.{
+ .usage = .{ .dynamic_update = true },
+ .width = state.Width,
+ .height = state.Height,
+ .sample_count = state.SampleCount,
+ .pixel_format = .RGBA8,
+ });
+ const nearest_tex1 = sg.makeImage(.{
.usage = .{ .color_attachment = true },
- .width = offscreen_width,
- .height = offscreen_height,
- .sample_count = offscreen_sample_count,
+ .width = state.Width,
+ .height = state.Height,
+ .sample_count = state.SampleCount,
.pixel_format = .RGBA8,
});
- state.offscreen.pixels_img = sg.makeImage(.{
- .usage = .{ .dynamic_update = true },
- .width = offscreen_width,
- .height = offscreen_height,
- .sample_count = offscreen_sample_count,
+ const nearest_tex2 = sg.makeImage(.{
+ .usage = .{ .color_attachment = true },
+ .width = state.Width,
+ .height = state.Height,
+ .sample_count = state.SampleCount,
.pixel_format = .RGBA8,
});
- const depth_img = sg.makeImage(.{
+ const nearest_depth_img = sg.makeImage(.{
.usage = .{ .depth_stencil_attachment = true },
- .width = offscreen_width,
- .height = offscreen_height,
- .sample_count = offscreen_sample_count,
+ .width = state.Width,
+ .height = state.Height,
+ .sample_count = state.SampleCount,
.pixel_format = .DEPTH,
});
-
- state.offscreen.pass.attachments.colors[0] = sg.makeView(.{
- .color_attachment = .{ .image = color_img },
+ state.nearest.render_tex1 = sg.makeView(.{
+ .color_attachment = .{ .image = nearest_tex1 },
});
- state.offscreen.pass.attachments.depth_stencil = sg.makeView(.{
- .depth_stencil_attachment = .{ .image = depth_img },
+ state.nearest.render_tex2 = sg.makeView(.{
+ .color_attachment = .{ .image = nearest_tex2 },
+ });
+ state.nearest.input_tex1 = sg.makeView(.{
+ .texture = .{ .image = nearest_tex1 },
+ });
+ state.nearest.input_tex2 = sg.makeView(.{
+ .texture = .{ .image = nearest_tex2 },
});
- state.offscreen.bind.views[shd.VIEW_off_tex] = sg.makeView(.{
- .texture = .{ .image = state.offscreen.pixels_img },
+ state.raymarch.bind.views[shd.VIEW_off_tex] = sg.makeView(.{
+ .texture = .{ .image = state.raymarch.pixels_img },
});
- state.display.bind.views[shd.VIEW_scr_tex] = sg.makeView(.{
- .texture = .{ .image = color_img },
+ state.nearest.pass.attachments.depth_stencil = sg.makeView(.{
+ .depth_stencil_attachment = .{ .image = nearest_depth_img },
});
const vbuf = sg.makeBuffer(.{ .data = sg.asRange(&[6]f32{
@@ -115,53 +133,63 @@ export fn init() void {
-1.0, 3.0,
3.0, -1.0,
}) });
- state.offscreen.bind.vertex_buffers[0] = vbuf;
- state.display.bind.vertex_buffers[0] = vbuf;
+ state.raymarch.bind.vertex_buffers[0] = vbuf;
+ state.nearest.bind.vertex_buffers[0] = vbuf;
// shader and pipeline object for the default render pass
- state.offscreen.pip = sg.makePipeline(.{
- .shader = sg.makeShader(shd.offscreenShaderDesc(sg.queryBackend())),
+ state.raymarch.pip = sg.makePipeline(.{
+ .shader = sg.makeShader(shd.raymarchShaderDesc(sg.queryBackend())),
.layout = init: {
var l = sg.VertexLayoutState{};
- l.attrs[shd.ATTR_offscreen_vpos] = .{ .format = .FLOAT2 };
+ l.attrs[shd.ATTR_raymarch_vpos] = .{ .format = .FLOAT2 };
break :init l;
},
.cull_mode = .BACK,
- .sample_count = offscreen_sample_count,
.depth = .{
.pixel_format = .DEPTH,
.compare = .LESS_EQUAL,
.write_enabled = true,
},
- .colors = init: {
- var c: [sg.max_color_attachments]sg.ColorTargetState = @splat(.{});
- c[0].pixel_format = .RGBA8;
- break :init c;
- },
});
- state.display.pip = sg.makePipeline(.{
- .shader = sg.makeShader(shd.defaultShaderDesc(sg.queryBackend())),
+ state.nearest.pip1 = sg.makePipeline(.{
+ .shader = sg.makeShader(shd.nearestShaderDesc(sg.queryBackend())),
.layout = init: {
var l = sg.VertexLayoutState{};
- l.attrs[shd.ATTR_default_vpos] = .{ .format = .FLOAT2 };
+ l.attrs[shd.ATTR_nearest_vpos] = .{ .format = .FLOAT2 };
break :init l;
},
.cull_mode = .BACK,
+ .sample_count = state.SampleCount,
.depth = .{
+ .pixel_format = .DEPTH,
.compare = .LESS_EQUAL,
.write_enabled = true,
},
+ .colors = init: {
+ var c: [sg.max_color_attachments]sg.ColorTargetState = @splat(.{});
+ c[0].pixel_format = .RGBA8;
+ break :init c;
+ },
+ });
+ state.nearest.pip2 = sg.makePipeline(.{
+ .shader = sg.makeShader(shd.nearestShaderDesc(sg.queryBackend())),
+ .layout = init: {
+ var l = sg.VertexLayoutState{};
+ l.attrs[shd.ATTR_nearest_vpos] = .{ .format = .FLOAT2 };
+ break :init l;
+ },
+ .cull_mode = .BACK,
});
// a sampler object for sampling the render target texture
- state.offscreen.bind.samplers[shd.SMP_off_smp] = sg.makeSampler(.{
+ state.raymarch.bind.samplers[shd.SMP_off_smp] = sg.makeSampler(.{
.min_filter = .LINEAR,
.mag_filter = .LINEAR,
.wrap_u = .REPEAT,
.wrap_v = .REPEAT,
});
- state.display.bind.samplers[shd.SMP_scr_smp] = sg.makeSampler(.{
+ state.nearest.bind.samplers[shd.SMP_scr_smp] = sg.makeSampler(.{
.min_filter = .LINEAR,
.mag_filter = .LINEAR,
.wrap_u = .REPEAT,
@@ -195,51 +223,72 @@ export fn frame() void {
// const dt: f32 = @floatCast(sapp.frameDuration() * 60);
// const aspect = sapp.widthf() / sapp.heightf();
- state.offscreen.fs.resolution[0] = sapp.widthf();
- state.offscreen.fs.resolution[1] = sapp.heightf();
+ state.raymarch.fs.resolution[0] = sapp.widthf();
+ state.raymarch.fs.resolution[1] = sapp.heightf();
if (ig.igBegin("abc", null, 0)) {
- // vs
- _ = ig.igDragFloat2("position", &state.offscreen.vs.position);
-
+ // general
+ _ = ig.igInputInt("show", &state.show);
// fs
- _ = ig.igInputInt("rayCount", &state.offscreen.fs.rayCount);
- _ = ig.igInputInt("maxSteps", &state.offscreen.fs.maxSteps);
- _ = ig.igDragFloatEx("size", &state.offscreen.fs.size, 1, 0, 1000, "%f", 0);
+ _ = ig.igInputInt("rayCount", &state.raymarch.fs.rayCount);
+ _ = ig.igInputInt("maxSteps", &state.raymarch.fs.maxSteps);
+ _ = ig.igDragFloatEx("size", &state.raymarch.fs.size, 1, 0, 1000, "%f", 0);
if (ig.igButton("load png")) {
var x: c_int = 0;
var y: c_int = 0;
var n: c_int = 0;
const img = stbi.stbi_load("test.png", &x, &y, &n, 0);
- @memcpy(&state.offscreen.pixels, img);
+ @memcpy(&state.raymarch.pixels, img);
stbi.stbi_image_free(img);
- state.offscreen.pixels_updated = true;
+ state.raymarch.pixels_updated = true;
}
}
ig.igEnd();
- if (state.offscreen.pixels_updated) {
- state.offscreen.pixels_updated = false;
+ if (state.raymarch.pixels_updated) {
+ state.raymarch.pixels_updated = false;
var imageData: sg.ImageData = .{};
- imageData.mip_levels[0] = sg.asRange(&state.offscreen.pixels);
- sg.updateImage(state.offscreen.pixels_img, imageData);
+ imageData.mip_levels[0] = sg.asRange(&state.raymarch.pixels);
+ sg.updateImage(state.raymarch.pixels_img, imageData);
}
- sg.beginPass(state.offscreen.pass);
- sg.applyPipeline(state.offscreen.pip);
- sg.applyBindings(state.offscreen.bind);
- sg.applyUniforms(shd.UB_vs_params, sg.asRange(&state.offscreen.vs));
- sg.applyUniforms(shd.UB_fs_params, sg.asRange(&state.offscreen.fs));
- sg.draw(0, 3, 1);
- sg.endPass();
+ if (state.show == 0) {
+ sg.beginPass(.{ .action = state.raymarch.pass_action, .swapchain = sglue.swapchain() });
+ sg.applyPipeline(state.raymarch.pip);
+ sg.applyBindings(state.raymarch.bind);
+ sg.applyUniforms(shd.UB_fs_params, sg.asRange(&state.raymarch.fs));
+ sg.draw(0, 3, 1);
+ simgui.render();
+ sg.endPass();
+ } else if (state.show == 1) {
+ // render to tex1
+ state.nearest.pass.attachments.colors[0] = state.nearest.render_tex1;
+ state.nearest.bind.views[shd.VIEW_scr_tex] = state.nearest.input_tex2;
+ sg.beginPass(state.nearest.pass);
+ sg.applyPipeline(state.nearest.pip1);
+ sg.applyBindings(state.nearest.bind);
+ sg.draw(0, 3, 1);
+ sg.endPass();
- sg.beginPass(.{ .action = state.display.pass_action, .swapchain = sglue.swapchain() });
- sg.applyPipeline(state.display.pip);
- sg.applyBindings(state.display.bind);
- sg.draw(0, 3, 1);
- simgui.render();
- sg.endPass();
+ // render from tex1 to tex2
+ state.nearest.pass.attachments.colors[0] = state.nearest.render_tex2;
+ state.nearest.bind.views[shd.VIEW_scr_tex] = state.nearest.input_tex1;
+ sg.beginPass(state.nearest.pass);
+ sg.applyPipeline(state.nearest.pip1);
+ sg.applyBindings(state.nearest.bind);
+ sg.draw(0, 3, 1);
+ sg.endPass();
+
+ // render from tex2 to screen
+ state.nearest.bind.views[shd.VIEW_scr_tex] = state.nearest.input_tex2;
+ sg.beginPass(.{.action = state.nearest.pass_action, .swapchain = sglue.swapchain() });
+ sg.applyPipeline(state.nearest.pip2);
+ sg.applyBindings(state.nearest.bind);
+ sg.draw(0, 3, 1);
+ simgui.render();
+ sg.endPass();
+ }
sg.commit();
}
diff --git a/src/shaders/main.glsl b/src/shaders/main.glsl
index 407d2c1..68a1e7e 100644
--- a/src/shaders/main.glsl
+++ b/src/shaders/main.glsl
@@ -1,19 +1,15 @@
// offscreen rendering shaders
-@vs vs_offscreen
-layout(binding=0) uniform vs_params {
- vec2 position;
-};
-
+@vs vs_screen
in vec2 vpos;
out vec2 fpos;
void main() {
- gl_Position = vec4(vpos + position, 0, 1);
+ gl_Position = vec4(vpos, 0, 1);
fpos = (vpos + 1) * 0.5;
}
@end
-@fs fs_offscreen
+@fs fs_raymarch
layout(binding=1) uniform texture2D off_tex;
layout(binding=1) uniform sampler off_smp;
layout(binding=1) uniform fs_params {
@@ -31,8 +27,6 @@ bool outOfBounds(vec2 uv) {
}
#define TAU 6.28318530718
-// #define RAYCOUNT 16
-// #define MAXSTEPS 8
float rand(vec2 seed)
{
@@ -88,22 +82,10 @@ void main() {
}
@end
-@program offscreen vs_offscreen fs_offscreen
-
+@program raymarch vs_screen fs_raymarch
-// default-pass shaders
-@vs vs_default
-
-in vec2 vpos;
-out vec2 fpos;
-
-void main() {
- gl_Position = vec4(vpos, 0, 1);
- fpos = (vpos + 1) * 0.5;
-}
-@end
-@fs fs_default
+@fs fs_nearest
layout(binding=0) uniform texture2D scr_tex;
layout(binding=0) uniform sampler scr_smp;
@@ -112,8 +94,9 @@ in vec2 fpos;
out vec4 frag_color;
void main() {
- frag_color = texture(sampler2D(scr_tex, scr_smp), fpos);
+ vec4 t = texture(sampler2D(scr_tex, scr_smp), fpos);
+ frag_color = vec4(fpos.x, fpos.y, 0, 1) + t;
}
@end
-@program default vs_default fs_default
+@program nearest vs_screen fs_nearest