Initial Camera implementation

This commit is contained in:
2026-08-01 23:53:08 -07:00
committed by GitHub
4 changed files with 29 additions and 7 deletions
+3
View File
@@ -35,6 +35,7 @@ App :: struct {
transfer_buffer: ^sdl.GPUTransferBuffer, transfer_buffer: ^sdl.GPUTransferBuffer,
draw_list: [dynamic]Queued_Sprite, draw_list: [dynamic]Queued_Sprite,
clear_color: sdl.FColor, clear_color: sdl.FColor,
camera: Camera,
} }
Shader_Backend :: enum { Shader_Backend :: enum {
@@ -124,6 +125,8 @@ init :: proc(app: ^App, title: cstring, width, height: i32) -> bool {
app.draw_list = make([dynamic]Queued_Sprite) app.draw_list = make([dynamic]Queued_Sprite)
app.camera = camera_default()
return true return true
} }
+17
View File
@@ -0,0 +1,17 @@
package engine
Camera :: struct {
position: Vec2,
anchor: Vec2,
}
camera_default :: proc() -> Camera {
return Camera{position = {0, 0}, anchor = {0.5, 0.5}}
}
world_to_screen :: proc(cam: Camera, world: Vec2, viewport: Vec2) -> Vec2 {
return {
world.x - cam.position.x + viewport.x * cam.anchor[0],
world.y - cam.position.y + viewport.y * cam.anchor[1],
}
}
+7 -7
View File
@@ -109,14 +109,17 @@ draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
trim_y := f32(frame.trim_offset[1]) trim_y := f32(frame.trim_offset[1])
pivot := sprite.data.def.pivot pivot := sprite.data.def.pivot
canvas_top := sprite.position.y - src_h * pivot[1] viewport := Vec2{f32(app.swapchain_w), f32(app.swapchain_h)}
feet := world_to_screen(app.camera, sprite.position, viewport)
canvas_top := feet.y - src_h * pivot[1]
x0_px, y0_px: f32 x0_px, y0_px: f32
if sprite.flip_x { if sprite.flip_x {
canvas_left := sprite.position.x - (1.0 - pivot[0]) * src_w canvas_left := feet.x - (1.0 - pivot[0]) * src_w
x0_px = canvas_left + (src_w - trim_x - fw) x0_px = canvas_left + (src_w - trim_x - fw)
y0_px = canvas_top + trim_y y0_px = canvas_top + trim_y
} else { } else {
canvas_left := sprite.position.x - src_w * pivot[0] canvas_left := feet.x - src_w * pivot[0]
x0_px = canvas_left + trim_x x0_px = canvas_left + trim_x
y0_px = canvas_top + trim_y y0_px = canvas_top + trim_y
} }
@@ -147,10 +150,7 @@ draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
{pos = p3, uv = {u0, v1}}, {pos = p3, uv = {u0, v1}},
} }
append( append(&app.draw_list, Queued_Sprite{texture = sprite.data.texture, verts = verts})
&app.draw_list,
Queued_Sprite{texture = sprite.data.texture, verts = verts},
)
} }
set_sprite_clip :: proc(sprite: ^Sprite, clip: string) { set_sprite_clip :: proc(sprite: ^Sprite, clip: string) {
+2
View File
@@ -39,6 +39,8 @@ main :: proc() {
} else { } else {
eng.set_sprite_clip(&toad, "idle") eng.set_sprite_clip(&toad, "idle")
} }
app.camera.position = toad.position - {0, 100}
eng.update_sprite(&toad, dt) eng.update_sprite(&toad, dt)
eng.begin_frame(&app) eng.begin_frame(&app)