Files
odin-iso-test/src3/gfx.odin
T
2026-08-05 16:57:44 +03:00

158 lines
3.0 KiB
Odin

package main
import rl "vendor:raylib"
Graphics :: union {
GfxNone,
GfxCircle,
GfxRect,
GfxRing,
GfxCircleLines,
GfxAnimatedSprite,
GfxTexture,
}
GfxNone :: struct {}
GfxCircle :: struct {
pos: rl.Vector2,
radius: f32,
color: rl.Color,
}
GfxRect :: struct {
pos: rl.Vector2,
size: rl.Vector2,
color: rl.Color,
}
GfxRing :: struct {
pos: rl.Vector2,
inner_radius: f32,
outer_radius: f32,
color: rl.Color,
}
GfxCircleLines :: struct {
pos: rl.Vector2,
radius: f32,
color: rl.Color,
}
GfxTexture :: struct {}
GfxAnimatedSprite :: struct {
pos: rl.Vector2,
atlas: ^Atlas,
frame: i32,
speed: f32,
current_time: f32,
update: proc(g: ^GfxAnimatedSprite, dt: f32),
}
PlayerTexFiles :: enum {
IDLE,
RUN,
RUN_ATTACK,
WALK,
WALK_ATTACK,
ATTACK,
}
Atlas :: struct {
tex: rl.Texture2D,
frame_size: rl.Vector2,
cols: i32,
rows: i32,
frames: i32,
get_offset: proc(a: ^Atlas, f: i32) -> rl.Vector2,
}
GraphicsAssetStore :: struct {
playerTex: map[PlayerTexFiles]Atlas,
}
player_atlas_get :: proc(g: ^GraphicsAssetStore, f: PlayerTexFiles) -> ^Atlas {
return &g.playerTex[f]
}
gfx_init :: proc() -> GraphicsAssetStore {
st := GraphicsAssetStore{}
st.playerTex = make(map[PlayerTexFiles]Atlas)
st.playerTex[.IDLE] = init_atlas(
texture_path = "assets/3rdparty/player_idle.png",
size = rl.Vector2{64, 64},
)
return st
}
init_atlas :: proc(texture_path: cstring, size: rl.Vector2) -> Atlas {
atlas := Atlas {
tex = rl.LoadTexture(texture_path),
frame_size = size,
get_offset = get_offset,
}
atlas.rows = atlas.tex.height / (i32(size.y))
atlas.cols = atlas.tex.width / i32(size.x)
atlas.frames = atlas.cols * atlas.rows
return atlas
}
get_offset :: proc(a: ^Atlas, f: i32) -> rl.Vector2 {
col := f % a.cols
row := f / a.cols
return rl.Vector2{f32(col) * a.frame_size.x, f32(row) * a.frame_size.y}
}
gfx_free :: proc(g: GraphicsAssetStore) {
for _, tex in g.playerTex {
rl.UnloadTexture(tex.tex)
}
delete(g.playerTex)
}
gfx_draw :: proc(pos: rl.Vector2, g: ^Graphics) {
#partial switch v in g {
case GfxCircle:
rl.DrawCircleV(pos + v.pos, v.radius, v.color)
case GfxRect:
rl.DrawRectangleV(pos - v.size / 2 + v.pos, v.size, v.color)
case GfxRing:
rl.DrawRing(pos + v.pos, v.inner_radius, v.outer_radius, 0, 360, 0, v.color)
case GfxCircleLines:
rl.DrawCircleLinesV(pos + v.pos, v.radius, v.color)
case GfxAnimatedSprite:
//TODO: Count from L to R row-wize
frame_offset := v.atlas->get_offset(v.frame)
rl.DrawTexturePro(
v.atlas^.tex,
rl.Rectangle {
frame_offset.x,
frame_offset.y,
v.atlas.frame_size.x,
v.atlas.frame_size.y,
},
rl.Rectangle {
pos.x - v.atlas.frame_size.x * 3 / 2,
pos.y - v.atlas.frame_size.y * 3 / 2,
v.atlas.frame_size.x * 3,
v.atlas.frame_size.y * 3,
},
rl.Vector2{0, 0},
0,
rl.WHITE,
)
// v.current_time += rl.GetFrameTime()
// if v.current_time > v.speed {
// v.current_time = v.current_time - v.speed
// v.frame += 1
// }
}
}