package examples import "core:os" import sdl "vendor:sdl3" import "../../draw" import "../../draw/draw_qr" import cyber "../cybersteel" textures :: proc() { if !sdl.Init({.VIDEO}) do os.exit(1) window := sdl.CreateWindow("Textures", 800, 750, {.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) PLEX_SANS_REGULAR = draw.register_font(cyber.SANS_REGULAR_RAW) FONT_SIZE :: u16(14) LABEL_OFFSET :: f32(8) // gap between item and its label //----- Texture registration ---------------------------------- 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) 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_texture, _ := draw_qr.register_texture_from("https://x.com/miiilato/status/1880241066471051443") defer draw.unregister_texture(qr_texture) spin_angle: f32 = 0 //----- Draw loop ---------------------------------- 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 = 750}) // Background draw.rectangle(base_layer, {0, 0, 800, 750}, draw.Color{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( base_layer, {COL1, ROW1_Y, ITEM_SIZE, ITEM_SIZE}, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp, }, ) draw.text( base_layer, "Nearest", {COL1, ROW1_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Linear (bilinear blur) draw.rectangle( base_layer, {COL2, ROW1_Y, ITEM_SIZE, ITEM_SIZE}, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Linear_Clamp, }, ) draw.text( base_layer, "Linear", {COL2, ROW1_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Tiled (4x repeat) draw.rectangle( base_layer, {COL3, ROW1_Y, ITEM_SIZE, ITEM_SIZE}, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 4, 4}, sampler = .Nearest_Repeat, }, ) draw.text( base_layer, "Tiled 4x", {COL3, ROW1_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) //----- Row 2: Sampler presets (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}, draw.Color{255, 255, 255, 255}) // white bg draw.rectangle( base_layer, {COL1, ROW2_Y, ITEM_SIZE, ITEM_SIZE}, draw.Texture_Fill{id = qr_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp}, ) draw.text( base_layer, "QR Code", {COL1, ROW2_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Rounded corners draw.rectangle( base_layer, {COL2, ROW2_Y, ITEM_SIZE, ITEM_SIZE}, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp, }, radii = draw.uniform_radii({COL2, ROW2_Y, ITEM_SIZE, ITEM_SIZE}, 0.3), ) draw.text( base_layer, "Rounded", {COL2, ROW2_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Rotating rot_rect := draw.Rectangle{COL3, ROW2_Y, ITEM_SIZE, ITEM_SIZE} draw.rectangle( base_layer, rot_rect, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp, }, origin = draw.center_of(rot_rect), rotation = spin_angle, ) draw.text( base_layer, "Rotating", {COL3, ROW2_Y + ITEM_SIZE + LABEL_OFFSET}, PLEX_SANS_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}, draw.Color{60, 60, 60, 255}) // bg draw.rectangle( base_layer, inner_s, draw.Texture_Fill{id = stripe_texture, tint = draw.WHITE, uv_rect = uv_s, sampler = sampler_s}, ) draw.text( base_layer, "Stretch", {COL1, ROW3_Y + FIT_SIZE + LABEL_OFFSET}, PLEX_SANS_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}, draw.Color{60, 60, 60, 255}) draw.rectangle( base_layer, inner_f, draw.Texture_Fill{id = stripe_texture, tint = draw.WHITE, uv_rect = uv_f, sampler = sampler_f}, ) draw.text( base_layer, "Fill", {COL2, ROW3_Y + FIT_SIZE + LABEL_OFFSET}, PLEX_SANS_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}, draw.Color{60, 60, 60, 255}) // visible margin bg draw.rectangle( base_layer, inner_ft, draw.Texture_Fill{id = stripe_texture, tint = draw.WHITE, uv_rect = uv_ft, sampler = sampler_ft}, ) draw.text( base_layer, "Fit", {COL3, ROW3_Y + FIT_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Per-corner radii draw.rectangle( base_layer, {COL4, ROW3_Y, FIT_SIZE, FIT_SIZE}, draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp, }, radii = {20, 0, 20, 0}, ) draw.text( base_layer, "Per-corner", {COL4, ROW3_Y + FIT_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) //----- Row 4: Textured shapes (y=520) ---------------------------------- ROW4_Y :: f32(520) SHAPE_SIZE :: f32(80) SHAPE_GAP :: f32(30) SHAPE_COL1 :: f32(30) SHAPE_COL2 :: SHAPE_COL1 + SHAPE_SIZE + SHAPE_GAP SHAPE_COL3 :: SHAPE_COL2 + SHAPE_SIZE + SHAPE_GAP SHAPE_COL4 :: SHAPE_COL3 + SHAPE_SIZE + SHAPE_GAP SHAPE_COL5 :: SHAPE_COL4 + SHAPE_SIZE + SHAPE_GAP checker_fill := draw.Texture_Fill { id = checker_texture, tint = draw.WHITE, uv_rect = {0, 0, 1, 1}, sampler = .Nearest_Clamp, } // Textured circle draw.circle( base_layer, {SHAPE_COL1 + SHAPE_SIZE / 2, ROW4_Y + SHAPE_SIZE / 2}, SHAPE_SIZE / 2, checker_fill, ) draw.text( base_layer, "Circle", {SHAPE_COL1, ROW4_Y + SHAPE_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Textured ellipse draw.ellipse( base_layer, {SHAPE_COL2 + SHAPE_SIZE / 2, ROW4_Y + SHAPE_SIZE / 2}, SHAPE_SIZE / 2, SHAPE_SIZE / 3, checker_fill, ) draw.text( base_layer, "Ellipse", {SHAPE_COL2, ROW4_Y + SHAPE_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Textured polygon (hexagon) draw.polygon( base_layer, {SHAPE_COL3 + SHAPE_SIZE / 2, ROW4_Y + SHAPE_SIZE / 2}, 6, SHAPE_SIZE / 2, checker_fill, ) draw.text( base_layer, "Polygon", {SHAPE_COL3, ROW4_Y + SHAPE_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Textured ring draw.ring( base_layer, {SHAPE_COL4 + SHAPE_SIZE / 2, ROW4_Y + SHAPE_SIZE / 2}, SHAPE_SIZE / 4, SHAPE_SIZE / 2, checker_fill, ) draw.text( base_layer, "Ring", {SHAPE_COL4, ROW4_Y + SHAPE_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) // Textured line (capsule) draw.line( base_layer, {SHAPE_COL5, ROW4_Y + SHAPE_SIZE / 2}, {SHAPE_COL5 + SHAPE_SIZE, ROW4_Y + SHAPE_SIZE / 2}, checker_fill, thickness = 20, ) draw.text( base_layer, "Line", {SHAPE_COL5, ROW4_Y + SHAPE_SIZE + LABEL_OFFSET}, PLEX_SANS_REGULAR, FONT_SIZE, color = draw.WHITE, ) draw.end(gpu, window) } }