Files
levlib/draw/examples/hellope.odin

243 lines
6.6 KiB
Odin

package examples
import "../../draw"
import "../../vendor/clay"
import "core:os"
import sdl "vendor:sdl3"
JETBRAINS_MONO_REGULAR_RAW :: #load("fonts/JetBrainsMono-Regular.ttf")
JETBRAINS_MONO_REGULAR: draw.Font_Id = max(draw.Font_Id) // Max so we crash if registration is forgotten
hellope_shapes :: proc() {
if !sdl.Init({.VIDEO}) do os.exit(1)
window := sdl.CreateWindow("Hellope!", 500, 500, {.HIGH_PIXEL_DENSITY})
gpu := sdl.CreateGPUDevice({.MSL}, true, nil)
if !sdl.ClaimWindowForGPUDevice(gpu, window) do os.exit(1)
if !draw.init(gpu, window) do os.exit(1)
spin_angle: f32 = 0
for {
defer free_all(context.temp_allocator)
ev: sdl.Event
for sdl.PollEvent(&ev) {
if ev.type == .QUIT do return
}
spin_angle += 1
base_layer := draw.begin({w = 500, h = 500})
// Background
draw.rectangle(base_layer, {0, 0, 500, 500}, {40, 40, 40, 255})
// ----- Shapes without rotation (existing demo) -----
draw.rectangle(base_layer, {20, 20, 200, 120}, {80, 120, 200, 255})
draw.rectangle_lines(base_layer, {20, 20, 200, 120}, draw.WHITE, thick = 2)
draw.rectangle(base_layer, {240, 20, 240, 120}, {200, 80, 80, 255}, roundness = 0.3)
draw.rectangle_gradient(
base_layer,
{20, 160, 460, 60},
{255, 0, 0, 255},
{0, 255, 0, 255},
{0, 0, 255, 255},
{255, 255, 0, 255},
)
// ----- Rotation demos -----
// Rectangle rotating around its center
rect := draw.Rectangle{100, 320, 80, 50}
draw.rectangle(
base_layer,
rect,
{100, 200, 100, 255},
origin = draw.center_of(rect),
rotation = spin_angle,
)
draw.rectangle_lines(
base_layer,
rect,
draw.WHITE,
thick = 2,
origin = draw.center_of(rect),
rotation = spin_angle,
)
// Rounded rectangle rotating around its center
rrect := draw.Rectangle{230, 300, 100, 80}
draw.rectangle(
base_layer,
rrect,
{200, 100, 200, 255},
roundness = 0.4,
origin = draw.center_of(rrect),
rotation = spin_angle,
)
// Ellipse rotating around its center (tilted ellipse)
draw.ellipse(base_layer, {410, 340}, 50, 30, {255, 200, 50, 255}, rotation = spin_angle)
// Circle orbiting a point (moon orbiting planet)
planet_pos := [2]f32{100, 450}
moon_pos := planet_pos + {0, -40}
draw.circle(base_layer, planet_pos, 8, {200, 200, 200, 255}) // planet (stationary)
draw.circle(base_layer, moon_pos, 5, {100, 150, 255, 255}, origin = {0, 40}, rotation = spin_angle) // moon orbiting
// Ring arc rotating in place
draw.ring(base_layer, {250, 450}, 15, 30, 0, 270, {100, 100, 220, 255}, rotation = spin_angle)
// Triangle rotating around its center
tv1 := [2]f32{350, 420}
tv2 := [2]f32{420, 480}
tv3 := [2]f32{340, 480}
draw.triangle(
base_layer,
tv1,
tv2,
tv3,
{220, 180, 60, 255},
origin = draw.center_of(tv1, tv2, tv3),
rotation = spin_angle,
)
// Polygon rotating around its center (already had rotation; now with origin for orbit)
draw.poly(base_layer, {460, 450}, 6, 30, {180, 100, 220, 255}, rotation = spin_angle)
draw.poly_lines(base_layer, {460, 450}, 6, 30, draw.WHITE, rotation = spin_angle, thick = 2)
draw.end(gpu, window)
}
}
hellope_text :: proc() {
if !sdl.Init({.VIDEO}) do os.exit(1)
window := sdl.CreateWindow("Hellope!", 600, 600, {.HIGH_PIXEL_DENSITY})
gpu := sdl.CreateGPUDevice({.MSL}, true, nil)
if !sdl.ClaimWindowForGPUDevice(gpu, window) do os.exit(1)
if !draw.init(gpu, window) do os.exit(1)
JETBRAINS_MONO_REGULAR = draw.register_font(JETBRAINS_MONO_REGULAR_RAW)
FONT_SIZE :: u16(24)
spin_angle: f32 = 0
for {
defer free_all(context.temp_allocator)
ev: sdl.Event
for sdl.PollEvent(&ev) {
if ev.type == .QUIT do return
}
spin_angle += 0.5
base_layer := draw.begin({w = 600, h = 600})
// Grey background
draw.rectangle(base_layer, {0, 0, 600, 600}, {127, 127, 127, 255})
// ----- Text API demos -----
// Cached text with id — TTF_Text reused across frames (good for text-heavy apps)
draw.text(
base_layer,
"Hellope!",
{300, 80},
JETBRAINS_MONO_REGULAR,
FONT_SIZE,
color = draw.WHITE,
origin = draw.center_of("Hellope!", JETBRAINS_MONO_REGULAR, FONT_SIZE),
id = "hellope",
)
// Rotating sentence — verifies multi-word text rotation around center
draw.text(
base_layer,
"Hellope World!",
{300, 250},
JETBRAINS_MONO_REGULAR,
FONT_SIZE,
color = {255, 200, 50, 255},
origin = draw.center_of("Hellope World!", JETBRAINS_MONO_REGULAR, FONT_SIZE),
rotation = spin_angle,
id = "rotating_sentence",
)
// Uncached text (no id) — created and destroyed each frame, simplest usage
draw.text(
base_layer,
"Top-left anchored",
{20, 450},
JETBRAINS_MONO_REGULAR,
FONT_SIZE,
color = draw.WHITE,
)
// Measure text for manual layout
size := draw.measure_text("Measured!", JETBRAINS_MONO_REGULAR, FONT_SIZE)
draw.rectangle(base_layer, {300 - size.x / 2, 380, size.x, size.y}, {60, 60, 60, 200})
draw.text(
base_layer,
"Measured!",
{300, 380},
JETBRAINS_MONO_REGULAR,
FONT_SIZE,
color = draw.WHITE,
origin = draw.top_of("Measured!", JETBRAINS_MONO_REGULAR, FONT_SIZE),
id = "measured",
)
// Rotating text anchored at top-left (no origin offset) — spins around top-left corner
draw.text(
base_layer,
"Corner spin",
{150, 530},
JETBRAINS_MONO_REGULAR,
FONT_SIZE,
color = {100, 200, 255, 255},
rotation = spin_angle,
id = "corner_spin",
)
draw.end(gpu, window)
}
}
hellope_clay :: proc() {
if !sdl.Init({.VIDEO}) do os.exit(1)
window := sdl.CreateWindow("Hellope!", 500, 500, {.HIGH_PIXEL_DENSITY})
gpu := sdl.CreateGPUDevice({.MSL}, true, nil)
if !sdl.ClaimWindowForGPUDevice(gpu, window) do os.exit(1)
if !draw.init(gpu, window) do os.exit(1)
JETBRAINS_MONO_REGULAR = draw.register_font(JETBRAINS_MONO_REGULAR_RAW)
text_config := clay.TextElementConfig {
fontId = JETBRAINS_MONO_REGULAR,
fontSize = 24,
textColor = {255, 255, 255, 255},
}
for {
defer free_all(context.temp_allocator)
ev: sdl.Event
for sdl.PollEvent(&ev) {
if ev.type == .QUIT do return
}
base_layer := draw.begin({w = 500, h = 500})
clay.SetLayoutDimensions({width = base_layer.bounds.w, height = base_layer.bounds.h})
clay.BeginLayout()
if clay.UI()(
{
id = clay.ID("outer"),
layout = {
sizing = {clay.SizingGrow({}), clay.SizingGrow({})},
childAlignment = {x = .Center, y = .Center},
},
backgroundColor = {127, 127, 127, 255},
},
) {
clay.Text("Hellope!", &text_config)
}
clay_batch := draw.ClayBatch {
bounds = base_layer.bounds,
cmds = clay.EndLayout(),
}
draw.prepare_clay_batch(base_layer, &clay_batch, {0, 0})
draw.end(gpu, window)
}
}