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) } }