Massive renaming
This commit is contained in:
175
draw/draw.odin
175
draw/draw.odin
@@ -36,14 +36,14 @@ BLUE :: Color{0, 0, 255, 255}
|
||||
BLANK :: Color{0, 0, 0, 0}
|
||||
|
||||
// Convert clay.Color ([4]c.float in 0–255 range) to Color.
|
||||
color_from_clay :: proc(cc: clay.Color) -> Color {
|
||||
return Color{u8(cc[0]), u8(cc[1]), u8(cc[2]), u8(cc[3])}
|
||||
color_from_clay :: proc(clay_color: clay.Color) -> Color {
|
||||
return Color{u8(clay_color[0]), u8(clay_color[1]), u8(clay_color[2]), u8(clay_color[3])}
|
||||
}
|
||||
|
||||
// Convert Color to [4]f32 in 0.0–1.0 range. Useful for SDL interop (e.g. clear color).
|
||||
color_to_f32 :: proc(c: Color) -> [4]f32 {
|
||||
color_to_f32 :: proc(color: Color) -> [4]f32 {
|
||||
INV :: 1.0 / 255.0
|
||||
return {f32(c[0]) * INV, f32(c[1]) * INV, f32(c[2]) * INV, f32(c[3]) * INV}
|
||||
return {f32(color[0]) * INV, f32(color[1]) * INV, f32(color[2]) * INV, f32(color[3]) * INV}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
@@ -51,10 +51,10 @@ color_to_f32 :: proc(c: Color) -> [4]f32 {
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Rectangle :: struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
w: f32,
|
||||
h: f32,
|
||||
x: f32,
|
||||
y: f32,
|
||||
width: f32,
|
||||
height: f32,
|
||||
}
|
||||
|
||||
Sub_Batch_Kind :: enum u8 {
|
||||
@@ -102,7 +102,7 @@ Global :: struct {
|
||||
tmp_primitives: [dynamic]Primitive,
|
||||
tmp_sub_batches: [dynamic]Sub_Batch,
|
||||
tmp_uncached_text: [dynamic]^sdl_ttf.Text, // Uncached TTF_Text objects to destroy after end()
|
||||
clay_mem: [^]u8,
|
||||
clay_memory: [^]u8,
|
||||
msaa_texture: ^sdl.GPUTexture,
|
||||
curr_layer_index: uint,
|
||||
max_layers: int,
|
||||
@@ -114,8 +114,8 @@ Global :: struct {
|
||||
max_primitives: int,
|
||||
max_sub_batches: int,
|
||||
dpi_scaling: f32,
|
||||
msaa_w: u32,
|
||||
msaa_h: u32,
|
||||
msaa_width: u32,
|
||||
msaa_height: u32,
|
||||
sample_count: sdl.GPUSampleCount,
|
||||
clay_z_index: i16,
|
||||
cleared: bool,
|
||||
@@ -174,13 +174,13 @@ init :: proc(
|
||||
tmp_uncached_text = make([dynamic]^sdl_ttf.Text, 0, 16, allocator = allocator),
|
||||
odin_context = odin_context,
|
||||
dpi_scaling = sdl.GetWindowDisplayScale(window),
|
||||
clay_mem = make([^]u8, min_memory_size, allocator = allocator),
|
||||
clay_memory = make([^]u8, min_memory_size, allocator = allocator),
|
||||
sample_count = resolved_sample_count,
|
||||
pipeline_2d_base = pipeline,
|
||||
text_cache = text_cache,
|
||||
}
|
||||
log.debug("Window DPI scaling:", GLOB.dpi_scaling)
|
||||
arena := clay.CreateArenaWithCapacityAndMemory(min_memory_size, GLOB.clay_mem)
|
||||
arena := clay.CreateArenaWithCapacityAndMemory(min_memory_size, GLOB.clay_memory)
|
||||
window_width, window_height: c.int
|
||||
sdl.GetWindowSize(window, &window_width, &window_height)
|
||||
|
||||
@@ -219,9 +219,9 @@ destroy :: proc(device: ^sdl.GPUDevice, allocator := context.allocator) {
|
||||
delete(GLOB.tmp_text_batches)
|
||||
delete(GLOB.tmp_primitives)
|
||||
delete(GLOB.tmp_sub_batches)
|
||||
for t in GLOB.tmp_uncached_text do sdl_ttf.DestroyText(t)
|
||||
for ttf_text in GLOB.tmp_uncached_text do sdl_ttf.DestroyText(ttf_text)
|
||||
delete(GLOB.tmp_uncached_text)
|
||||
free(GLOB.clay_mem, allocator)
|
||||
free(GLOB.clay_memory, allocator)
|
||||
if GLOB.msaa_texture != nil {
|
||||
sdl.ReleaseGPUTexture(device, GLOB.msaa_texture)
|
||||
}
|
||||
@@ -235,7 +235,7 @@ clear_global :: proc() {
|
||||
GLOB.clay_z_index = 0
|
||||
GLOB.cleared = false
|
||||
// Destroy uncached TTF_Text objects from the previous frame (after end() has submitted draw data)
|
||||
for t in GLOB.tmp_uncached_text do sdl_ttf.DestroyText(t)
|
||||
for ttf_text in GLOB.tmp_uncached_text do sdl_ttf.DestroyText(ttf_text)
|
||||
clear(&GLOB.tmp_uncached_text)
|
||||
clear(&GLOB.layers)
|
||||
clear(&GLOB.scissors)
|
||||
@@ -260,12 +260,12 @@ measure_text_clay :: proc "c" (
|
||||
context = GLOB.odin_context
|
||||
text := string(text.chars[:text.length])
|
||||
c_text := strings.clone_to_cstring(text, context.temp_allocator)
|
||||
w, h: c.int
|
||||
if !sdl_ttf.GetStringSize(get_font(config.fontId, config.fontSize), c_text, 0, &w, &h) {
|
||||
width, height: c.int
|
||||
if !sdl_ttf.GetStringSize(get_font(config.fontId, config.fontSize), c_text, 0, &width, &height) {
|
||||
log.panicf("Failed to measure text: %s", sdl.GetError())
|
||||
}
|
||||
|
||||
return clay.Dimensions{width = f32(w) / GLOB.dpi_scaling, height = f32(h) / GLOB.dpi_scaling}
|
||||
return clay.Dimensions{width = f32(width) / GLOB.dpi_scaling, height = f32(height) / GLOB.dpi_scaling}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
@@ -282,8 +282,8 @@ begin :: proc(bounds: Rectangle) -> ^Layer {
|
||||
bounds = sdl.Rect {
|
||||
x = i32(bounds.x * GLOB.dpi_scaling),
|
||||
y = i32(bounds.y * GLOB.dpi_scaling),
|
||||
w = i32(bounds.w * GLOB.dpi_scaling),
|
||||
h = i32(bounds.h * GLOB.dpi_scaling),
|
||||
w = i32(bounds.width * GLOB.dpi_scaling),
|
||||
h = i32(bounds.height * GLOB.dpi_scaling),
|
||||
},
|
||||
}
|
||||
append(&GLOB.scissors, scissor)
|
||||
@@ -313,8 +313,8 @@ new_layer :: proc(prev_layer: ^Layer, bounds: Rectangle) -> ^Layer {
|
||||
bounds = sdl.Rect {
|
||||
x = i32(bounds.x * GLOB.dpi_scaling),
|
||||
y = i32(bounds.y * GLOB.dpi_scaling),
|
||||
w = i32(bounds.w * GLOB.dpi_scaling),
|
||||
h = i32(bounds.h * GLOB.dpi_scaling),
|
||||
w = i32(bounds.width * GLOB.dpi_scaling),
|
||||
h = i32(bounds.height * GLOB.dpi_scaling),
|
||||
},
|
||||
}
|
||||
append(&GLOB.scissors, scissor)
|
||||
@@ -344,8 +344,8 @@ prepare_sdf_primitive :: proc(layer: ^Layer, prim: Primitive) {
|
||||
|
||||
// Submit a text element to the given layer for rendering.
|
||||
// Copies SDL_ttf vertices directly (with baked position) and copies indices for indexed drawing.
|
||||
prepare_text :: proc(layer: ^Layer, txt: Text) {
|
||||
data := sdl_ttf.GetGPUTextDrawData(txt.ref)
|
||||
prepare_text :: proc(layer: ^Layer, text: Text) {
|
||||
data := sdl_ttf.GetGPUTextDrawData(text.sdl_text)
|
||||
if data == nil {
|
||||
return // nil is normal for empty text
|
||||
}
|
||||
@@ -363,9 +363,9 @@ prepare_text :: proc(layer: ^Layer, txt: Text) {
|
||||
append(
|
||||
&GLOB.tmp_text_verts,
|
||||
Vertex {
|
||||
position = {pos.x + txt.position[0] * GLOB.dpi_scaling, -pos.y + txt.position[1] * GLOB.dpi_scaling},
|
||||
position = {pos.x + text.position[0] * GLOB.dpi_scaling, -pos.y + text.position[1] * GLOB.dpi_scaling},
|
||||
uv = {uv.x, uv.y},
|
||||
color = txt.color,
|
||||
color = text.color,
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -396,8 +396,8 @@ prepare_text :: proc(layer: ^Layer, txt: Text) {
|
||||
// Used by the high-level `text` proc when rotation or a non-zero origin is specified.
|
||||
// NOTE: xform must be in physical (DPI-scaled) pixel space — the caller pre-scales
|
||||
// pos and origin by GLOB.dpi_scaling before building the transform.
|
||||
prepare_text_transformed :: proc(layer: ^Layer, txt: Text, xform: Transform_2D) {
|
||||
data := sdl_ttf.GetGPUTextDrawData(txt.ref)
|
||||
prepare_text_transformed :: proc(layer: ^Layer, text: Text, transform: Transform_2D) {
|
||||
data := sdl_ttf.GetGPUTextDrawData(text.sdl_text)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
@@ -416,7 +416,7 @@ prepare_text_transformed :: proc(layer: ^Layer, txt: Text, xform: Transform_2D)
|
||||
// so we apply directly — no per-vertex DPI divide/multiply.
|
||||
append(
|
||||
&GLOB.tmp_text_verts,
|
||||
Vertex{position = apply_transform(xform, {pos.x, -pos.y}), uv = {uv.x, uv.y}, color = txt.color},
|
||||
Vertex{position = apply_transform(transform, {pos.x, -pos.y}), uv = {uv.x, uv.y}, color = text.color},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -501,10 +501,10 @@ prepare_clay_batch :: proc(
|
||||
|
||||
// Translate bounding box of the primitive by the layer position
|
||||
bounds := Rectangle {
|
||||
x = render_command.boundingBox.x + layer.bounds.x,
|
||||
y = render_command.boundingBox.y + layer.bounds.y,
|
||||
w = render_command.boundingBox.width,
|
||||
h = render_command.boundingBox.height,
|
||||
x = render_command.boundingBox.x + layer.bounds.x,
|
||||
y = render_command.boundingBox.y + layer.bounds.y,
|
||||
width = render_command.boundingBox.width,
|
||||
height = render_command.boundingBox.height,
|
||||
}
|
||||
|
||||
if render_command.zIndex > GLOB.clay_z_index {
|
||||
@@ -532,9 +532,7 @@ prepare_clay_batch :: proc(
|
||||
prepare_text(layer, Text{sdl_text, {bounds.x, bounds.y}, color_from_clay(render_data.textColor)})
|
||||
case clay.RenderCommandType.Image:
|
||||
case clay.RenderCommandType.ScissorStart:
|
||||
if bounds.w == 0 || bounds.h == 0 {
|
||||
continue
|
||||
}
|
||||
if bounds.width == 0 || bounds.height == 0 do continue
|
||||
|
||||
curr_scissor := &GLOB.scissors[layer.scissor_start + layer.scissor_len - 1]
|
||||
|
||||
@@ -545,8 +543,8 @@ prepare_clay_batch :: proc(
|
||||
bounds = sdl.Rect {
|
||||
c.int(bounds.x * GLOB.dpi_scaling),
|
||||
c.int(bounds.y * GLOB.dpi_scaling),
|
||||
c.int(bounds.w * GLOB.dpi_scaling),
|
||||
c.int(bounds.h * GLOB.dpi_scaling),
|
||||
c.int(bounds.width * GLOB.dpi_scaling),
|
||||
c.int(bounds.height * GLOB.dpi_scaling),
|
||||
},
|
||||
}
|
||||
append(&GLOB.scissors, new)
|
||||
@@ -555,8 +553,8 @@ prepare_clay_batch :: proc(
|
||||
curr_scissor.bounds = sdl.Rect {
|
||||
c.int(bounds.x * GLOB.dpi_scaling),
|
||||
c.int(bounds.y * GLOB.dpi_scaling),
|
||||
c.int(bounds.w * GLOB.dpi_scaling),
|
||||
c.int(bounds.h * GLOB.dpi_scaling),
|
||||
c.int(bounds.width * GLOB.dpi_scaling),
|
||||
c.int(bounds.height * GLOB.dpi_scaling),
|
||||
}
|
||||
}
|
||||
case clay.RenderCommandType.ScissorEnd:
|
||||
@@ -575,13 +573,13 @@ prepare_clay_batch :: proc(
|
||||
render_data := render_command.renderData.border
|
||||
cr := render_data.cornerRadius
|
||||
color := color_from_clay(render_data.color)
|
||||
thick := f32(render_data.width.top)
|
||||
thickness := f32(render_data.width.top)
|
||||
radii := [4]f32{cr.topLeft, cr.topRight, cr.bottomRight, cr.bottomLeft}
|
||||
|
||||
if radii == {0, 0, 0, 0} {
|
||||
rectangle_lines(layer, bounds, color, thick)
|
||||
rectangle_lines(layer, bounds, color, thickness)
|
||||
} else {
|
||||
rectangle_corners_lines(layer, bounds, radii, color, thick)
|
||||
rectangle_corners_lines(layer, bounds, radii, color, thickness)
|
||||
}
|
||||
case clay.RenderCommandType.Custom:
|
||||
}
|
||||
@@ -601,8 +599,8 @@ end :: proc(device: ^sdl.GPUDevice, window: ^sdl.Window, clear_color: Color = BL
|
||||
sdl.EndGPUCopyPass(copy_pass)
|
||||
|
||||
swapchain_texture: ^sdl.GPUTexture
|
||||
w, h: u32
|
||||
if !sdl.WaitAndAcquireGPUSwapchainTexture(cmd_buffer, window, &swapchain_texture, &w, &h) {
|
||||
width, height: u32
|
||||
if !sdl.WaitAndAcquireGPUSwapchainTexture(cmd_buffer, window, &swapchain_texture, &width, &height) {
|
||||
log.panicf("Failed to acquire swapchain texture: %s", sdl.GetError())
|
||||
}
|
||||
|
||||
@@ -618,16 +616,16 @@ end :: proc(device: ^sdl.GPUDevice, window: ^sdl.Window, clear_color: Color = BL
|
||||
render_texture := swapchain_texture
|
||||
|
||||
if use_msaa {
|
||||
ensure_msaa_texture(device, sdl.GetGPUSwapchainTextureFormat(device, window), w, h)
|
||||
ensure_msaa_texture(device, sdl.GetGPUSwapchainTextureFormat(device, window), width, height)
|
||||
render_texture = GLOB.msaa_texture
|
||||
}
|
||||
|
||||
cc := color_to_f32(clear_color)
|
||||
clear_color_f32 := color_to_f32(clear_color)
|
||||
|
||||
// Draw layers. One render pass per layer; sub-batches draw in submission order within each scissor.
|
||||
for &layer, index in GLOB.layers {
|
||||
log.debug("Drawing layer", index)
|
||||
draw_layer(device, window, cmd_buffer, render_texture, w, h, cc, &layer)
|
||||
draw_layer(device, window, cmd_buffer, render_texture, width, height, clear_color_f32, &layer)
|
||||
}
|
||||
|
||||
// Resolve MSAA render texture to the swapchain.
|
||||
@@ -659,15 +657,15 @@ end :: proc(device: ^sdl.GPUDevice, window: ^sdl.Window, clear_color: Color = BL
|
||||
max_sample_count :: proc(device: ^sdl.GPUDevice, window: ^sdl.Window) -> sdl.GPUSampleCount {
|
||||
format := sdl.GetGPUSwapchainTextureFormat(device, window)
|
||||
counts := [?]sdl.GPUSampleCount{._8, ._4, ._2}
|
||||
for sc in counts {
|
||||
if sdl.GPUTextureSupportsSampleCount(device, format, sc) do return sc
|
||||
for count in counts {
|
||||
if sdl.GPUTextureSupportsSampleCount(device, format, count) do return count
|
||||
}
|
||||
return ._1
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
ensure_msaa_texture :: proc(device: ^sdl.GPUDevice, format: sdl.GPUTextureFormat, w, h: u32) {
|
||||
if GLOB.msaa_texture != nil && GLOB.msaa_w == w && GLOB.msaa_h == h {
|
||||
ensure_msaa_texture :: proc(device: ^sdl.GPUDevice, format: sdl.GPUTextureFormat, width, height: u32) {
|
||||
if GLOB.msaa_texture != nil && GLOB.msaa_width == width && GLOB.msaa_height == height {
|
||||
return
|
||||
}
|
||||
if GLOB.msaa_texture != nil {
|
||||
@@ -679,18 +677,18 @@ ensure_msaa_texture :: proc(device: ^sdl.GPUDevice, format: sdl.GPUTextureFormat
|
||||
type = .D2,
|
||||
format = format,
|
||||
usage = {.COLOR_TARGET},
|
||||
width = w,
|
||||
height = h,
|
||||
width = width,
|
||||
height = height,
|
||||
layer_count_or_depth = 1,
|
||||
num_levels = 1,
|
||||
sample_count = GLOB.sample_count,
|
||||
},
|
||||
)
|
||||
if GLOB.msaa_texture == nil {
|
||||
log.panicf("Failed to create MSAA texture (%dx%d): %s", w, h, sdl.GetError())
|
||||
log.panicf("Failed to create MSAA texture (%dx%d): %s", width, height, sdl.GetError())
|
||||
}
|
||||
GLOB.msaa_w = w
|
||||
GLOB.msaa_h = h
|
||||
GLOB.msaa_width = width
|
||||
GLOB.msaa_height = height
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
@@ -718,9 +716,21 @@ Vertex_Uniforms :: struct {
|
||||
}
|
||||
|
||||
// Push projection, dpi scale, and rendering mode as a single uniform block (slot 0).
|
||||
push_globals :: proc(cmd_buffer: ^sdl.GPUCommandBuffer, w: f32, h: f32, mode: Draw_Mode = .Tessellated) {
|
||||
push_globals :: proc(
|
||||
cmd_buffer: ^sdl.GPUCommandBuffer,
|
||||
width: f32,
|
||||
height: f32,
|
||||
mode: Draw_Mode = .Tessellated,
|
||||
) {
|
||||
globals := Vertex_Uniforms {
|
||||
projection = ortho_rh(left = 0.0, top = 0.0, right = f32(w), bottom = f32(h), near = -1.0, far = 1.0),
|
||||
projection = ortho_rh(
|
||||
left = 0.0,
|
||||
top = 0.0,
|
||||
right = f32(width),
|
||||
bottom = f32(height),
|
||||
near = -1.0,
|
||||
far = 1.0,
|
||||
),
|
||||
scale = GLOB.dpi_scaling,
|
||||
mode = mode,
|
||||
}
|
||||
@@ -818,23 +828,26 @@ Transform_2D :: struct {
|
||||
// origin – pivot point in local space (measured from the shape's natural reference point).
|
||||
// rotation_deg – rotation in degrees, counter-clockwise.
|
||||
//
|
||||
build_pivot_rot :: proc(pos: [2]f32, origin: [2]f32, rotation_deg: f32) -> Transform_2D {
|
||||
rad := math.to_radians(rotation_deg)
|
||||
c := math.cos(rad)
|
||||
s := math.sin(rad)
|
||||
build_pivot_rotation :: proc(position: [2]f32, origin: [2]f32, rotation_deg: f32) -> Transform_2D {
|
||||
radians := math.to_radians(rotation_deg)
|
||||
cos_angle := math.cos(radians)
|
||||
sin_angle := math.sin(radians)
|
||||
return Transform_2D {
|
||||
m00 = c,
|
||||
m01 = -s,
|
||||
m10 = s,
|
||||
m11 = c,
|
||||
tx = pos.x - (c * origin.x - s * origin.y),
|
||||
ty = pos.y - (s * origin.x + c * origin.y),
|
||||
m00 = cos_angle,
|
||||
m01 = -sin_angle,
|
||||
m10 = sin_angle,
|
||||
m11 = cos_angle,
|
||||
tx = position.x - (cos_angle * origin.x - sin_angle * origin.y),
|
||||
ty = position.y - (sin_angle * origin.x + cos_angle * origin.y),
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the transform to a local-space point, producing a world-space point.
|
||||
apply_transform :: #force_inline proc(t: Transform_2D, p: [2]f32) -> [2]f32 {
|
||||
return {t.m00 * p.x + t.m01 * p.y + t.tx, t.m10 * p.x + t.m11 * p.y + t.ty}
|
||||
apply_transform :: #force_inline proc(transform: Transform_2D, point: [2]f32) -> [2]f32 {
|
||||
return {
|
||||
transform.m00 * point.x + transform.m01 * point.y + transform.tx,
|
||||
transform.m10 * point.x + transform.m11 * point.y + transform.ty,
|
||||
}
|
||||
}
|
||||
|
||||
// Fast-path check callers use BEFORE building a transform.
|
||||
@@ -849,55 +862,55 @@ needs_transform :: #force_inline proc(origin: [2]f32, rotation: f32) -> bool {
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
center_of :: proc {
|
||||
center_of_rect,
|
||||
center_of_rectangle,
|
||||
center_of_triangle,
|
||||
center_of_text,
|
||||
}
|
||||
|
||||
top_left_of :: proc {
|
||||
top_left_of_rect,
|
||||
top_left_of_rectangle,
|
||||
top_left_of_triangle,
|
||||
top_left_of_text,
|
||||
}
|
||||
|
||||
top_of :: proc {
|
||||
top_of_rect,
|
||||
top_of_rectangle,
|
||||
top_of_triangle,
|
||||
top_of_text,
|
||||
}
|
||||
|
||||
top_right_of :: proc {
|
||||
top_right_of_rect,
|
||||
top_right_of_rectangle,
|
||||
top_right_of_triangle,
|
||||
top_right_of_text,
|
||||
}
|
||||
|
||||
left_of :: proc {
|
||||
left_of_rect,
|
||||
left_of_rectangle,
|
||||
left_of_triangle,
|
||||
left_of_text,
|
||||
}
|
||||
|
||||
right_of :: proc {
|
||||
right_of_rect,
|
||||
right_of_rectangle,
|
||||
right_of_triangle,
|
||||
right_of_text,
|
||||
}
|
||||
|
||||
bottom_left_of :: proc {
|
||||
bottom_left_of_rect,
|
||||
bottom_left_of_rectangle,
|
||||
bottom_left_of_triangle,
|
||||
bottom_left_of_text,
|
||||
}
|
||||
|
||||
bottom_of :: proc {
|
||||
bottom_of_rect,
|
||||
bottom_of_rectangle,
|
||||
bottom_of_triangle,
|
||||
bottom_of_text,
|
||||
}
|
||||
|
||||
bottom_right_of :: proc {
|
||||
bottom_right_of_rect,
|
||||
bottom_right_of_rectangle,
|
||||
bottom_right_of_triangle,
|
||||
bottom_right_of_text,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user