Clean up SDL code and fix sloppy mistakes

This commit is contained in:
Rats 2025-10-21 18:41:25 -05:00
parent eb8368216a
commit 6824a942a7
4 changed files with 268 additions and 416 deletions

View file

@ -100,7 +100,7 @@ video_demo_layout :: proc(data: ^Video_Demo_Data) -> clay.ClayArray(clay.RenderC
// Child elements go inside braces // Child elements go inside braces
if clay.UI(clay.ID("HeaderBar"))( if clay.UI(clay.ID("HeaderBar"))(
{ {
layout = {sizing = {height = clay.SizingFixed(60), width = clay.SizingFixed(0)}, padding = {16, 16, 0, 0}, childGap = 16, childAlignment = {y = .Center}}, layout = {sizing = {height = clay.SizingFixed(60), width = clay.SizingGrow()}, padding = {16, 16, 0, 0}, childGap = 16, childAlignment = {y = .Center}},
backgroundColor = contentBackgroundColor, backgroundColor = contentBackgroundColor,
cornerRadius = clay.CornerRadiusAll(8), cornerRadius = clay.CornerRadiusAll(8),
}, },
@ -154,7 +154,7 @@ video_demo_layout :: proc(data: ^Video_Demo_Data) -> clay.ClayArray(clay.RenderC
clay.TextDynamic(document.title, clay.TextConfig({fontId = VIDEO_DEMO_FONT_ID_BODY, fontSize = 20, textColor = {255, 255, 255, 255}})) clay.TextDynamic(document.title, clay.TextConfig({fontId = VIDEO_DEMO_FONT_ID_BODY, fontSize = 20, textColor = {255, 255, 255, 255}}))
} }
} else { } else {
clickData := new_clone((Sidebar_Click_Data) { clickData := new_clone(Sidebar_Click_Data {
requestedDocumentIndex = i, requestedDocumentIndex = i,
selectedDocumentIndex = &data.selectedDocumentIndex, selectedDocumentIndex = &data.selectedDocumentIndex,
}, context.temp_allocator) }, context.temp_allocator)

View file

@ -1,4 +1,4 @@
Odin doesn't directly package SDL, so on Windows, you'll want to copy `SDL3.dll` and `SDL3_ttf.dll` into this directory. On Linux and Mac, you should install SDL3 via your package manager Odin doesn't directly package SDL, so on Windows, you'll want to copy `SDL3.dll` and `SDL3_ttf.dll` into this directory from odin's `vendor/sdl3` directory located next to the compiler. You can use `odin root` to figure out where your compiler is installed. On Linux and Mac, you should install SDL3 via your package manager
## Running on Windows ## Running on Windows
In an embdedded termninal, missing dependencies will fail silently on Windows, so if you have any unexplainable crashes, make sure the DLLs are in your current working directory (the path you run the command from). It's easiest to just copy them next to this file, and run from here as well. In an embdedded termninal, missing dependencies will fail silently on Windows, so if you have any unexplainable crashes, make sure the DLLs are in your current working directory (the path you run the command from). It's easiest to just copy them next to this file, and run from here as well.

View file

@ -10,7 +10,7 @@ import "vendor:sdl3/ttf"
App_State :: struct { App_State :: struct {
window: ^sdl.Window, window: ^sdl.Window,
rendererData: Clay_SDL3RendererData, rendererData: Clay_SDL_Render_Data,
} }
state: App_State state: App_State
@ -22,7 +22,7 @@ errorHandler :: proc "c" (errorData: clay.ErrorData) {
} }
load_font :: proc(data: []byte, size: f32, id: u16, fonts: ^[dynamic]^ttf.Font) { load_font :: proc(data: []byte, size: f32, id: u16, fonts: ^[dynamic]^ttf.Font) {
font_stream := sdl.IOFromConstMem(raw_data(ROBOTO), uint(len(ROBOTO))) font_stream := sdl.IOFromConstMem(raw_data(data), uint(len(data)))
font := ttf.OpenFontIO(font_stream, true, size * 2) font := ttf.OpenFontIO(font_stream, true, size * 2)
assign_at(fonts, int(id), font) assign_at(fonts, int(id), font)
} }
@ -38,7 +38,7 @@ measure_text :: proc "c" (text: clay.StringSlice, config: ^clay.TextElementConfi
sdl.LogError(i32(sdl.LogCategory.ERROR), "Failed to measure text: %s", sdl.GetError()) sdl.LogError(i32(sdl.LogCategory.ERROR), "Failed to measure text: %s", sdl.GetError())
} }
return clay.Dimensions{f32(width), f32(height)} return {f32(width), f32(height)}
} }
// Load at compile time, directly into the binary // Load at compile time, directly into the binary
ROBOTO := #load("./Roboto-Regular.ttf") ROBOTO := #load("./Roboto-Regular.ttf")
@ -58,9 +58,9 @@ main :: proc() {
state.window = window state.window = window
state.rendererData.renderer = renderer state.rendererData.renderer = renderer
state.rendererData.textEngine = ttf.CreateRendererTextEngine(renderer) state.rendererData.text_engine = ttf.CreateRendererTextEngine(renderer)
minMemorySize := (uint)(clay.MinMemorySize()) minMemorySize := uint(clay.MinMemorySize())
arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, make([^]u8, minMemorySize)) arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, make([^]u8, minMemorySize))
clay.Initialize(arena, {1280, 720}, {handler = errorHandler}) clay.Initialize(arena, {1280, 720}, {handler = errorHandler})
clay.SetMeasureTextFunction(measure_text, &state.rendererData.fonts) clay.SetMeasureTextFunction(measure_text, &state.rendererData.fonts)
@ -78,12 +78,10 @@ main :: proc() {
window_width, window_height: i32 window_width, window_height: i32
for !done { for !done {
defer free_all(context.temp_allocator)
scrollDelta: clay.Vector2 scrollDelta: clay.Vector2
for (sdl.PollEvent(&event)) { for sdl.PollEvent(&event) {
if (event.type == .QUIT) { if event.type == .QUIT {
done = true done = true
} else if event.type == .MOUSE_WHEEL { } else if event.type == .MOUSE_WHEEL {
scrollDelta.x = event.wheel.x scrollDelta.x = event.wheel.x
@ -99,10 +97,8 @@ main :: proc() {
clay.SetLayoutDimensions({width = f32(window_width), height = f32(window_height)}) clay.SetLayoutDimensions({width = f32(window_width), height = f32(window_height)})
mouseX: f32 = 0 mousePosition : clay.Vector2
mouseY: f32 = 0 mouseState := sdl.GetMouseState(&mousePosition.x, &mousePosition.y)
mouseState := sdl.GetMouseState(&mouseX, &mouseY)
mousePosition := (clay.Vector2){mouseX, mouseY}
clay.SetPointerState(mousePosition, .LEFT in mouseState) clay.SetPointerState(mousePosition, .LEFT in mouseState)
clay.UpdateScrollContainers(false, scrollDelta, f32(deltaTime)) clay.UpdateScrollContainers(false, scrollDelta, f32(deltaTime))
@ -112,7 +108,7 @@ main :: proc() {
sdl.SetRenderDrawColor(renderer, 0, 0, 0, 255) sdl.SetRenderDrawColor(renderer, 0, 0, 0, 255)
sdl.RenderClear(renderer) sdl.RenderClear(renderer)
sdl_Clay_RenderClayCommands(&state.rendererData, &commands) sdl_render_clay_commands(&state.rendererData, &commands)
sdl.RenderPresent(renderer) sdl.RenderPresent(renderer)
} }

View file

@ -3,12 +3,13 @@ package video_demo_sdl
import clay "../../clay-odin" import clay "../../clay-odin"
import "core:math" import "core:math"
import "core:math/linalg"
import sdl "vendor:sdl3" import sdl "vendor:sdl3"
import "vendor:sdl3/ttf" import "vendor:sdl3/ttf"
Clay_SDL3RendererData :: struct { Clay_SDL_Render_Data :: struct {
renderer: ^sdl.Renderer, renderer: ^sdl.Renderer,
textEngine: ^ttf.TextEngine, text_engine: ^ttf.TextEngine,
fonts: [dynamic]^ttf.Font, fonts: [dynamic]^ttf.Font,
} }
@ -24,21 +25,17 @@ px_to_pt :: proc "contextless" (pixels: f32) -> f32 {
NUM_CIRCLE_SEGMENTS :: 16 NUM_CIRCLE_SEGMENTS :: 16
//all rendering is performed by a single SDL call, avoiding multiple RenderRect + plumbing choice for circles. //all rendering is performed by a single SDL call, avoiding multiple RenderRect + plumbing choice for circles.
sdl_Clay_RenderFillRoundedRect :: proc( @(private = "file")
rendererData: ^Clay_SDL3RendererData, fill_rounded_rect :: proc(rendererData: ^Clay_SDL_Render_Data, rect: sdl.FRect, cornerRadius: f32, _color: clay.Color) {
rect: sdl.FRect,
cornerRadius: f32,
_color: clay.Color,
) {
color := sdl.FColor(_color / 255) color := sdl.FColor(_color / 255)
indexCount: i32 = 0 indexCount: i32 = 0
vertexCount: i32 = 0 vertexCount: i32 = 0
minRadius := sdl.min(rect.w, rect.h) / 2 minRadius := min(rect.w, rect.h) / 2
clampedRadius := sdl.min(cornerRadius, minRadius) clampedRadius := min(cornerRadius, minRadius)
numCircleSegments := sdl.max(NUM_CIRCLE_SEGMENTS, i32(clampedRadius * 0.5)) numCircleSegments := max(NUM_CIRCLE_SEGMENTS, i32(clampedRadius * 0.5))
totalVertices := 4 + (4 * (numCircleSegments * 2)) + 2 * 4 totalVertices := 4 + (4 * (numCircleSegments * 2)) + 2 * 4
totalIndices := 6 + (4 * (numCircleSegments * 3)) + 6 * 4 totalIndices := 6 + (4 * (numCircleSegments * 3)) + 6 * 4
@ -48,26 +45,10 @@ sdl_Clay_RenderFillRoundedRect :: proc(
indices := make([]i32, totalIndices, allocator = context.temp_allocator) indices := make([]i32, totalIndices, allocator = context.temp_allocator)
//define center rectangle //define center rectangle
vertices[vertexCount + 0] = (sdl.Vertex) { vertices[vertexCount + 0] = {{rect.x + clampedRadius, rect.y + clampedRadius}, color, {0, 0}} //0 center TL
{rect.x + clampedRadius, rect.y + clampedRadius}, vertices[vertexCount + 1] = {{rect.x + rect.w - clampedRadius, rect.y + clampedRadius}, color, {1, 0}} //1 center TR
color, vertices[vertexCount + 2] = {{rect.x + rect.w - clampedRadius, rect.y + rect.h - clampedRadius}, color, {1, 1}} //2 center BR
{0, 0}, vertices[vertexCount + 3] = {{rect.x + clampedRadius, rect.y + rect.h - clampedRadius}, color, {0, 1}} //3 center BL
} //0 center TL
vertices[vertexCount + 1] = (sdl.Vertex) {
{rect.x + rect.w - clampedRadius, rect.y + clampedRadius},
color,
{1, 0},
} //1 center TR
vertices[vertexCount + 2] = (sdl.Vertex) {
{rect.x + rect.w - clampedRadius, rect.y + rect.h - clampedRadius},
color,
{1, 1},
} //2 center BR
vertices[vertexCount + 3] = (sdl.Vertex) {
{rect.x + clampedRadius, rect.y + rect.h - clampedRadius},
color,
{0, 1},
} //3 center BL
vertexCount += 4 vertexCount += 4
@ -89,7 +70,7 @@ sdl_Clay_RenderFillRoundedRect :: proc(
for j in i32(0) ..< 4 { // Iterate over four corners for j in i32(0) ..< 4 { // Iterate over four corners
cx, cy, signX, signY: f32 cx, cy, signX, signY: f32
switch (j) { switch j {
case 0: case 0:
cx = rect.x + clampedRadius cx = rect.x + clampedRadius
cy = rect.y + clampedRadius cy = rect.y + clampedRadius
@ -115,22 +96,8 @@ sdl_Clay_RenderFillRoundedRect :: proc(
return return
} }
vertices[vertexCount + 0] = (sdl.Vertex) { vertices[vertexCount + 0] = {{cx + math.cos(angle1) * clampedRadius * signX, cy + math.sin(angle1) * clampedRadius * signY}, color, {0, 0}}
{ vertices[vertexCount + 1] = {{cx + math.cos(angle2) * clampedRadius * signX, cy + math.sin(angle2) * clampedRadius * signY}, color, {0, 0}}
cx + sdl.cosf(angle1) * clampedRadius * signX,
cy + sdl.sinf(angle1) * clampedRadius * signY,
},
color,
{0, 0},
}
vertices[vertexCount + 1] = (sdl.Vertex) {
{
cx + sdl.cosf(angle2) * clampedRadius * signX,
cy + sdl.sinf(angle2) * clampedRadius * signY,
},
color,
{0, 0},
}
vertexCount += 2 vertexCount += 2
@ -143,12 +110,8 @@ sdl_Clay_RenderFillRoundedRect :: proc(
//Define edge rectangles //Define edge rectangles
// Top edge // Top edge
vertices[vertexCount + 0] = (sdl.Vertex){{rect.x + clampedRadius, rect.y}, color, {0, 0}} //TL vertices[vertexCount + 0] = {{rect.x + clampedRadius, rect.y}, color, {0, 0}} //TL
vertices[vertexCount + 1] = (sdl.Vertex) { vertices[vertexCount + 1] = {{rect.x + rect.w - clampedRadius, rect.y}, color, {1, 0}} //TR
{rect.x + rect.w - clampedRadius, rect.y},
color,
{1, 0},
} //TR
vertexCount += 2 vertexCount += 2
@ -160,16 +123,8 @@ sdl_Clay_RenderFillRoundedRect :: proc(
indices[indexCount + 5] = vertexCount - 1 //TR indices[indexCount + 5] = vertexCount - 1 //TR
indexCount += 6 indexCount += 6
// Right edge // Right edge
vertices[vertexCount + 0] = (sdl.Vertex) { vertices[vertexCount + 0] = {{rect.x + rect.w, rect.y + clampedRadius}, color, {1, 0}} //RT
{rect.x + rect.w, rect.y + clampedRadius}, vertices[vertexCount + 1] = {{rect.x + rect.w, rect.y + rect.h - clampedRadius}, color, {1, 1}} //RB
color,
{1, 0},
} //RT
vertices[vertexCount + 1] = (sdl.Vertex) {
{rect.x + rect.w, rect.y + rect.h - clampedRadius},
color,
{1, 1},
} //RB
vertexCount += 2 vertexCount += 2
indices[indexCount + 0] = 1 indices[indexCount + 0] = 1
@ -181,16 +136,8 @@ sdl_Clay_RenderFillRoundedRect :: proc(
indexCount += 6 indexCount += 6
// Bottom edge // Bottom edge
vertices[vertexCount + 0] = (sdl.Vertex) { vertices[vertexCount + 0] = {{rect.x + rect.w - clampedRadius, rect.y + rect.h}, color, {1, 1}} //BR
{rect.x + rect.w - clampedRadius, rect.y + rect.h}, vertices[vertexCount + 1] = {{rect.x + clampedRadius, rect.y + rect.h}, color, {0, 1}} //BL
color,
{1, 1},
} //BR
vertices[vertexCount + 1] = (sdl.Vertex) {
{rect.x + clampedRadius, rect.y + rect.h},
color,
{0, 1},
} //BL
vertexCount += 2 vertexCount += 2
indices[indexCount + 0] = 2 indices[indexCount + 0] = 2
@ -202,12 +149,8 @@ sdl_Clay_RenderFillRoundedRect :: proc(
indexCount += 6 indexCount += 6
// Left edge // Left edge
vertices[vertexCount + 0] = (sdl.Vertex) { vertices[vertexCount + 0] = {{rect.x, rect.y + rect.h - clampedRadius}, color, {0, 1}} //LB
{rect.x, rect.y + rect.h - clampedRadius}, vertices[vertexCount + 1] = {{rect.x, rect.y + clampedRadius}, color, {0, 0}} //LT
color,
{0, 1},
} //LB
vertices[vertexCount + 1] = (sdl.Vertex){{rect.x, rect.y + clampedRadius}, color, {0, 0}} //LT
vertexCount += 2 vertexCount += 2
indices[indexCount + 0] = 3 indices[indexCount + 0] = 3
@ -219,237 +162,150 @@ sdl_Clay_RenderFillRoundedRect :: proc(
indexCount += 6 indexCount += 6
// Render everything // Render everything
sdl.RenderGeometry( sdl.RenderGeometry(rendererData.renderer, nil, raw_data(vertices), vertexCount, raw_data(indices), indexCount)
rendererData.renderer,
nil,
raw_data(vertices),
vertexCount,
raw_data(indices),
indexCount,
)
} }
sdl_Clay_RenderArc :: proc( @(private = "file")
rendererData: ^Clay_SDL3RendererData, render_arc :: proc(rendererData: ^Clay_SDL_Render_Data, center: sdl.FPoint, radius: f32, startAngle: f32, endAngle: f32, thickness: f32, color: clay.Color) {
center: sdl.FPoint, sdl.SetRenderDrawColor(rendererData.renderer, clay_to_sdl_color(color))
radius: f32,
startAngle: f32,
endAngle: f32,
thickness: f32,
color: clay.Color,
) {
sdl.SetRenderDrawColor(
rendererData.renderer,
u8(color.r),
u8(color.g),
u8(color.b),
u8(color.a),
)
radStart := startAngle * (math.PI / 180.0) radStart := math.to_radians(startAngle)
radEnd := endAngle * (math.PI / 180.0) radEnd := math.to_radians(endAngle)
numCircleSegments := sdl.max(NUM_CIRCLE_SEGMENTS, i32(radius * 1.5)) //increase circle segments for larger circles, 1.5 is arbitrary. numCircleSegments := max(NUM_CIRCLE_SEGMENTS, i32(radius * 1.5)) //increase circle segments for larger circles, 1.5 is arbitrary.
angleStep := (radEnd - radStart) / f32(numCircleSegments) angleStep := (radEnd - radStart) / f32(numCircleSegments)
thicknessStep: f32 = 0.4 //arbitrary value to avoid overlapping lines. Changing THICKNESS_STEP or numCircleSegments might cause artifacts. thicknessStep: f32 = 0.4 //arbitrary value to avoid overlapping lines. Changing THICKNESS_STEP or numCircleSegments might cause artifacts.
for t := thicknessStep; t < thickness - thicknessStep; t += thicknessStep { for t := thicknessStep; t < thickness - thicknessStep; t += thicknessStep {
points := make([]sdl.FPoint, numCircleSegments + 1, allocator = context.temp_allocator) points := make([]sdl.FPoint, numCircleSegments + 1, allocator = context.temp_allocator)
clampedRadius := sdl.max(radius - t, 1) clampedRadius := max(radius - t, 1)
for i in 0 ..= numCircleSegments { for i in 0 ..= numCircleSegments {
angle := radStart + f32(i) * angleStep angle := radStart + f32(i) * angleStep
points[i] = (sdl.FPoint) { points[i] = sdl.FPoint{math.round(center.x + math.cos(angle) * clampedRadius), math.round(center.y + math.sin(angle) * clampedRadius)}
sdl.roundf(center.x + sdl.cosf(angle) * clampedRadius),
sdl.roundf(center.y + sdl.sinf(angle) * clampedRadius),
}
} }
sdl.RenderLines(rendererData.renderer, raw_data(points), numCircleSegments + 1) sdl.RenderLines(rendererData.renderer, raw_data(points), numCircleSegments + 1)
} }
} }
currentClippingRectangle: sdl.Rect @(private = "file")
current_clipping_rect: sdl.Rect
sdl_Clay_RenderClayCommands :: proc( clay_to_sdl_color :: proc(color: clay.Color) -> (r, g, b, a: u8) {
rendererData: ^Clay_SDL3RendererData, return expand_values(linalg.array_cast(color, u8))
rcommands: ^clay.ClayArray(clay.RenderCommand), }
) {
for i in 0 ..< rcommands.length { sdl_render_clay_commands :: proc(renderer_data: ^Clay_SDL_Render_Data, commands: ^clay.ClayArray(clay.RenderCommand)) {
rcmd := clay.RenderCommandArray_Get(rcommands, i) for i in 0 ..< commands.length {
bounding_box := rcmd.boundingBox cmd := clay.RenderCommandArray_Get(commands, i)
bounding_box := cmd.boundingBox
rect := sdl.FRect{bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height} rect := sdl.FRect{bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height}
#partial switch (rcmd.commandType) { #partial switch cmd.commandType {
case .Rectangle: case .Rectangle:
config := &rcmd.renderData.rectangle config := &cmd.renderData.rectangle
sdl.SetRenderDrawBlendMode(rendererData.renderer, sdl.BLENDMODE_BLEND) sdl.SetRenderDrawBlendMode(renderer_data.renderer, sdl.BLENDMODE_BLEND)
sdl.SetRenderDrawColor( sdl.SetRenderDrawColor(renderer_data.renderer, clay_to_sdl_color(config.backgroundColor))
rendererData.renderer, if config.cornerRadius.topLeft > 0 {
u8(config.backgroundColor.r), fill_rounded_rect(renderer_data, rect, config.cornerRadius.topLeft, config.backgroundColor)
u8(config.backgroundColor.g),
u8(config.backgroundColor.b),
u8(config.backgroundColor.a),
)
if (config.cornerRadius.topLeft > 0) {
sdl_Clay_RenderFillRoundedRect(
rendererData,
rect,
config.cornerRadius.topLeft,
config.backgroundColor,
)
} else { } else {
sdl.RenderFillRect(rendererData.renderer, &rect) sdl.RenderFillRect(renderer_data.renderer, &rect)
} }
case .Text: case .Text:
config := &rcmd.renderData.text config := &cmd.renderData.text
font := rendererData.fonts[config.fontId] font := renderer_data.fonts[config.fontId]
ttf.SetFontSize(font, px_to_pt(f32(config.fontSize))) ttf.SetFontSize(font, px_to_pt(f32(config.fontSize)))
text := ttf.CreateText( text := ttf.CreateText(renderer_data.text_engine, font, cstring(config.stringContents.chars), uint(config.stringContents.length))
rendererData.textEngine, ttf.SetTextColor(text, clay_to_sdl_color(config.textColor))
font,
cstring(config.stringContents.chars),
uint(config.stringContents.length),
)
ttf.SetTextColor(
text,
u8(config.textColor.r),
u8(config.textColor.g),
u8(config.textColor.b),
u8(config.textColor.a),
)
ttf.DrawRendererText(text, rect.x, rect.y) ttf.DrawRendererText(text, rect.x, rect.y)
ttf.DestroyText(text) ttf.DestroyText(text)
case .Border: case .Border:
config := &rcmd.renderData.border config := &cmd.renderData.border
minRadius := sdl.min(rect.w, rect.h) / 2 minRadius := min(rect.w, rect.h) / 2
clampedRadii := clay.CornerRadius { clampedRadii := clay.CornerRadius {
topLeft = sdl.min(config.cornerRadius.topLeft, minRadius), topLeft = min(config.cornerRadius.topLeft, minRadius),
topRight = sdl.min(config.cornerRadius.topRight, minRadius), topRight = min(config.cornerRadius.topRight, minRadius),
bottomLeft = sdl.min(config.cornerRadius.bottomLeft, minRadius), bottomLeft = min(config.cornerRadius.bottomLeft, minRadius),
bottomRight = sdl.min(config.cornerRadius.bottomRight, minRadius), bottomRight = min(config.cornerRadius.bottomRight, minRadius),
} }
//edges //edges
sdl.SetRenderDrawColor( sdl.SetRenderDrawColor(renderer_data.renderer, clay_to_sdl_color(config.color))
rendererData.renderer, if config.width.left > 0 {
u8(config.color.r),
u8(config.color.g),
u8(config.color.b),
u8(config.color.a),
)
if (config.width.left > 0) {
starting_y := rect.y + clampedRadii.topLeft starting_y := rect.y + clampedRadii.topLeft
length := rect.h - clampedRadii.topLeft - clampedRadii.bottomLeft length := rect.h - clampedRadii.topLeft - clampedRadii.bottomLeft
line := sdl.FRect{rect.x - 1, starting_y, f32(config.width.left), length} line := sdl.FRect{rect.x - 1, starting_y, f32(config.width.left), length}
sdl.RenderFillRect(rendererData.renderer, &line) sdl.RenderFillRect(renderer_data.renderer, &line)
} }
if (config.width.right > 0) { if config.width.right > 0 {
starting_x := rect.x + rect.w - f32(config.width.right) + 1 starting_x := rect.x + rect.w - f32(config.width.right) + 1
starting_y := rect.y + clampedRadii.topRight starting_y := rect.y + clampedRadii.topRight
length := rect.h - clampedRadii.topRight - clampedRadii.bottomRight length := rect.h - clampedRadii.topRight - clampedRadii.bottomRight
line := sdl.FRect{starting_x, starting_y, f32(config.width.right), length} line := sdl.FRect{starting_x, starting_y, f32(config.width.right), length}
sdl.RenderFillRect(rendererData.renderer, &line) sdl.RenderFillRect(renderer_data.renderer, &line)
} }
if (config.width.top > 0) { if config.width.top > 0 {
starting_x := rect.x + clampedRadii.topLeft starting_x := rect.x + clampedRadii.topLeft
length := rect.w - clampedRadii.topLeft - clampedRadii.topRight length := rect.w - clampedRadii.topLeft - clampedRadii.topRight
line := sdl.FRect{starting_x, rect.y - 1, length, f32(config.width.top)} line := sdl.FRect{starting_x, rect.y - 1, length, f32(config.width.top)}
sdl.RenderFillRect(rendererData.renderer, &line) sdl.RenderFillRect(renderer_data.renderer, &line)
} }
if (config.width.bottom > 0) { if config.width.bottom > 0 {
starting_x := rect.x + clampedRadii.bottomLeft starting_x := rect.x + clampedRadii.bottomLeft
starting_y := rect.y + rect.h - f32(config.width.bottom) + 1 starting_y := rect.y + rect.h - f32(config.width.bottom) + 1
length := rect.w - clampedRadii.bottomLeft - clampedRadii.bottomRight length := rect.w - clampedRadii.bottomLeft - clampedRadii.bottomRight
line := sdl.FRect{starting_x, starting_y, length, f32(config.width.bottom)} line := sdl.FRect{starting_x, starting_y, length, f32(config.width.bottom)}
sdl.SetRenderDrawColor( sdl.SetRenderDrawColor(renderer_data.renderer, clay_to_sdl_color(config.color))
rendererData.renderer, sdl.RenderFillRect(renderer_data.renderer, &line)
u8(config.color.r),
u8(config.color.g),
u8(config.color.b),
u8(config.color.a),
)
sdl.RenderFillRect(rendererData.renderer, &line)
} }
//corners //corners
if (config.cornerRadius.topLeft > 0) { if config.cornerRadius.topLeft > 0 {
centerX := rect.x + clampedRadii.topLeft - 1 centerX := rect.x + clampedRadii.topLeft - 1
centerY := rect.y + clampedRadii.topLeft - 1 centerY := rect.y + clampedRadii.topLeft - 1
sdl_Clay_RenderArc( render_arc(renderer_data, {centerX, centerY}, clampedRadii.topLeft, 180, 270, f32(config.width.top), config.color)
rendererData,
(sdl.FPoint){centerX, centerY},
clampedRadii.topLeft,
180.0,
270.0,
f32(config.width.top),
config.color,
)
} }
if (config.cornerRadius.topRight > 0) { if config.cornerRadius.topRight > 0 {
centerX := rect.x + rect.w - clampedRadii.topRight centerX := rect.x + rect.w - clampedRadii.topRight
centerY := rect.y + clampedRadii.topRight - 1 centerY := rect.y + clampedRadii.topRight - 1
sdl_Clay_RenderArc( render_arc(renderer_data, {centerX, centerY}, clampedRadii.topRight, 270, 360, f32(config.width.top), config.color)
rendererData,
(sdl.FPoint){centerX, centerY},
clampedRadii.topRight,
270.0,
360.0,
f32(config.width.top),
config.color,
)
} }
if (config.cornerRadius.bottomLeft > 0) { if config.cornerRadius.bottomLeft > 0 {
centerX := rect.x + clampedRadii.bottomLeft - 1 centerX := rect.x + clampedRadii.bottomLeft - 1
centerY := rect.y + rect.h - clampedRadii.bottomLeft centerY := rect.y + rect.h - clampedRadii.bottomLeft
sdl_Clay_RenderArc( render_arc(renderer_data, {centerX, centerY}, clampedRadii.bottomLeft, 90, 180, f32(config.width.bottom), config.color)
rendererData,
(sdl.FPoint){centerX, centerY},
clampedRadii.bottomLeft,
90.0,
180.0,
f32(config.width.bottom),
config.color,
)
} }
if (config.cornerRadius.bottomRight > 0) { if config.cornerRadius.bottomRight > 0 {
centerX := rect.x + rect.w - clampedRadii.bottomRight centerX := rect.x + rect.w - clampedRadii.bottomRight
centerY := rect.y + rect.h - clampedRadii.bottomRight centerY := rect.y + rect.h - clampedRadii.bottomRight
sdl_Clay_RenderArc( render_arc(renderer_data, {centerX, centerY}, clampedRadii.bottomRight, 0, 90, f32(config.width.bottom), config.color)
rendererData,
(sdl.FPoint){centerX, centerY},
clampedRadii.bottomRight,
0.0,
90.0,
f32(config.width.bottom),
config.color,
)
} }
case .ScissorStart: case .ScissorStart:
boundingBox := rcmd.boundingBox boundingBox := cmd.boundingBox
currentClippingRectangle = (sdl.Rect) { current_clipping_rect = sdl.Rect {
x = i32(boundingBox.x), x = i32(boundingBox.x),
y = i32(boundingBox.y), y = i32(boundingBox.y),
w = i32(boundingBox.width), w = i32(boundingBox.width),
h = i32(boundingBox.height), h = i32(boundingBox.height),
} }
sdl.SetRenderClipRect(rendererData.renderer, &currentClippingRectangle) sdl.SetRenderClipRect(renderer_data.renderer, &current_clipping_rect)
case .ScissorEnd: case .ScissorEnd:
sdl.SetRenderClipRect(rendererData.renderer, nil) sdl.SetRenderClipRect(renderer_data.renderer, nil)
case .Image: case .Image:
texture := (^sdl.Texture)(rcmd.renderData.image.imageData) texture := (^sdl.Texture)(cmd.renderData.image.imageData)
dest := sdl.FRect{rect.x, rect.y, rect.w, rect.h} dest := sdl.FRect{rect.x, rect.y, rect.w, rect.h}
sdl.RenderTexture(rendererData.renderer, texture, nil, &dest) sdl.RenderTexture(renderer_data.renderer, texture, nil, &dest)
case: case:
sdl.Log("Unknown render command type: %d", rcmd.commandType) sdl.Log("Unknown render command type: %d", cmd.commandType)
} }
} }
} }