aboutsummaryrefslogtreecommitdiff
path: root/src/draw
diff options
context:
space:
mode:
authorXander Swan <no email>2025-12-17 18:38:21 -0500
committerXander Swan <no email>2025-12-17 18:38:21 -0500
commitce4d64bd41937d7dff18ca607122188dc338d696 (patch)
treead5f7cbdffcc1478883cbca0ea7b8365b2108d0a /src/draw
parent87a7a010ecbe2cb99fedf44d0cac31e2efae86d5 (diff)
switch to raylib, update some structure
Diffstat (limited to 'src/draw')
-rw-r--r--src/draw/draw.odin316
-rw-r--r--src/draw/framebuffer.odin94
-rw-r--r--src/draw/sprite.odin44
3 files changed, 86 insertions, 368 deletions
diff --git a/src/draw/draw.odin b/src/draw/draw.odin
index 6c013de..6761b36 100644
--- a/src/draw/draw.odin
+++ b/src/draw/draw.odin
@@ -1,12 +1,9 @@
package draw
-import "core:math/linalg"
import "core:math"
+import "core:c"
-import sg "shared:sokol/gfx"
-import sapp "shared:sokol/app"
-import sdtxt "shared:sokol/debugtext"
-import sglue "shared:sokol/glue"
+import rl "vendor:raylib"
Vec2 :: [2]f32
Vec3 :: [3]f32
@@ -23,238 +20,69 @@ Color :: [4]f32
SCREEN_WIDTH :: 480
SCREEN_HEIGHT :: 360
-Renderer :: struct {
- screen: Framebuffer,
-
- window_pass: struct {
- pass_action: sg.Pass_Action,
- pipe: sg.Pipeline,
- },
-
- view: sg.View,
- sampler: sg.Sampler,
-
- white_1x1: sg.Image,
-
- projection: Mat4,
- current_batch: Batch,
-
+renderer: struct {
+ screen: rl.RenderTexture2D,
tint: Color,
}
-Vertex :: struct {
- pos: Vec2,
- uv: Vec2,
- color: Color,
-}
-
-Batch :: struct {
- img: sg.Image,
- vertices: [dynamic]Vertex,
-}
-
-init :: proc(r: ^Renderer) {
- r.window_pass.pipe = sg.make_pipeline({
- shader = sg.make_shader(default_shader_desc(sg.query_backend())),
- layout = {
- attrs = {
- ATTR_default_vposition = {format = .FLOAT2},
- ATTR_default_vuv = {format = .FLOAT2},
- ATTR_default_vcolor = {format = .FLOAT4},
- },
- },
- })
-
- r.window_pass.pass_action = {
- colors = {
- 0 = {load_action = .CLEAR, clear_value = {0, 0, 0, 1}},
- },
+@(private)
+color_to_rl :: proc(col: Color) -> rl.Color {
+ return rl.Color{
+ u8(col.r * 255),
+ u8(col.g * 255),
+ u8(col.b * 255),
+ u8(col.a * 255),
}
-
- white := [?]u8{255, 255, 255, 255}
-
- r.white_1x1 = sg.make_image({
- width = 1,
- height = 1,
- data = {
- mip_levels = {
- 0 = {ptr=&white, size=size_of(white)},
- },
- },
- })
-
- init_framebuffer(
- &r.screen,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- Color{0.2, 0.2, 0.2, 1.0},
- )
-
- r.view = sg.alloc_view()
- r.sampler = sg.make_sampler({})
-
- r.tint = {1, 1, 1, 1}
-
- sdtxt.set_context(sdtxt.make_context({
- color_format = .RGBA8,
- depth_format = .NONE,
- sample_count = 1,
- }))
-}
-
-deinit :: proc(r: ^Renderer) {
- delete_batch(&r.current_batch)
-
- sg.destroy_pipeline(r.window_pass.pipe)
-
- sg.destroy_view(r.view)
- sg.destroy_sampler(r.sampler)
-
- destroy_framebuffer(&r.screen)
}
-new_frame :: proc(r: ^Renderer) {
- framebuffer_draw_start(r.screen)
- r.projection = linalg.matrix_ortho3d(
- 0, f32(SCREEN_WIDTH),
- f32(SCREEN_HEIGHT), 0,
- 0.0, 1.0,
- )
+init :: proc() {
+ renderer.screen = rl.LoadRenderTexture(SCREEN_WIDTH, SCREEN_HEIGHT)
+ renderer.tint = Color{1, 1, 1, 1}
}
-end_frame :: proc(r: ^Renderer) {
- flush_current_batch(r)
- clear(&r.current_batch.vertices)
-
- sdtxt.draw()
-
- framebuffer_draw_end(r.screen)
-
- r.projection = linalg.matrix_ortho3d(
- 0, f32(sapp.width()),
- 0, f32(sapp.height()),
- 0.0, 1.0,
- )
-
- sg.begin_pass({action=r.window_pass.pass_action, swapchain=sglue.swapchain()})
- sg.apply_pipeline(r.window_pass.pipe)
-
- scale := math.min(
- f32(sapp.height()) / f32(SCREEN_HEIGHT) ,
- f32(sapp.width()) / f32(SCREEN_WIDTH),
- )
- screen_start := Vec2{
- (f32(sapp.width()) - (SCREEN_WIDTH * scale)) / 2,
- (f32(sapp.height()) - (SCREEN_HEIGHT * scale)) / 2,
- }
-
- texture(
- r,
- r.screen.img,
- screen_start,
- scale = Vec2{scale, scale},
- )
-
- flush_current_batch(r)
- clear(&r.current_batch.vertices)
-
- sg.end_pass()
-
- sg.commit()
+deinit :: proc() {
+ rl.UnloadRenderTexture(renderer.screen)
}
-@(private)
-delete_batch :: proc(batch: ^Batch) {
- delete(batch.vertices)
+new_frame :: proc() {
+ rl.BeginTextureMode(renderer.screen)
+ rl.ClearBackground(color_to_rl(Color{0.2, 0.2, 0.2, 1}))
}
-flush_current_batch :: proc(r: ^Renderer) {
- batch := r.current_batch
-
- if len(batch.vertices) == 0 {
- return
- }
-
- buffer := sg.make_buffer({
- data = {
- ptr = &r.current_batch.vertices[0],
- size = size_of(Vertex) * len(r.current_batch.vertices),
- },
- })
-
- sg.init_view(r.view, {
- texture = {
- image = r.current_batch.img,
- },
- })
-
- binds: sg.Bindings
-
- binds.vertex_buffers[0] = buffer
- binds.views[VIEW_tex] = r.view
- binds.samplers[SMP_tex_samp] = r.sampler
+end_frame :: proc() {
+ rl.EndTextureMode()
- uniforms := Default_Vs_Params {
- projection = transmute([16]f32)r.projection,
- }
-
- sg.apply_bindings(binds)
- sg.apply_uniforms(UB_default_vs_params, {ptr=&uniforms, size=size_of(uniforms)})
-
- sg.draw(0, len(r.current_batch.vertices), 1)
-
- sg.uninit_view(r.view)
-
- sg.destroy_buffer(buffer)
-}
+ rl.BeginDrawing()
+ {
+ rl.ClearBackground(color_to_rl(Color{0, 0, 0, 1}))
+ scale := math.min(
+ f32(rl.GetScreenWidth()) / f32(SCREEN_WIDTH),
+ f32(rl.GetScreenHeight()) / f32(SCREEN_HEIGHT),
+ )
+ screen_start := Vec2{
+ (f32(rl.GetScreenWidth()) - (SCREEN_WIDTH * scale)) / 2,
+ (f32(rl.GetScreenHeight()) - (SCREEN_HEIGHT * scale)) / 2,
+ }
-@(private)
-new_batch :: proc(batch: ^Batch, img: sg.Image) {
- clear(&batch.vertices)
- batch.img = img
-}
-
-request_batch :: proc(r: ^Renderer, img: sg.Image) -> ^Batch {
- if len(r.current_batch.vertices) == 0 {
- new_batch(&r.current_batch, img)
- } else if img != r.current_batch.img {
- flush_current_batch(r)
- new_batch(&r.current_batch, img)
+ texture_full(
+ renderer.screen.texture,
+ screen_start,
+ scale = Vec2{scale, scale},
+ )
}
-
- return &r.current_batch
-}
-
-@(private)
-batch_vertices :: proc(
- b: ^Batch,
- vertices: []Vertex,
-) {
- append(&b.vertices, ..vertices)
+ rl.EndDrawing()
}
rect :: proc(
- r: ^Renderer,
rect: Rect,
- color := Color{1, 1, 1, 1},
) {
assert(rect.size.x > 0 && rect.size.y > 0)
- batch := request_batch(r, r.white_1x1)
-
- start := rect.start
- end := rect.start + rect.size
-
- vertices := [?]Vertex{
- {start, {0, 0}, r.tint},
- {{end.x, start.y}, {1, 0}, r.tint},
- {{start.x, end.y}, {0, 1}, r.tint},
-
- {{end.x, start.y}, {1, 0}, r.tint},
- {{start.x, end.y}, {0, 1}, r.tint},
- {end, {1, 1}, r.tint},
- }
-
- batch_vertices(batch, vertices[:])
+ rl.DrawRectangle(
+ c.int(rect.start.x), c.int(rect.start.y),
+ c.int(rect.size.x), c.int(rect.size.y),
+ color_to_rl(renderer.tint),
+ )
}
texture :: proc{
@@ -263,52 +91,42 @@ texture :: proc{
}
texture_quad :: proc(
- r: ^Renderer,
- img: sg.Image,
+ img: rl.Texture2D,
quad: Rect,
- pos: Vec2,
+ position: Vec2,
offset := Vec2{0, 0},
+ rotation: f32 = 0,
scale := Vec2{1, 1},
) {
- assert(quad.size.x > 0 && quad.size.y > 0)
+ // assert(quad.size.x > 0 && quad.size.y > 0)
- batch := request_batch(r, img)
-
- top_left := pos + offset * scale
- bot_rght := top_left + quad.size * scale
+ quad := quad
+ quad.size *= scale
- size := Vec2{
- f32(sg.query_image_width(img)),
- f32(sg.query_image_height(img)),
- }
-
- uv_start := quad.start / size
- uv_end := (quad.start + quad.size) / size
-
- // |/|
- vertices := [?]Vertex{
- {top_left, uv_start, r.tint},
- {{bot_rght.x, top_left.y}, {uv_end.x, uv_start.y}, r.tint},
- {{top_left.x, bot_rght.y}, {uv_start.x, uv_end.y }, r.tint},
-
- {{bot_rght.x, top_left.y}, {uv_end.x, uv_start.y}, r.tint},
- {{top_left.x, bot_rght.y}, {uv_start.x, uv_end.y }, r.tint},
- {bot_rght, uv_end, r.tint},
- }
-
- batch_vertices(batch, vertices[:])
+ rl.DrawTexturePro(
+ img,
+ transmute(rl.Rectangle)quad,
+ rl.Rectangle{
+ position.x, position.y,
+ quad.size.x * scale.x, quad.size.y * scale.y,
+ },
+ offset,
+ rotation,
+ color_to_rl(renderer.tint),
+ )
}
texture_full :: proc(
- r: ^Renderer,
- img: sg.Image,
- pos: Vec2,
+ img: rl.Texture2D,
+ position: Vec2,
offset := Vec2{0, 0},
+ rotation: f32 = 0,
scale := Vec2{1, 1},
) {
size := Vec2{
- f32(sg.query_image_width(img)),
- f32(sg.query_image_height(img)),
+ f32(img.width),
+ -f32(img.height),
}
- texture_quad(r, img, Rect{Vec2{0, 0}, size}, pos, offset, scale)
+
+ texture_quad(img, Rect{Vec2{0, 0}, size}, position, offset, rotation, scale)
}
diff --git a/src/draw/framebuffer.odin b/src/draw/framebuffer.odin
deleted file mode 100644
index cd7848b..0000000
--- a/src/draw/framebuffer.odin
+++ /dev/null
@@ -1,94 +0,0 @@
-package draw
-
-import sg "shared:sokol/gfx"
-
-Framebuffer :: struct {
- img: sg.Image,
- view: sg.View,
- pipe: sg.Pipeline,
- pass: sg.Pass,
-}
-
-init_framebuffer :: proc(
- fb: ^Framebuffer,
- width: i32,
- height: i32,
- clear_color := Color{0, 0, 0, 0},
-) {
- fb.pipe = sg.make_pipeline({
- shader = sg.make_shader(default_shader_desc(sg.query_backend())),
- layout = {
- attrs = {
- ATTR_default_vposition = {format = .FLOAT2},
- ATTR_default_vuv = {format = .FLOAT2},
- ATTR_default_vcolor = {format = .FLOAT4},
- },
- },
- depth = {
- pixel_format = .NONE,
- },
- sample_count = 1,
- colors = {
- 0 = {
- pixel_format = .RGBA8,
- blend = {
- enabled = true,
- src_factor_rgb = .SRC_ALPHA,
- dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
- src_factor_alpha = .ONE,
- dst_factor_alpha = .ZERO,
- },
- },
- },
- })
-
- fb.img = sg.make_image({
- usage = {
- color_attachment = true,
- },
-
- width = width,
- height = height,
-
- pixel_format = .RGBA8,
- sample_count = 1,
- })
-
- fb.view = sg.make_view({
- texture = {
- image = fb.img,
- },
- })
-
- fb.pass = {
- attachments = {
- colors = {
- 0 = sg.make_view({
- color_attachment = {
- image = fb.img,
- },
- }),
- },
- },
- action = {
- colors = {
- 0 = {load_action = .CLEAR, clear_value = transmute(sg.Color)clear_color},
- },
- },
- }
-}
-
-destroy_framebuffer :: proc(fb: ^Framebuffer) {
- sg.destroy_pipeline(fb.pipe)
- sg.destroy_view(fb.view)
- sg.destroy_image(fb.img)
-}
-
-framebuffer_draw_start :: proc(fb: Framebuffer) {
- sg.begin_pass(fb.pass)
- sg.apply_pipeline(fb.pipe)
-}
-
-framebuffer_draw_end :: proc(fb: Framebuffer) {
- sg.end_pass()
-}
diff --git a/src/draw/sprite.odin b/src/draw/sprite.odin
index 59d1c32..a6a109b 100644
--- a/src/draw/sprite.odin
+++ b/src/draw/sprite.odin
@@ -1,13 +1,14 @@
package draw
import "core:log"
-import "core:image"
-import "core:image/qoi"
+// import "core:image"
+import "core:mem"
+// import "core:image/qoi"
-import sg "shared:sokol/gfx"
+import rl "vendor:raylib"
Sprite :: struct {
- image: sg.Image,
+ image: rl.Texture2D,
anim: Animation,
active_anim: u32,
frame_time: f32,
@@ -18,6 +19,7 @@ Sprite :: struct {
pos: Vec2,
offset: Vec2,
+ rotation: f32,
scale: Vec2,
}
@@ -26,26 +28,15 @@ init_sprite :: proc(
path: string,
anim: Animation = {},
) -> bool {
- img, img_err := qoi.load_from_file(path)
- if img_err != nil {
- log.error("could not load image")
- return false
- }
- defer image.destroy(img)
+ byte_path := make([]u8, len(path) + 1, context.temp_allocator)
+ copy(byte_path, path)
+ byte_path[len(path)] = 0
- sprite.image = sg.make_image({
- width = i32(img.width),
- height = i32(img.height),
- data = {
- mip_levels = {
- 0 = {ptr=&img.pixels.buf[0], size=len(img.pixels.buf)},
- },
- },
- })
+ sprite.image = rl.LoadTexture(transmute(cstring)&byte_path[0])
sprite.anim = anim
- sprite.width = i32(img.width / len(sprite.anim.frames))
- sprite.height = i32(img.height)
+ sprite.width = i32(int(sprite.image.width) / len(sprite.anim.frames))
+ sprite.height = i32(sprite.image.height)
sprite.scale = Vec2{1, 1}
@@ -53,12 +44,16 @@ init_sprite :: proc(
"loaded sprite '%v' %vx%v (%vx%v)",
path,
sprite.width, sprite.height,
- img.width, img.height,
+ sprite.image.width, sprite.image.height,
)
return true
}
+destroy_sprite :: proc(sprite: Sprite) {
+ rl.UnloadTexture(sprite.image)
+}
+
set_sprite_active_tag :: proc(sprite: ^Sprite, tag_name: string) {
sprite.active_anim = sprite.anim.frame_tags_indices[tag_name]
}
@@ -84,13 +79,11 @@ update_sprite :: proc(sprite: ^Sprite, dt: f32) {
}
sprite :: proc(
- r: ^Renderer,
sprite: Sprite,
) {
frame := sprite.anim.frames[sprite.current_frame]
- texture(
- r,
+ texture_quad(
sprite.image,
Rect {
Vec2{f32(frame.rect.x), f32(frame.rect.y)},
@@ -98,6 +91,7 @@ sprite :: proc(
},
sprite.pos,
sprite.offset,
+ sprite.rotation,
sprite.scale,
)
}