treesummaryrefslogcommitdiff
path: root/src/main.zig
blob: 4c6d98a77441e08b452487f366b61adfcc9d967b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//------------------------------------------------------------------------------
//  offscreen.zig
//
//  Render to an offscreen rendertarget texture, and use this texture
//  for rendering to the display.
//------------------------------------------------------------------------------
const sokol = @import("sokol");
const slog = sokol.log;
const sg = sokol.gfx;
const sapp = sokol.app;
const sglue = sokol.glue;
const imgui = sokol.imgui;
const appimgui = sokol.appimgui;
const vec3 = @import("math.zig").Vec3;
const mat4 = @import("math.zig").Mat4;
const shd = @import("shaders/main.glsl.zig");

const state = struct {
    const display = struct {
        var pass_action: sg.PassAction = .{};
        var pip: sg.Pipeline = .{};
        var bind: sg.Bindings = .{};
    };
};

export fn init() void {
    sg.setup(.{
        .environment = sglue.environment(),
        .logger = .{ .func = slog.func },
    });

    imgui.setup(.{});
    appimgui.setup();

    // default pass action: clear to blue-ish
    state.display.pass_action.colors[0] = .{
        .load_action = .CLEAR,
        .clear_value = .{ .r = 0.25, .g = 0.45, .b = 0.65, .a = 1.0 },
    };

    const vbuf = sg.makeBuffer(.{});
    state.display.bind.vertex_buffers[0] = vbuf;

    // shader and pipeline object for the default render pass
    state.display.pip = sg.makePipeline(.{
        .shader = sg.makeShader(shd.offscreenShaderDesc(sg.queryBackend())),
        .layout = init: {
            var l = sg.VertexLayoutState{};
            l.attrs[shd.ATTR_offscreen_position] = .{};
            break :init l;
        },
        .index_type = .UINT16,
        .cull_mode = .BACK,
        .depth = .{
            .compare = .LESS_EQUAL,
            .write_enabled = true,
        },
    });
}

export fn event(ev: [*c]const sapp.Event) void {
    appimgui.trackEvent(ev.*);
}

export fn frame() void {
    // const dt: f32 = @floatCast(sapp.frameDuration() * 60);
    // const aspect = sapp.widthf() / sapp.heightf();

    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);
    sg.endPass();

    sg.commit();
}

export fn cleanup() void {
    appimgui.shutdown();
    imgui.shutdown();
    sg.shutdown();
}

pub fn main() void {
    sapp.run(.{
        .init_cb = init,
        .frame_cb = frame,
        .event_cb = event,
        .cleanup_cb = cleanup,
        .sample_count = 4,
        .width = 800,
        .height = 600,
        .icon = .{ .sokol_default = true },
        .window_title = "offscreen.zig",
        .logger = .{ .func = slog.func },
    });
}

fn computeVsParams(rx: f32, ry: f32, aspect: f32, eye_dist: f32) shd.VsParams {
    const proj = mat4.persp(45, aspect, 0.01, 10);
    const view = mat4.lookat(.{ .x = 0, .y = 0, .z = eye_dist }, vec3.zero(), vec3.up());
    const view_proj = mat4.mul(proj, view);
    const rxm = mat4.rotate(rx, .{ .x = 1, .y = 0, .z = 0 });
    const rym = mat4.rotate(ry, .{ .x = 0, .y = 1, .z = 0 });
    const model = mat4.mul(rxm, rym);
    return shd.VsParams{ .mvp = mat4.mul(view_proj, model) };
}