282 lines
7.7 KiB
Odin
282 lines
7.7 KiB
Odin
package examples
|
|
|
|
import "../../draw"
|
|
import "../../draw/draw_qr"
|
|
import "core:math"
|
|
import "core:os"
|
|
import sdl "vendor:sdl3"
|
|
|
|
textures :: proc() {
|
|
if !sdl.Init({.VIDEO}) do os.exit(1)
|
|
window := sdl.CreateWindow("Textures", 800, 600, {.HIGH_PIXEL_DENSITY})
|
|
gpu := sdl.CreateGPUDevice(draw.PLATFORM_SHADER_FORMAT, 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(14)
|
|
LABEL_OFFSET :: f32(8) // gap between item and its label
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Procedural checkerboard texture (8x8, RGBA8)
|
|
// -------------------------------------------------------------------------
|
|
checker_size :: 8
|
|
checker_pixels: [checker_size * checker_size * 4]u8
|
|
for y in 0 ..< checker_size {
|
|
for x in 0 ..< checker_size {
|
|
i := (y * checker_size + x) * 4
|
|
is_dark := ((x + y) % 2) == 0
|
|
val: u8 = 40 if is_dark else 220
|
|
checker_pixels[i + 0] = val // R
|
|
checker_pixels[i + 1] = val / 2 // G — slight color tint
|
|
checker_pixels[i + 2] = val // B
|
|
checker_pixels[i + 3] = 255 // A
|
|
}
|
|
}
|
|
checker_texture, _ := draw.register_texture(
|
|
draw.Texture_Desc {
|
|
width = checker_size,
|
|
height = checker_size,
|
|
depth_or_layers = 1,
|
|
type = .D2,
|
|
format = .R8G8B8A8_UNORM,
|
|
usage = {.SAMPLER},
|
|
mip_levels = 1,
|
|
},
|
|
checker_pixels[:],
|
|
)
|
|
defer draw.unregister_texture(checker_texture)
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Non-square gradient stripe texture (16x8, RGBA8) for fit mode demos
|
|
// -------------------------------------------------------------------------
|
|
stripe_w :: 16
|
|
stripe_h :: 8
|
|
stripe_pixels: [stripe_w * stripe_h * 4]u8
|
|
for y in 0 ..< stripe_h {
|
|
for x in 0 ..< stripe_w {
|
|
i := (y * stripe_w + x) * 4
|
|
stripe_pixels[i + 0] = u8(x * 255 / (stripe_w - 1)) // R gradient left→right
|
|
stripe_pixels[i + 1] = u8(y * 255 / (stripe_h - 1)) // G gradient top→bottom
|
|
stripe_pixels[i + 2] = 128 // B constant
|
|
stripe_pixels[i + 3] = 255 // A
|
|
}
|
|
}
|
|
stripe_texture, _ := draw.register_texture(
|
|
draw.Texture_Desc {
|
|
width = stripe_w,
|
|
height = stripe_h,
|
|
depth_or_layers = 1,
|
|
type = .D2,
|
|
format = .R8G8B8A8_UNORM,
|
|
usage = {.SAMPLER},
|
|
mip_levels = 1,
|
|
},
|
|
stripe_pixels[:],
|
|
)
|
|
defer draw.unregister_texture(stripe_texture)
|
|
|
|
// -------------------------------------------------------------------------
|
|
// QR code texture (R8_UNORM — see rendering note below)
|
|
// -------------------------------------------------------------------------
|
|
qr_texture, _ := draw_qr.register_texture_from_text("https://x.com/miiilato/status/1880241066471051443")
|
|
defer draw.unregister_texture(qr_texture)
|
|
|
|
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({width = 800, height = 600})
|
|
|
|
// Background
|
|
draw.rectangle(base_layer, {0, 0, 800, 600}, {30, 30, 30, 255})
|
|
|
|
// =====================================================================
|
|
// Row 1: Sampler presets (y=30)
|
|
// =====================================================================
|
|
ROW1_Y :: f32(30)
|
|
ITEM_SIZE :: f32(120)
|
|
COL1 :: f32(30)
|
|
COL2 :: f32(180)
|
|
COL3 :: f32(330)
|
|
COL4 :: f32(480)
|
|
|
|
// Nearest (sharp pixel edges)
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
{COL1, ROW1_Y, ITEM_SIZE, ITEM_SIZE},
|
|
checker_texture,
|
|
sampler = .Nearest_Clamp,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Nearest",
|
|
{COL1, ROW1_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Linear (bilinear blur)
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
{COL2, ROW1_Y, ITEM_SIZE, ITEM_SIZE},
|
|
checker_texture,
|
|
sampler = .Linear_Clamp,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Linear",
|
|
{COL2, ROW1_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Tiled (4x repeat)
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
{COL3, ROW1_Y, ITEM_SIZE, ITEM_SIZE},
|
|
checker_texture,
|
|
sampler = .Nearest_Repeat,
|
|
uv_rect = {0, 0, 4, 4},
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Tiled 4x",
|
|
{COL3, ROW1_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// =====================================================================
|
|
// Row 2: QR code, Rounded, Rotating (y=190)
|
|
// =====================================================================
|
|
ROW2_Y :: f32(190)
|
|
|
|
// QR code (RGBA texture with baked colors, nearest sampling)
|
|
draw.rectangle(base_layer, {COL1, ROW2_Y, ITEM_SIZE, ITEM_SIZE}, {255, 255, 255, 255}) // white bg
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
{COL1, ROW2_Y, ITEM_SIZE, ITEM_SIZE},
|
|
qr_texture,
|
|
sampler = .Nearest_Clamp,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"QR Code",
|
|
{COL1, ROW2_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Rounded corners
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
{COL2, ROW2_Y, ITEM_SIZE, ITEM_SIZE},
|
|
checker_texture,
|
|
sampler = .Nearest_Clamp,
|
|
roundness = 0.3,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Rounded",
|
|
{COL2, ROW2_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Rotating
|
|
rot_rect := draw.Rectangle{COL3, ROW2_Y, ITEM_SIZE, ITEM_SIZE}
|
|
draw.rectangle_texture(
|
|
base_layer,
|
|
rot_rect,
|
|
checker_texture,
|
|
sampler = .Nearest_Clamp,
|
|
origin = draw.center_of(rot_rect),
|
|
rotation = spin_angle,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Rotating",
|
|
{COL3, ROW2_Y + ITEM_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// =====================================================================
|
|
// Row 3: Fit modes + Per-corner radii (y=360)
|
|
// =====================================================================
|
|
ROW3_Y :: f32(360)
|
|
FIT_SIZE :: f32(120) // square target rect
|
|
|
|
// Stretch
|
|
uv_s, sampler_s, inner_s := draw.fit_params(.Stretch, {COL1, ROW3_Y, FIT_SIZE, FIT_SIZE}, stripe_texture)
|
|
draw.rectangle(base_layer, {COL1, ROW3_Y, FIT_SIZE, FIT_SIZE}, {60, 60, 60, 255}) // bg
|
|
draw.rectangle_texture(base_layer, inner_s, stripe_texture, uv_rect = uv_s, sampler = sampler_s)
|
|
draw.text(
|
|
base_layer,
|
|
"Stretch",
|
|
{COL1, ROW3_Y + FIT_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Fill (center-crop)
|
|
uv_f, sampler_f, inner_f := draw.fit_params(.Fill, {COL2, ROW3_Y, FIT_SIZE, FIT_SIZE}, stripe_texture)
|
|
draw.rectangle(base_layer, {COL2, ROW3_Y, FIT_SIZE, FIT_SIZE}, {60, 60, 60, 255})
|
|
draw.rectangle_texture(base_layer, inner_f, stripe_texture, uv_rect = uv_f, sampler = sampler_f)
|
|
draw.text(
|
|
base_layer,
|
|
"Fill",
|
|
{COL2, ROW3_Y + FIT_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Fit (letterbox)
|
|
uv_ft, sampler_ft, inner_ft := draw.fit_params(.Fit, {COL3, ROW3_Y, FIT_SIZE, FIT_SIZE}, stripe_texture)
|
|
draw.rectangle(base_layer, {COL3, ROW3_Y, FIT_SIZE, FIT_SIZE}, {60, 60, 60, 255}) // visible margin bg
|
|
draw.rectangle_texture(base_layer, inner_ft, stripe_texture, uv_rect = uv_ft, sampler = sampler_ft)
|
|
draw.text(
|
|
base_layer,
|
|
"Fit",
|
|
{COL3, ROW3_Y + FIT_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
// Per-corner radii
|
|
draw.rectangle_texture_corners(
|
|
base_layer,
|
|
{COL4, ROW3_Y, FIT_SIZE, FIT_SIZE},
|
|
{20, 0, 20, 0},
|
|
checker_texture,
|
|
sampler = .Nearest_Clamp,
|
|
)
|
|
draw.text(
|
|
base_layer,
|
|
"Per-corner",
|
|
{COL4, ROW3_Y + FIT_SIZE + LABEL_OFFSET},
|
|
JETBRAINS_MONO_REGULAR,
|
|
FONT_SIZE,
|
|
color = draw.WHITE,
|
|
)
|
|
|
|
draw.end(gpu, window)
|
|
}
|
|
}
|