asdf
This commit is contained in:
parent
30de08b1ee
commit
28f0d737b1
18 changed files with 3472 additions and 493 deletions
537
src/main.odin
537
src/main.odin
|
|
@ -1,201 +1,12 @@
|
|||
package main
|
||||
|
||||
import "core:c"
|
||||
import "core:fmt"
|
||||
import "core:math"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:time"
|
||||
|
||||
import sdl "vendor:sdl3"
|
||||
import "rsmview"
|
||||
import "gndview"
|
||||
import "shared"
|
||||
|
||||
Vec3 :: [3]f32
|
||||
Mat4 :: [16]f32 // column-major
|
||||
|
||||
Camera :: struct {
|
||||
center: Vec3,
|
||||
distance: f32,
|
||||
orientation: Rotor,
|
||||
fov_deg: f32,
|
||||
}
|
||||
|
||||
Debug_State :: struct {
|
||||
enabled: bool,
|
||||
accum: f32,
|
||||
}
|
||||
|
||||
Rotor :: struct {
|
||||
s, x, y, z: f32,
|
||||
}
|
||||
|
||||
Cube_Instance :: struct {
|
||||
pos: Vec3,
|
||||
scale: f32,
|
||||
color: Vec3,
|
||||
}
|
||||
|
||||
Vertex :: struct {
|
||||
pos: Vec3,
|
||||
}
|
||||
|
||||
Push_Constants :: struct {
|
||||
mvp: Mat4,
|
||||
color: [4]f32,
|
||||
}
|
||||
|
||||
mat4_identity :: proc() -> Mat4 {
|
||||
return Mat4{1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1}
|
||||
}
|
||||
|
||||
mat4_mul :: proc(a, b: Mat4) -> Mat4 {
|
||||
r := Mat4{}
|
||||
for c in 0 ..< 4 {
|
||||
for row in 0 ..< 4 {
|
||||
r[c*4+row] =
|
||||
a[0*4+row] * b[c*4+0] +
|
||||
a[1*4+row] * b[c*4+1] +
|
||||
a[2*4+row] * b[c*4+2] +
|
||||
a[3*4+row] * b[c*4+3]
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
vec3_sub :: proc(a, b: Vec3) -> Vec3 {
|
||||
return Vec3{a[0] - b[0], a[1] - b[1], a[2] - b[2]}
|
||||
}
|
||||
|
||||
vec3_add :: proc(a, b: Vec3) -> Vec3 {
|
||||
return Vec3{a[0] + b[0], a[1] + b[1], a[2] + b[2]}
|
||||
}
|
||||
|
||||
vec3_scale :: proc(v: Vec3, s: f32) -> Vec3 {
|
||||
return Vec3{v[0] * s, v[1] * s, v[2] * s}
|
||||
}
|
||||
|
||||
vec3_dot :: proc(a, b: Vec3) -> f32 {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
|
||||
}
|
||||
|
||||
vec3_cross :: proc(a, b: Vec3) -> Vec3 {
|
||||
return Vec3{
|
||||
a[1] * b[2] - a[2] * b[1],
|
||||
a[2] * b[0] - a[0] * b[2],
|
||||
a[0] * b[1] - a[1] * b[0],
|
||||
}
|
||||
}
|
||||
|
||||
vec3_normalize :: proc(v: Vec3) -> Vec3 {
|
||||
len2 := vec3_dot(v, v)
|
||||
if len2 <= 0.000001 {
|
||||
return Vec3{0, 0, 0}
|
||||
}
|
||||
inv := 1.0 / math.sqrt(len2)
|
||||
return vec3_scale(v, inv)
|
||||
}
|
||||
|
||||
rotor_identity :: proc() -> Rotor {
|
||||
return Rotor{1, 0, 0, 0}
|
||||
}
|
||||
|
||||
rotor_normalize :: proc(r: Rotor) -> Rotor {
|
||||
len2 := r.s*r.s + r.x*r.x + r.y*r.y + r.z*r.z
|
||||
if len2 <= 0.000001 {
|
||||
return rotor_identity()
|
||||
}
|
||||
inv := 1.0 / math.sqrt(len2)
|
||||
return Rotor{r.s * inv, r.x * inv, r.y * inv, r.z * inv}
|
||||
}
|
||||
|
||||
rotor_mul :: proc(a, b: Rotor) -> Rotor {
|
||||
return Rotor{
|
||||
a.s*b.s - a.x*b.x - a.y*b.y - a.z*b.z,
|
||||
a.s*b.x + a.x*b.s + a.y*b.z - a.z*b.y,
|
||||
a.s*b.y - a.x*b.z + a.y*b.s + a.z*b.x,
|
||||
a.s*b.z + a.x*b.y - a.y*b.x + a.z*b.s,
|
||||
}
|
||||
}
|
||||
|
||||
rotor_from_axis_angle :: proc(axis: Vec3, angle: f32) -> Rotor {
|
||||
a := vec3_normalize(axis)
|
||||
h := angle * 0.5
|
||||
c := math.cos(h)
|
||||
s := math.sin(h)
|
||||
return Rotor{c, a[0] * s, a[1] * s, a[2] * s}
|
||||
}
|
||||
|
||||
rotate_vec3 :: proc(r: Rotor, v: Vec3) -> Vec3 {
|
||||
u := Vec3{r.x, r.y, r.z}
|
||||
t := vec3_scale(vec3_cross(u, v), 2.0)
|
||||
return vec3_add(v, vec3_add(vec3_scale(t, r.s), vec3_cross(u, t)))
|
||||
}
|
||||
|
||||
mat4_translate :: proc(p: Vec3) -> Mat4 {
|
||||
m := mat4_identity()
|
||||
m[12] = p[0]
|
||||
m[13] = p[1]
|
||||
m[14] = p[2]
|
||||
return m
|
||||
}
|
||||
|
||||
mat4_scale_uniform :: proc(s: f32) -> Mat4 {
|
||||
m := mat4_identity()
|
||||
m[0] = s
|
||||
m[5] = s
|
||||
m[10] = s
|
||||
return m
|
||||
}
|
||||
|
||||
mat4_perspective :: proc(fov_deg, aspect, z_near, z_far: f32) -> Mat4 {
|
||||
f := 1.0 / math.tan((fov_deg * 0.5) * (math.PI / 180.0))
|
||||
m := Mat4{}
|
||||
m[0] = f / aspect
|
||||
m[5] = f
|
||||
m[10] = (z_far + z_near) / (z_near - z_far)
|
||||
m[11] = -1
|
||||
m[14] = (2.0 * z_far * z_near) / (z_near - z_far)
|
||||
return m
|
||||
}
|
||||
|
||||
mat4_look_at :: proc(eye, target, up: Vec3) -> Mat4 {
|
||||
fwd := vec3_normalize(vec3_sub(target, eye))
|
||||
right := vec3_normalize(vec3_cross(fwd, up))
|
||||
real_up := vec3_cross(right, fwd)
|
||||
|
||||
m := mat4_identity()
|
||||
m[0] = right[0]
|
||||
m[1] = real_up[0]
|
||||
m[2] = -fwd[0]
|
||||
m[4] = right[1]
|
||||
m[5] = real_up[1]
|
||||
m[6] = -fwd[1]
|
||||
m[8] = right[2]
|
||||
m[9] = real_up[2]
|
||||
m[10] = -fwd[2]
|
||||
m[12] = -vec3_dot(right, eye)
|
||||
m[13] = -vec3_dot(real_up, eye)
|
||||
m[14] = vec3_dot(fwd, eye)
|
||||
return m
|
||||
}
|
||||
|
||||
camera_forward :: proc(c: Camera) -> Vec3 {
|
||||
return vec3_normalize(rotate_vec3(c.orientation, Vec3{0, 0, -1}))
|
||||
}
|
||||
|
||||
camera_right :: proc(c: Camera) -> Vec3 {
|
||||
return vec3_normalize(rotate_vec3(c.orientation, Vec3{1, 0, 0}))
|
||||
}
|
||||
|
||||
camera_up :: proc(c: Camera) -> Vec3 {
|
||||
return vec3_normalize(rotate_vec3(c.orientation, Vec3{0, 1, 0}))
|
||||
}
|
||||
|
||||
camera_position :: proc(c: Camera) -> Vec3 {
|
||||
return vec3_sub(c.center, vec3_scale(camera_forward(c), c.distance))
|
||||
}
|
||||
|
||||
read_file_or_fail :: proc(path: string) -> []u8 {
|
||||
file_bytes, err := os.read_entire_file(path, context.allocator)
|
||||
|
|
@ -206,7 +17,7 @@ read_file_or_fail :: proc(path: string) -> []u8 {
|
|||
return file_bytes
|
||||
}
|
||||
|
||||
create_gpu_shader :: proc(device: ^sdl.GPUDevice, path: string, stage: sdl.GPUShaderStage) -> ^sdl.GPUShader {
|
||||
create_gpu_shader :: proc(device: ^sdl.GPUDevice, path: string, stage: sdl.GPUShaderStage, num_samplers: u32) -> ^sdl.GPUShader {
|
||||
bytes := read_file_or_fail(path)
|
||||
if len(bytes) == 0 {
|
||||
return nil
|
||||
|
|
@ -218,7 +29,7 @@ create_gpu_shader :: proc(device: ^sdl.GPUDevice, path: string, stage: sdl.GPUSh
|
|||
entrypoint = cstring("main"),
|
||||
format = sdl.GPUShaderFormat{.SPIRV},
|
||||
stage = stage,
|
||||
num_samplers = 0,
|
||||
num_samplers = num_samplers,
|
||||
num_storage_textures = 0,
|
||||
num_storage_buffers = 0,
|
||||
num_uniform_buffers = 1,
|
||||
|
|
@ -233,41 +44,23 @@ create_gpu_shader :: proc(device: ^sdl.GPUDevice, path: string, stage: sdl.GPUSh
|
|||
return shader
|
||||
}
|
||||
|
||||
copy_vertices_to_gpu :: proc(device: ^sdl.GPUDevice, cmd: ^sdl.GPUCommandBuffer, vertices: []Vertex, dst: ^sdl.GPUBuffer) -> bool {
|
||||
byte_count := len(vertices) * size_of(Vertex)
|
||||
tb_info := sdl.GPUTransferBufferCreateInfo{
|
||||
usage = .UPLOAD,
|
||||
size = u32(byte_count),
|
||||
props = 0,
|
||||
}
|
||||
tb := sdl.CreateGPUTransferBuffer(device, tb_info)
|
||||
if tb == nil {
|
||||
fmt.println("CreateGPUTransferBuffer failed:", sdl.GetError())
|
||||
return false
|
||||
}
|
||||
defer sdl.ReleaseGPUTransferBuffer(device, tb)
|
||||
|
||||
mapped := sdl.MapGPUTransferBuffer(device, tb, false)
|
||||
if mapped == nil {
|
||||
fmt.println("MapGPUTransferBuffer failed:", sdl.GetError())
|
||||
return false
|
||||
}
|
||||
mem.copy_non_overlapping(mapped, raw_data(vertices), byte_count)
|
||||
sdl.UnmapGPUTransferBuffer(device, tb)
|
||||
|
||||
cp := sdl.BeginGPUCopyPass(cmd)
|
||||
if cp == nil {
|
||||
fmt.println("BeginGPUCopyPass failed:", sdl.GetError())
|
||||
return false
|
||||
}
|
||||
|
||||
src := sdl.GPUTransferBufferLocation{transfer_buffer = tb, offset = 0}
|
||||
dst_region := sdl.GPUBufferRegion{buffer = dst, offset = 0, size = u32(byte_count)}
|
||||
sdl.UploadToGPUBuffer(cp, src, dst_region, false)
|
||||
sdl.EndGPUCopyPass(cp)
|
||||
copy_data_to_gpu :: proc(
|
||||
device: ^sdl.GPUDevice,
|
||||
cmd: ^sdl.GPUCommandBuffer,
|
||||
vertices: []shared.Vertex,
|
||||
vert_buf: ^sdl.GPUBuffer,
|
||||
indices: []u16,
|
||||
ind_buf: ^sdl.GPUBuffer
|
||||
) -> bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
GPU_Vertex :: struct {
|
||||
position: [3]f32,
|
||||
uv: [2]f32,
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
if !sdl.Init(sdl.INIT_VIDEO) {
|
||||
fmt.println("SDL init failed:", sdl.GetError())
|
||||
|
|
@ -302,13 +95,13 @@ main :: proc() {
|
|||
return
|
||||
}
|
||||
|
||||
vertex_shader := create_gpu_shader(device, "shaders/cubes.vert.spv", .VERTEX)
|
||||
vertex_shader := create_gpu_shader(device, "shaders/cubes.vert.spv", .VERTEX, 0)
|
||||
if vertex_shader == nil {
|
||||
return
|
||||
}
|
||||
defer sdl.ReleaseGPUShader(device, vertex_shader)
|
||||
|
||||
fragment_shader := create_gpu_shader(device, "shaders/cubes.frag.spv", .FRAGMENT)
|
||||
fragment_shader := create_gpu_shader(device, "shaders/cubes.frag.spv", .FRAGMENT, 1)
|
||||
if fragment_shader == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -320,11 +113,12 @@ main :: proc() {
|
|||
return
|
||||
}
|
||||
|
||||
vb_descs := [1]sdl.GPUVertexBufferDescription{
|
||||
{slot = 0, pitch = size_of(Vertex), input_rate = .VERTEX, instance_step_rate = 0},
|
||||
vb_descs := []sdl.GPUVertexBufferDescription{
|
||||
{slot = 0, pitch = size_of(shared.Vertex), input_rate = .VERTEX, instance_step_rate = 0},
|
||||
}
|
||||
vattrs := [1]sdl.GPUVertexAttribute{
|
||||
{location = 0, buffer_slot = 0, format = .FLOAT3, offset = 0},
|
||||
vattrs := []sdl.GPUVertexAttribute{
|
||||
{location = 0, buffer_slot = 0, format = .FLOAT3, offset = u32(offset_of(shared.Vertex, pos))},
|
||||
{location = 1, buffer_slot = 0, format = .FLOAT2, offset = u32(offset_of(shared.Vertex, uv))},
|
||||
}
|
||||
|
||||
blend := sdl.GPUColorTargetBlendState{
|
||||
|
|
@ -342,15 +136,15 @@ main :: proc() {
|
|||
{format = color_format, blend_state = blend},
|
||||
}
|
||||
|
||||
pipeline_ci := sdl.GPUGraphicsPipelineCreateInfo{
|
||||
vertex_shader = vertex_shader,
|
||||
fragment_shader = fragment_shader,
|
||||
vertex_input_state = sdl.GPUVertexInputState{
|
||||
vertex_buffer_descriptions = &vb_descs[0],
|
||||
num_vertex_buffers = 1,
|
||||
vertex_attributes = &vattrs[0],
|
||||
num_vertex_attributes = 1,
|
||||
},
|
||||
pipeline_ci := sdl.GPUGraphicsPipelineCreateInfo{
|
||||
vertex_shader = vertex_shader,
|
||||
fragment_shader = fragment_shader,
|
||||
vertex_input_state = sdl.GPUVertexInputState{
|
||||
vertex_buffer_descriptions = &vb_descs[0],
|
||||
num_vertex_buffers = 1,
|
||||
vertex_attributes = &vattrs[0],
|
||||
num_vertex_attributes = 2,
|
||||
},
|
||||
primitive_type = .TRIANGLELIST,
|
||||
rasterizer_state = sdl.GPURasterizerState{
|
||||
fill_mode = .FILL,
|
||||
|
|
@ -374,15 +168,15 @@ main :: proc() {
|
|||
front_stencil_state = sdl.GPUStencilOpState{fail_op = .KEEP, pass_op = .KEEP, depth_fail_op = .KEEP, compare_op = .ALWAYS},
|
||||
compare_mask = 0,
|
||||
write_mask = 0,
|
||||
enable_depth_test = false,
|
||||
enable_depth_write = false,
|
||||
enable_stencil_test = false,
|
||||
enable_depth_test = true,
|
||||
enable_depth_write = true,
|
||||
enable_stencil_test = true,
|
||||
},
|
||||
target_info = sdl.GPUGraphicsPipelineTargetInfo{
|
||||
color_target_descriptions = &color_targets[0],
|
||||
num_color_targets = 1,
|
||||
depth_stencil_format = .INVALID,
|
||||
has_depth_stencil_target = false,
|
||||
depth_stencil_format = .D32_FLOAT,
|
||||
has_depth_stencil_target = true,
|
||||
},
|
||||
props = 0,
|
||||
}
|
||||
|
|
@ -394,249 +188,16 @@ main :: proc() {
|
|||
}
|
||||
defer sdl.ReleaseGPUGraphicsPipeline(device, pipeline)
|
||||
|
||||
vertices := [36]Vertex{
|
||||
{pos = Vec3{-0.5, -0.5, -0.5}}, {pos = Vec3{0.5, 0.5, -0.5}}, {pos = Vec3{0.5, -0.5, -0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, -0.5}}, {pos = Vec3{-0.5, 0.5, -0.5}}, {pos = Vec3{0.5, 0.5, -0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, 0.5}}, {pos = Vec3{0.5, -0.5, 0.5}}, {pos = Vec3{0.5, 0.5, 0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, 0.5}}, {pos = Vec3{0.5, 0.5, 0.5}}, {pos = Vec3{-0.5, 0.5, 0.5}},
|
||||
{pos = Vec3{-0.5, 0.5, 0.5}}, {pos = Vec3{-0.5, 0.5, -0.5}}, {pos = Vec3{-0.5, -0.5, -0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, -0.5}}, {pos = Vec3{-0.5, -0.5, 0.5}}, {pos = Vec3{-0.5, 0.5, 0.5}},
|
||||
{pos = Vec3{0.5, 0.5, 0.5}}, {pos = Vec3{0.5, -0.5, -0.5}}, {pos = Vec3{0.5, 0.5, -0.5}},
|
||||
{pos = Vec3{0.5, -0.5, -0.5}}, {pos = Vec3{0.5, 0.5, 0.5}}, {pos = Vec3{0.5, -0.5, 0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, -0.5}}, {pos = Vec3{0.5, -0.5, -0.5}}, {pos = Vec3{0.5, -0.5, 0.5}},
|
||||
{pos = Vec3{-0.5, -0.5, -0.5}}, {pos = Vec3{0.5, -0.5, 0.5}}, {pos = Vec3{-0.5, -0.5, 0.5}},
|
||||
{pos = Vec3{-0.5, 0.5, -0.5}}, {pos = Vec3{0.5, 0.5, 0.5}}, {pos = Vec3{0.5, 0.5, -0.5}},
|
||||
{pos = Vec3{-0.5, 0.5, -0.5}}, {pos = Vec3{-0.5, 0.5, 0.5}}, {pos = Vec3{0.5, 0.5, 0.5}},
|
||||
}
|
||||
|
||||
vbuf_info := sdl.GPUBufferCreateInfo{
|
||||
usage = sdl.GPUBufferUsageFlags{.VERTEX},
|
||||
size = u32(len(vertices) * size_of(Vertex)),
|
||||
props = 0,
|
||||
}
|
||||
vbuf := sdl.CreateGPUBuffer(device, vbuf_info)
|
||||
if vbuf == nil {
|
||||
fmt.println("CreateGPUBuffer failed:", sdl.GetError())
|
||||
return
|
||||
}
|
||||
defer sdl.ReleaseGPUBuffer(device, vbuf)
|
||||
|
||||
{
|
||||
setup_cmd := sdl.AcquireGPUCommandBuffer(device)
|
||||
if setup_cmd == nil {
|
||||
fmt.println("AcquireGPUCommandBuffer failed:", sdl.GetError())
|
||||
return
|
||||
}
|
||||
if !copy_vertices_to_gpu(device, setup_cmd, vertices[:], vbuf) {
|
||||
_ = sdl.CancelGPUCommandBuffer(setup_cmd)
|
||||
return
|
||||
}
|
||||
if !sdl.SubmitGPUCommandBuffer(setup_cmd) {
|
||||
fmt.println("SubmitGPUCommandBuffer (setup) failed:", sdl.GetError())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
init_yaw := rotor_from_axis_angle(Vec3{0, 1, 0}, 0.9)
|
||||
init_right := rotate_vec3(init_yaw, Vec3{1, 0, 0})
|
||||
init_pitch := rotor_from_axis_angle(init_right, -0.45)
|
||||
|
||||
camera := Camera{
|
||||
center = Vec3{0, 0.5, 0},
|
||||
distance = 8,
|
||||
orientation = rotor_normalize(rotor_mul(init_pitch, init_yaw)),
|
||||
fov_deg = 60,
|
||||
}
|
||||
|
||||
cubes := []Cube_Instance{
|
||||
{pos = Vec3{0, 0, 0}, scale = 1.0, color = Vec3{0.95, 0.45, 0.20}},
|
||||
{pos = Vec3{2, 0.5, -1}, scale = 0.8, color = Vec3{0.20, 0.70, 0.95}},
|
||||
{pos = Vec3{-2, -0.2, 1.5}, scale = 1.2, color = Vec3{0.85, 0.85, 0.30}},
|
||||
{pos = Vec3{1.0, 1.4, 2.0}, scale = 0.6, color = Vec3{0.40, 0.95, 0.60}},
|
||||
}
|
||||
|
||||
running := true
|
||||
last := time.tick_now()
|
||||
left_down := false
|
||||
middle_down := false
|
||||
debug := Debug_State{}
|
||||
|
||||
for running {
|
||||
now := time.tick_now()
|
||||
dt := f32(time.duration_seconds(time.tick_diff(last, now)))
|
||||
last = now
|
||||
|
||||
event: sdl.Event
|
||||
for sdl.PollEvent(&event) {
|
||||
#partial switch event.type {
|
||||
case .QUIT:
|
||||
running = false
|
||||
case .MOUSE_BUTTON_DOWN:
|
||||
switch event.button.button {
|
||||
case sdl.BUTTON_LEFT:
|
||||
left_down = true
|
||||
case sdl.BUTTON_MIDDLE:
|
||||
middle_down = true
|
||||
}
|
||||
case .MOUSE_BUTTON_UP:
|
||||
switch event.button.button {
|
||||
case sdl.BUTTON_LEFT:
|
||||
left_down = false
|
||||
case sdl.BUTTON_MIDDLE:
|
||||
middle_down = false
|
||||
}
|
||||
case .MOUSE_WHEEL:
|
||||
camera.distance = math.clamp(camera.distance - event.wheel.y * 0.7, 1.5, 80.0)
|
||||
case .KEY_DOWN:
|
||||
if event.key.key == sdl.K_ESCAPE {
|
||||
running = false
|
||||
} else if event.key.scancode == sdl.Scancode.F1 && !event.key.repeat {
|
||||
debug.enabled = !debug.enabled
|
||||
fmt.println("debug:", debug.enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x_rel: f32 = 0
|
||||
y_rel: f32 = 0
|
||||
_ = sdl.GetRelativeMouseState(&x_rel, &y_rel)
|
||||
|
||||
if left_down {
|
||||
yaw_r := rotor_from_axis_angle(Vec3{0, 1, 0}, -x_rel * 0.006)
|
||||
q1 := rotor_normalize(rotor_mul(yaw_r, camera.orientation))
|
||||
|
||||
right_axis := vec3_normalize(rotate_vec3(q1, Vec3{1, 0, 0}))
|
||||
pitch_r := rotor_from_axis_angle(right_axis, -y_rel * 0.006)
|
||||
q2 := rotor_normalize(rotor_mul(pitch_r, q1))
|
||||
|
||||
fwd2 := camera_forward(Camera{center = camera.center, distance = camera.distance, orientation = q2, fov_deg = camera.fov_deg})
|
||||
if math.abs(vec3_dot(fwd2, Vec3{0, 1, 0})) < 0.98 {
|
||||
camera.orientation = q2
|
||||
} else {
|
||||
camera.orientation = q1
|
||||
}
|
||||
}
|
||||
|
||||
if middle_down {
|
||||
right := camera_right(camera)
|
||||
up := camera_up(camera)
|
||||
pan_speed := 0.008 * camera.distance
|
||||
camera.center = vec3_add(camera.center, vec3_scale(right, -x_rel * pan_speed))
|
||||
camera.center = vec3_add(camera.center, vec3_scale(up, y_rel * pan_speed))
|
||||
}
|
||||
|
||||
keys := sdl.GetKeyboardState(nil)
|
||||
forward := camera_forward(camera)
|
||||
right := camera_right(camera)
|
||||
up := camera_up(camera)
|
||||
move_speed := camera.distance * dt * 1.4
|
||||
|
||||
if keys[sdl.Scancode.W] {
|
||||
camera.center = vec3_add(camera.center, vec3_scale(forward, move_speed))
|
||||
}
|
||||
if keys[sdl.Scancode.S] {
|
||||
camera.center = vec3_add(camera.center, vec3_scale(forward, -move_speed))
|
||||
}
|
||||
if keys[sdl.Scancode.A] {
|
||||
camera.center = vec3_add(camera.center, vec3_scale(right, -move_speed))
|
||||
}
|
||||
if keys[sdl.Scancode.D] {
|
||||
camera.center = vec3_add(camera.center, vec3_scale(right, move_speed))
|
||||
}
|
||||
|
||||
if debug.enabled {
|
||||
debug.accum += dt
|
||||
if debug.accum >= 0.2 {
|
||||
debug.accum = 0
|
||||
eye := camera_position(camera)
|
||||
fmt.println("cam eye:", eye,
|
||||
"center:", camera.center,
|
||||
"fwd:", forward,
|
||||
"right:", right,
|
||||
"up:", up)
|
||||
}
|
||||
}
|
||||
|
||||
w: c.int = 0
|
||||
h: c.int = 0
|
||||
sdl.GetWindowSize(window, &w, &h)
|
||||
if w <= 0 || h <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cmd := sdl.AcquireGPUCommandBuffer(device)
|
||||
if cmd == nil {
|
||||
fmt.println("AcquireGPUCommandBuffer failed:", sdl.GetError())
|
||||
break
|
||||
}
|
||||
|
||||
swap_tex: ^sdl.GPUTexture
|
||||
swap_w: sdl.Uint32 = 0
|
||||
swap_h: sdl.Uint32 = 0
|
||||
if !sdl.WaitAndAcquireGPUSwapchainTexture(cmd, window, &swap_tex, &swap_w, &swap_h) {
|
||||
fmt.println("WaitAndAcquireGPUSwapchainTexture failed:", sdl.GetError())
|
||||
_ = sdl.CancelGPUCommandBuffer(cmd)
|
||||
break
|
||||
}
|
||||
|
||||
if swap_tex == nil {
|
||||
if !sdl.SubmitGPUCommandBuffer(cmd) {
|
||||
fmt.println("SubmitGPUCommandBuffer failed:", sdl.GetError())
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
clear := sdl.FColor{0.08, 0.09, 0.12, 1.0}
|
||||
cti := sdl.GPUColorTargetInfo{
|
||||
texture = swap_tex,
|
||||
mip_level = 0,
|
||||
layer_or_depth_plane = 0,
|
||||
clear_color = clear,
|
||||
load_op = .CLEAR,
|
||||
store_op = .STORE,
|
||||
resolve_texture = nil,
|
||||
resolve_mip_level = 0,
|
||||
resolve_layer = 0,
|
||||
cycle = false,
|
||||
cycle_resolve_texture = false,
|
||||
}
|
||||
|
||||
rp := sdl.BeginGPURenderPass(cmd, &cti, 1, nil)
|
||||
if rp == nil {
|
||||
fmt.println("BeginGPURenderPass failed:", sdl.GetError())
|
||||
_ = sdl.CancelGPUCommandBuffer(cmd)
|
||||
break
|
||||
}
|
||||
|
||||
vp := sdl.GPUViewport{x = 0, y = 0, w = f32(swap_w), h = f32(swap_h), min_depth = 0, max_depth = 1}
|
||||
sdl.SetGPUViewport(rp, vp)
|
||||
sdl.BindGPUGraphicsPipeline(rp, pipeline)
|
||||
vb_binding := sdl.GPUBufferBinding{buffer = vbuf, offset = 0}
|
||||
sdl.BindGPUVertexBuffers(rp, 0, &vb_binding, 1)
|
||||
|
||||
aspect := f32(swap_w) / f32(swap_h)
|
||||
proj := mat4_perspective(camera.fov_deg, aspect, 0.1, 300.0)
|
||||
view := mat4_look_at(camera_position(camera), camera.center, camera_up(camera))
|
||||
vp_mat := mat4_mul(proj, view)
|
||||
|
||||
for cube in cubes {
|
||||
model := mat4_mul(mat4_translate(cube.pos), mat4_scale_uniform(cube.scale))
|
||||
pc := Push_Constants{}
|
||||
pc.mvp = mat4_mul(vp_mat, model)
|
||||
pc.color = [4]f32{cube.color[0], cube.color[1], cube.color[2], 1.0}
|
||||
sdl.PushGPUVertexUniformData(cmd, 0, &pc, u32(size_of(Push_Constants)))
|
||||
sdl.PushGPUFragmentUniformData(cmd, 0, &pc, u32(size_of(Push_Constants)))
|
||||
sdl.DrawGPUPrimitives(rp, 36, 1, 0, 0)
|
||||
}
|
||||
|
||||
sdl.EndGPURenderPass(rp)
|
||||
|
||||
if !sdl.SubmitGPUCommandBuffer(cmd) {
|
||||
fmt.println("SubmitGPUCommandBuffer failed:", sdl.GetError())
|
||||
break
|
||||
|
||||
pipeline_create_info := sdl.GPUGraphicsPipelineCreateInfo{
|
||||
primitive_type = .TRIANGLELIST,
|
||||
rasterizer_state = {
|
||||
fill_mode = .LINE,
|
||||
cull_mode = .FRONT,
|
||||
}
|
||||
}
|
||||
|
||||
gndview.runGame(window, device, pipeline)
|
||||
|
||||
_ = sdl.WaitForGPUIdle(device)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue