|
|
@@ -1,114 +1,75 @@
|
|
|
package main
|
|
|
|
|
|
import "base:runtime"
|
|
|
-import "core:encoding/uuid"
|
|
|
-import "core:fmt"
|
|
|
|
|
|
-import m "huginn:core/math"
|
|
|
+import mu "third-party:microui"
|
|
|
+
|
|
|
import sapp "third-party:sokol/app"
|
|
|
import sg "third-party:sokol/gfx"
|
|
|
+import sgl "third-party:sokol/gl"
|
|
|
import sglue "third-party:sokol/glue"
|
|
|
import slog "third-party:sokol/log"
|
|
|
|
|
|
state: struct {
|
|
|
- default: struct {
|
|
|
- pass_action: sg.Pass_Action,
|
|
|
- pip: sg.Pipeline,
|
|
|
- bind: sg.Bindings,
|
|
|
- },
|
|
|
- rx, ry: f32,
|
|
|
+ pass_action: sg.Pass_Action,
|
|
|
+} = {
|
|
|
+ pass_action = {colors = {0 = {load_action = .CLEAR, clear_value = {1.0, 0.0, 1.0, 1.0}}}},
|
|
|
}
|
|
|
|
|
|
-Vertex :: struct {
|
|
|
- x, y, r: f32,
|
|
|
-}
|
|
|
+mu_ctx: mu.Context
|
|
|
|
|
|
init :: proc "c" () {
|
|
|
context = runtime.default_context()
|
|
|
-
|
|
|
sg.setup({environment = sglue.environment(), logger = {func = slog.func}})
|
|
|
+ sgl.setup({logger = {func = slog.func}})
|
|
|
|
|
|
- // a vertex buffer
|
|
|
- vertices := [?]Vertex{{-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {-1.0, -1.0, 1.0}}
|
|
|
- state.default.bind.vertex_buffers[0] = sg.make_buffer(
|
|
|
- {data = {ptr = &vertices, size = size_of(vertices)}},
|
|
|
- )
|
|
|
+ mu.init(&mu_ctx)
|
|
|
+ mu_ctx.text_width = mu.default_atlas_text_width
|
|
|
+ mu_ctx.text_height = mu.default_atlas_text_height
|
|
|
+}
|
|
|
|
|
|
- // an index buffer
|
|
|
- indices := [?]u16{0, 1, 2, 0, 2, 3}
|
|
|
- state.default.bind.index_buffer = sg.make_buffer(
|
|
|
- {usage = {index_buffer = true}, data = {ptr = &indices, size = size_of(indices)}},
|
|
|
- )
|
|
|
+frame :: proc "c" () {
|
|
|
+ context = runtime.default_context()
|
|
|
|
|
|
- pip_desc := sg.Pipeline_Desc {
|
|
|
- shader = sg.make_shader(quad_shader_desc(sg.query_backend())),
|
|
|
- index_type = .UINT16,
|
|
|
- layout = {attrs = {ATTR_quad_position = {format = .FLOAT2}}},
|
|
|
- }
|
|
|
- pip_desc.colors[0].blend = {
|
|
|
- enabled = true,
|
|
|
- src_factor_rgb = .SRC_ALPHA,
|
|
|
- dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
|
|
|
- op_rgb = .ADD,
|
|
|
- src_factor_alpha = .SRC_ALPHA,
|
|
|
- dst_factor_alpha = .ONE_MINUS_SRC_ALPHA,
|
|
|
- op_alpha = .ADD,
|
|
|
- }
|
|
|
+ t := f32(sapp.frame_duration() * 60.0)
|
|
|
|
|
|
- // a shader and pipeline object
|
|
|
- state.default.pip = sg.make_pipeline(pip_desc)
|
|
|
+ mu.begin(&mu_ctx)
|
|
|
|
|
|
- // default pass action
|
|
|
- state.default.pass_action = {
|
|
|
- colors = {
|
|
|
- 0 = {load_action = .CLEAR, store_action = .STORE, clear_value = {0.0, 0.0, 0.0, 0.0}},
|
|
|
- },
|
|
|
- depth = {load_action = .DONTCARE, store_action = .DONTCARE, clear_value = 0.0},
|
|
|
- stencil = {load_action = .DONTCARE, store_action = .DONTCARE, clear_value = 0},
|
|
|
- }
|
|
|
-}
|
|
|
+ @(static) opts := mu.Options{}
|
|
|
+ if mu.begin_window(&mu_ctx, "Window", {0, 0, 400, 400}, opts) {
|
|
|
+ mu.button(&mu_ctx, "Button")
|
|
|
|
|
|
-draw_quad :: proc(position, size: m.vec2, color: m.vec4) {
|
|
|
- ortho_matrix := m.ortho(-1.0, sapp.widthf(), -1.0, sapp.heightf(), -1.0, 1.0)
|
|
|
- scale_matrix := m.scale({size.x, size.y, 0.0})
|
|
|
- translate_matrix := m.translate({position.x, position.y, 0.0})
|
|
|
- projection_matrix := m.mul(m.mul(ortho_matrix, translate_matrix), scale_matrix)
|
|
|
- vs_params := Vs_Params {
|
|
|
- u_projection = projection_matrix,
|
|
|
- u_color = color,
|
|
|
+ mu.end_window(&mu_ctx)
|
|
|
}
|
|
|
- sg.apply_uniforms(UB_vs_params, {ptr = &vs_params, size = size_of(vs_params)})
|
|
|
- sg.draw(0, 6, 1)
|
|
|
-}
|
|
|
|
|
|
-frame :: proc "c" () {
|
|
|
- context = runtime.default_context()
|
|
|
-
|
|
|
- t := f32(sapp.frame_duration() * 60.0)
|
|
|
- state.rx += 1.0 * t
|
|
|
+ mu.end(&mu_ctx)
|
|
|
+
|
|
|
+ sgl.defaults()
|
|
|
+ sgl.push_pipeline()
|
|
|
+ sgl.matrix_mode_projection()
|
|
|
+ sgl.push_matrix()
|
|
|
+ sgl.ortho(0.0, sapp.widthf(), sapp.heightf(), 0.0, -1.0, +1.0)
|
|
|
+ sgl.begin_quads()
|
|
|
+ current_command: ^mu.Command
|
|
|
+ for cmd_variant in mu.next_command_iterator(&mu_ctx, ¤t_command) {
|
|
|
+ #partial switch cmd in cmd_variant {
|
|
|
+ case ^mu.Command_Rect:
|
|
|
+ draw_rect(cmd.rect, cmd.color)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sgl.end()
|
|
|
+ sgl.pop_matrix()
|
|
|
+ sgl.pop_pipeline()
|
|
|
|
|
|
- sg.begin_pass({action = state.default.pass_action, swapchain = sglue.swapchain()})
|
|
|
- sg.apply_pipeline(state.default.pip)
|
|
|
- sg.apply_bindings(state.default.bind)
|
|
|
- draw_quad({0.0, 0.0}, {100.0, 100.0}, {1.0, 0.0, 1.0, 1.0})
|
|
|
- draw_quad({state.rx, 0.0}, {100.0, 100.0}, {1.0, 1.0, 1.0, 1.0})
|
|
|
+ sg.begin_pass({action = state.pass_action, swapchain = sglue.swapchain()})
|
|
|
+ sgl.draw()
|
|
|
sg.end_pass()
|
|
|
sg.commit()
|
|
|
}
|
|
|
|
|
|
-compute_mvp :: proc(rx, ry, aspect, eye_dist: f32) -> m.mat4 {
|
|
|
- proj := m.persp(fov = 45.0, aspect = aspect, near = 0.01, far = 10.0)
|
|
|
- view := m.lookat(eye = {0.0, 0.0, eye_dist}, center = {}, up = m.up())
|
|
|
- view_proj := m.mul(proj, view)
|
|
|
- rxm := m.rotate(rx, {1.0, 0.0, 0.0})
|
|
|
- rym := m.rotate(ry, {0.0, 1.0, 0.0})
|
|
|
- model := m.mul(rym, rxm)
|
|
|
- mvp := m.mul(view_proj, model)
|
|
|
- return mvp
|
|
|
-}
|
|
|
-
|
|
|
cleanup :: proc "c" () {
|
|
|
context = runtime.default_context()
|
|
|
+ sgl.shutdown()
|
|
|
sg.shutdown()
|
|
|
}
|
|
|
|
|
|
@@ -118,11 +79,34 @@ main :: proc() {
|
|
|
init_cb = init,
|
|
|
frame_cb = frame,
|
|
|
cleanup_cb = cleanup,
|
|
|
- width = 1920,
|
|
|
- height = 1080,
|
|
|
- window_title = "quad",
|
|
|
- icon = {sokol_default = false},
|
|
|
+ width = 1280,
|
|
|
+ height = 720,
|
|
|
+ sample_count = 4,
|
|
|
+ window_title = "huginn",
|
|
|
+ icon = {sokol_default = true},
|
|
|
logger = {func = slog.func},
|
|
|
},
|
|
|
)
|
|
|
}
|
|
|
+
|
|
|
+push_quad :: proc(dst: mu.Rect, src: mu.Rect, color: mu.Color) {
|
|
|
+ u0 := f32(src.x) / f32(mu.DEFAULT_ATLAS_WIDTH)
|
|
|
+ v0 := f32(src.y) / f32(mu.DEFAULT_ATLAS_HEIGHT)
|
|
|
+ u1 := f32(src.x + src.w) / f32(mu.DEFAULT_ATLAS_WIDTH)
|
|
|
+ v1 := f32(src.y + src.h) / f32(mu.DEFAULT_ATLAS_HEIGHT)
|
|
|
+
|
|
|
+ x0 := f32(dst.x)
|
|
|
+ y0 := f32(dst.y)
|
|
|
+ x1 := f32(dst.x + dst.w)
|
|
|
+ y1 := f32(dst.y + dst.h)
|
|
|
+
|
|
|
+ sgl.c4b(color.r, color.g, color.b, color.a)
|
|
|
+ sgl.v2f_t2f(x0, y0, u0, v0)
|
|
|
+ sgl.v2f_t2f(x1, y0, u1, v0)
|
|
|
+ sgl.v2f_t2f(x1, y1, u1, v1)
|
|
|
+ sgl.v2f_t2f(x0, y1, u0, v1)
|
|
|
+}
|
|
|
+
|
|
|
+draw_rect :: proc(rect: mu.Rect, color: mu.Color) {
|
|
|
+ push_quad(rect, mu.default_atlas[mu.DEFAULT_ATLAS_WHITE], color)
|
|
|
+}
|