158 lines
4 KiB
Odin
158 lines
4 KiB
Odin
package main
|
|
|
|
import "base:runtime"
|
|
|
|
import "core:fmt"
|
|
import "core:log"
|
|
import glm "core:math/linalg/glsl"
|
|
import "core:math/rand"
|
|
|
|
import sapp "sokol/app"
|
|
import sg "sokol/gfx"
|
|
import sglue "sokol/glue"
|
|
import slog "sokol/log"
|
|
|
|
MAX_QUADS :: 1_000_000
|
|
Quad :: struct #packed {
|
|
transform: glm.mat4,
|
|
color: glm.vec3,
|
|
}
|
|
|
|
ctx: runtime.Context
|
|
state: struct {
|
|
pip: sg.Pipeline,
|
|
bind: sg.Bindings,
|
|
pass_action: sg.Pass_Action,
|
|
quads: [MAX_QUADS]Quad,
|
|
quad_count: uint,
|
|
proj: glm.mat4,
|
|
}
|
|
player_pos: glm.vec2
|
|
|
|
init :: proc "c" () {
|
|
ctx = runtime.default_context()
|
|
context = ctx
|
|
context.logger = log.create_console_logger()
|
|
|
|
sg.setup({environment = sglue.environment(), logger = {func = slog.func}})
|
|
|
|
vertices := [?]glm.vec2{{-0.5, 0.5}, {-0.5, -0.5}, {0.5, -0.5}, {0.5, 0.5}}
|
|
|
|
indicies := [?]u16{0, 1, 2, 0, 2, 3}
|
|
|
|
state.bind.vertex_buffers[0] = sg.make_buffer({data = {ptr = &vertices, size = size_of(vertices)}})
|
|
state.bind.vertex_buffers[1] = sg.make_buffer({size = MAX_QUADS * size_of(Quad), usage = .STREAM})
|
|
state.bind.index_buffer = sg.make_buffer(
|
|
{type = .INDEXBUFFER, data = {ptr = &indicies, size = size_of(indicies)}},
|
|
)
|
|
|
|
state.pip = sg.make_pipeline(
|
|
{
|
|
shader = sg.make_shader(quad_shader_desc(sg.query_backend())),
|
|
layout = {
|
|
buffers = {1 = {step_func = .PER_INSTANCE}},
|
|
attrs = {
|
|
ATTR_quad_position = {format = .FLOAT2, buffer_index = 0},
|
|
ATTR_quad_inst_mat0 = {format = .FLOAT4, buffer_index = 1},
|
|
ATTR_quad_inst_mat1 = {format = .FLOAT4, buffer_index = 1},
|
|
ATTR_quad_inst_mat2 = {format = .FLOAT4, buffer_index = 1},
|
|
ATTR_quad_inst_mat3 = {format = .FLOAT4, buffer_index = 1},
|
|
ATTR_quad_color = {format = .FLOAT3, buffer_index = 1},
|
|
},
|
|
},
|
|
depth = {write_enabled = false},
|
|
index_type = .UINT16,
|
|
},
|
|
)
|
|
|
|
state.pass_action = {
|
|
colors = {0 = {load_action = .CLEAR, clear_value = {r = 0, g = 0, b = 0, a = 1}}},
|
|
}
|
|
}
|
|
|
|
draw_quad :: proc(pos, size: glm.vec2, rotation := f32(0), color := glm.vec3(1)) {
|
|
model := glm.mat4Translate({pos.x + size.x / 2, pos.y + size.y / 2, 0})
|
|
model *= glm.mat4Rotate({0, 0, 1}, glm.radians(rotation))
|
|
model *= glm.mat4Scale({size.x, size.y, 0})
|
|
|
|
mvp := state.proj * model
|
|
|
|
state.quads[state.quad_count] = {
|
|
transform = mvp,
|
|
color = color,
|
|
}
|
|
|
|
state.quad_count += 1
|
|
}
|
|
|
|
flush_quads :: proc() {
|
|
sg.update_buffer(
|
|
state.bind.vertex_buffers[1],
|
|
{ptr = &state.quads, size = size_of(Quad) * state.quad_count},
|
|
)
|
|
|
|
sg.begin_pass({action = state.pass_action, swapchain = sglue.swapchain()})
|
|
sg.apply_pipeline(state.pip)
|
|
sg.apply_bindings(state.bind)
|
|
sg.draw(0, 6, state.quad_count)
|
|
sg.end_pass()
|
|
sg.commit()
|
|
|
|
state.quad_count = 0
|
|
}
|
|
|
|
frame :: proc "c" () {
|
|
context = ctx
|
|
|
|
state.proj = glm.mat4Ortho3d(0, f32(sapp.width()), f32(sapp.height()), 0, -1, 1)
|
|
|
|
draw_quad(player_pos, {50, 100}, 0)
|
|
flush_quads()
|
|
}
|
|
|
|
event :: proc "c" (event: ^sapp.Event) {
|
|
context = ctx
|
|
#partial switch event.type {
|
|
case .KEY_DOWN:
|
|
if event.key_code == .ESCAPE {
|
|
sapp.quit()
|
|
}
|
|
|
|
if event.key_code == .W {
|
|
player_pos.y -= 10
|
|
}
|
|
|
|
if event.key_code == .S {
|
|
player_pos.y += 10
|
|
}
|
|
|
|
if event.key_code == .A {
|
|
player_pos.x -= 10
|
|
}
|
|
|
|
if event.key_code == .D {
|
|
player_pos.x += 10
|
|
}
|
|
}
|
|
}
|
|
|
|
cleanup :: proc "c" () {
|
|
context = ctx
|
|
sg.shutdown()
|
|
}
|
|
|
|
main :: proc() {
|
|
sapp.run(
|
|
{
|
|
init_cb = init,
|
|
frame_cb = frame,
|
|
cleanup_cb = cleanup,
|
|
event_cb = event,
|
|
width = 640,
|
|
height = 480,
|
|
window_title = "triangle",
|
|
icon = {sokol_default = true},
|
|
logger = {func = slog.func},
|
|
},
|
|
)
|
|
}
|