Compare commits
7 Commits
f9dca4cdfe
...
master
Author | SHA1 | Date | |
---|---|---|---|
a30a509bcb | |||
|
a3d6a2762e | ||
753793fa89 | |||
|
fcad0ccfc3 | ||
|
b0fe8f0d29 | ||
|
f11f688ea0 | ||
51c46ea279 |
@@ -321,6 +321,10 @@ layout :: proc(layer: ^renderer.Layer) {
|
|||||||
border_color = {0, 0, 0, 1},
|
border_color = {0, 0, 0, 1},
|
||||||
border_width = 10,
|
border_width = 10,
|
||||||
)
|
)
|
||||||
|
|
||||||
renderer.prepare_quad(layer, test_quad)
|
renderer.prepare_quad(layer, test_quad)
|
||||||
|
|
||||||
|
text_ok, text := renderer.text(0, "Raw Text", {bounds.x + 80, bounds.y + 80})
|
||||||
|
if text_ok {
|
||||||
|
renderer.prepare_text(layer, text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,8 +13,8 @@ fi
|
|||||||
|
|
||||||
# Convert GLSL to SPIRV
|
# Convert GLSL to SPIRV
|
||||||
echo "Converting GLSL shaders to SPIRV..."
|
echo "Converting GLSL shaders to SPIRV..."
|
||||||
mkdir -p renderer/res/shaders/compiled
|
mkdir -p res/shaders/compiled
|
||||||
cd renderer/res/shaders/raw || exit
|
cd res/shaders/raw || exit
|
||||||
glslangValidator -V quad.vert -o ../compiled/quad.vert.spv
|
glslangValidator -V quad.vert -o ../compiled/quad.vert.spv
|
||||||
glslangValidator -V quad.frag -o ../compiled/quad.frag.spv
|
glslangValidator -V quad.frag -o ../compiled/quad.frag.spv
|
||||||
glslangValidator -V text.vert -o ../compiled/text.vert.spv
|
glslangValidator -V text.vert -o ../compiled/text.vert.spv
|
||||||
|
@@ -211,7 +211,7 @@ draw_quads :: proc(
|
|||||||
) {
|
) {
|
||||||
using global
|
using global
|
||||||
|
|
||||||
if layer.quad_len == 0 {
|
if layer.quad_instance_len == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,6 +33,7 @@ Global :: struct {
|
|||||||
tmp_quads: [dynamic]Quad,
|
tmp_quads: [dynamic]Quad,
|
||||||
max_tmp_quads: int,
|
max_tmp_quads: int,
|
||||||
clay_mem: [^]u8,
|
clay_mem: [^]u8,
|
||||||
|
clay_z_index: i16,
|
||||||
odin_context: runtime.Context,
|
odin_context: runtime.Context,
|
||||||
quad_pipeline: QuadPipeline,
|
quad_pipeline: QuadPipeline,
|
||||||
text_pipeline: TextPipeline,
|
text_pipeline: TextPipeline,
|
||||||
@@ -68,6 +69,7 @@ clear_global :: proc() {
|
|||||||
using global
|
using global
|
||||||
|
|
||||||
curr_layer_index = 0
|
curr_layer_index = 0
|
||||||
|
clay_z_index = 0
|
||||||
clear(&layers)
|
clear(&layers)
|
||||||
clear(&scissors)
|
clear(&scissors)
|
||||||
clear(&tmp_text)
|
clear(&tmp_text)
|
||||||
@@ -86,7 +88,7 @@ Rectangle :: struct {
|
|||||||
Layer :: struct {
|
Layer :: struct {
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
quad_instance_start: u32,
|
quad_instance_start: u32,
|
||||||
quad_len: u32,
|
quad_instance_len: u32,
|
||||||
text_instance_start: u32,
|
text_instance_start: u32,
|
||||||
text_instance_len: u32,
|
text_instance_len: u32,
|
||||||
text_vertex_start: u32,
|
text_vertex_start: u32,
|
||||||
@@ -184,19 +186,20 @@ begin_prepare :: proc(bounds: Rectangle) -> ^Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new layer
|
/// Creates a new layer
|
||||||
new_layer :: proc(old_layer: ^Layer, bounds: Rectangle) -> ^Layer {
|
new_layer :: proc(prev_layer: ^Layer, bounds: Rectangle) -> ^Layer {
|
||||||
using global
|
using global
|
||||||
layer := Layer {
|
layer := Layer {
|
||||||
bounds = bounds,
|
bounds = bounds,
|
||||||
quad_instance_start = old_layer.quad_instance_start + old_layer.quad_len,
|
quad_instance_start = prev_layer.quad_instance_start + prev_layer.quad_instance_len,
|
||||||
text_instance_start = old_layer.text_instance_start + old_layer.text_instance_len,
|
text_instance_start = prev_layer.text_instance_start + prev_layer.text_instance_len,
|
||||||
text_vertex_start = old_layer.text_vertex_start + old_layer.text_vertex_len,
|
text_vertex_start = prev_layer.text_vertex_start + prev_layer.text_vertex_len,
|
||||||
text_index_start = old_layer.text_index_start + old_layer.text_instance_len,
|
text_index_start = prev_layer.text_index_start + prev_layer.text_index_len,
|
||||||
scissor_start = old_layer.scissor_start + old_layer.scissor_len,
|
scissor_start = prev_layer.scissor_start + prev_layer.scissor_len,
|
||||||
scissor_len = 1,
|
scissor_len = 1,
|
||||||
}
|
}
|
||||||
append(&layers, layer)
|
append(&layers, layer)
|
||||||
curr_layer_index += 1
|
curr_layer_index += 1
|
||||||
|
log.debug("Added new layer; curr index", curr_layer_index)
|
||||||
|
|
||||||
scissor := Scissor {
|
scissor := Scissor {
|
||||||
bounds = sdl.Rect {
|
bounds = sdl.Rect {
|
||||||
@@ -227,10 +230,26 @@ prepare_quad :: proc(layer: ^Layer, quad: Quad) {
|
|||||||
using global
|
using global
|
||||||
|
|
||||||
append(&tmp_quads, quad)
|
append(&tmp_quads, quad)
|
||||||
layer.quad_len += 1
|
layer.quad_instance_len += 1
|
||||||
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO need to make sure no overlap with clay render command IDs
|
||||||
|
prepare_text :: proc(layer: ^Layer, text: Text) {
|
||||||
|
using global
|
||||||
|
|
||||||
|
data := sdl_ttf.GetGPUTextDrawData(text.ref)
|
||||||
|
if data == nil {
|
||||||
|
log.error("Failed to find GPUTextDrawData for sdl_text")
|
||||||
|
}
|
||||||
|
|
||||||
|
append(&tmp_text, text)
|
||||||
|
layer.text_instance_len += 1
|
||||||
|
layer.text_vertex_len += u32(data.num_vertices)
|
||||||
|
layer.text_index_len += u32(data.num_indices)
|
||||||
|
scissors[layer.scissor_start + layer.scissor_len - 1].text_len += 1
|
||||||
|
}
|
||||||
|
|
||||||
// ====== Clay-specific processing ======
|
// ====== Clay-specific processing ======
|
||||||
ClayBatch :: struct {
|
ClayBatch :: struct {
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
@@ -239,7 +258,7 @@ ClayBatch :: struct {
|
|||||||
|
|
||||||
/// Upload data to the GPU
|
/// Upload data to the GPU
|
||||||
prepare_clay_batch :: proc(
|
prepare_clay_batch :: proc(
|
||||||
layer: ^Layer,
|
base_layer: ^Layer,
|
||||||
mouse_pos: [2]f32,
|
mouse_pos: [2]f32,
|
||||||
mouse_flags: sdl.MouseButtonFlags,
|
mouse_flags: sdl.MouseButtonFlags,
|
||||||
mouse_wheel_delta: [2]f32,
|
mouse_wheel_delta: [2]f32,
|
||||||
@@ -250,14 +269,17 @@ prepare_clay_batch :: proc(
|
|||||||
|
|
||||||
// Update clay internals
|
// Update clay internals
|
||||||
clay.SetPointerState(
|
clay.SetPointerState(
|
||||||
clay.Vector2{mouse_pos.x - layer.bounds.x, mouse_pos.y - layer.bounds.y},
|
clay.Vector2{mouse_pos.x - base_layer.bounds.x, mouse_pos.y - base_layer.bounds.y},
|
||||||
.LEFT in mouse_flags,
|
.LEFT in mouse_flags,
|
||||||
)
|
)
|
||||||
clay.UpdateScrollContainers(true, transmute(clay.Vector2)mouse_wheel_delta, frame_time)
|
clay.UpdateScrollContainers(true, transmute(clay.Vector2)mouse_wheel_delta, frame_time)
|
||||||
|
|
||||||
|
layer := base_layer
|
||||||
|
|
||||||
// Parse render commands
|
// Parse render commands
|
||||||
for i in 0 ..< int(batch.cmds.length) {
|
for i in 0 ..< int(batch.cmds.length) {
|
||||||
render_command := clay.RenderCommandArray_Get(&batch.cmds, cast(i32)i)
|
render_command := clay.RenderCommandArray_Get(&batch.cmds, cast(i32)i)
|
||||||
|
|
||||||
// Translate bounding box of the primitive by the layer position
|
// Translate bounding box of the primitive by the layer position
|
||||||
bounds := Rectangle {
|
bounds := Rectangle {
|
||||||
x = render_command.boundingBox.x + layer.bounds.x,
|
x = render_command.boundingBox.x + layer.bounds.x,
|
||||||
@@ -266,6 +288,18 @@ prepare_clay_batch :: proc(
|
|||||||
h = render_command.boundingBox.height,
|
h = render_command.boundingBox.height,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if render_command.zIndex > clay_z_index {
|
||||||
|
log.debug(
|
||||||
|
"Higher zIndex found, creating new layer & setting z_index to",
|
||||||
|
render_command.zIndex,
|
||||||
|
)
|
||||||
|
layer = new_layer(layer, bounds)
|
||||||
|
// Update bounds to new layer offset
|
||||||
|
bounds.x = render_command.boundingBox.x + layer.bounds.x
|
||||||
|
bounds.y = render_command.boundingBox.y + layer.bounds.y
|
||||||
|
clay_z_index = render_command.zIndex
|
||||||
|
}
|
||||||
|
|
||||||
switch (render_command.commandType) {
|
switch (render_command.commandType) {
|
||||||
case clay.RenderCommandType.None:
|
case clay.RenderCommandType.None:
|
||||||
case clay.RenderCommandType.Text:
|
case clay.RenderCommandType.Text:
|
||||||
@@ -347,7 +381,7 @@ prepare_clay_batch :: proc(
|
|||||||
}
|
}
|
||||||
append(&tmp_quads, quad)
|
append(&tmp_quads, quad)
|
||||||
|
|
||||||
layer.quad_len += 1
|
layer.quad_instance_len += 1
|
||||||
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
||||||
case clay.RenderCommandType.Border:
|
case clay.RenderCommandType.Border:
|
||||||
render_data := render_command.renderData.border
|
render_data := render_command.renderData.border
|
||||||
@@ -363,7 +397,7 @@ prepare_clay_batch :: proc(
|
|||||||
// Technically these should be drawn on top of everything else including children, but
|
// Technically these should be drawn on top of everything else including children, but
|
||||||
// for our use case we can just chuck these in with the quad pipeline
|
// for our use case we can just chuck these in with the quad pipeline
|
||||||
append(&tmp_quads, quad)
|
append(&tmp_quads, quad)
|
||||||
layer.quad_len += 1
|
layer.quad_instance_len += 1
|
||||||
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
scissors[layer.scissor_start + layer.scissor_len - 1].quad_len += 1
|
||||||
case clay.RenderCommandType.Custom:
|
case clay.RenderCommandType.Custom:
|
||||||
}
|
}
|
||||||
@@ -386,6 +420,7 @@ draw :: proc(device: ^sdl.GPUDevice, window: ^sdl.Window, cmd_buffer: ^sdl.GPUCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
for &layer, index in layers {
|
for &layer, index in layers {
|
||||||
|
log.debug("Drawing layer", index)
|
||||||
draw_quads(
|
draw_quads(
|
||||||
device,
|
device,
|
||||||
window,
|
window,
|
||||||
|
@@ -61,6 +61,38 @@ Text :: struct {
|
|||||||
color: [4]f32,
|
color: [4]f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text :: proc(
|
||||||
|
id: u32,
|
||||||
|
txt: cstring,
|
||||||
|
pos: [2]f32,
|
||||||
|
color: [4]f32 = {0.0, 0.0, 0.0, 1.0},
|
||||||
|
font_id: u16 = JETBRAINS_MONO_REGULAR,
|
||||||
|
font_size: u16 = 44,
|
||||||
|
) -> (bool, Text) {
|
||||||
|
using global
|
||||||
|
|
||||||
|
sdl_text := text_pipeline.cache[id]
|
||||||
|
if sdl_text == nil {
|
||||||
|
sdl_text = sdl_ttf.CreateText(text_pipeline.engine, get_font(font_id, font_size), txt, 0)
|
||||||
|
text_pipeline.cache[id] = sdl_text
|
||||||
|
} else {
|
||||||
|
//TODO if IDs are always unique and never change the underlying text
|
||||||
|
// can get rid of this
|
||||||
|
_ = sdl_ttf.SetTextString(sdl_text, txt, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sdl_text == nil {
|
||||||
|
log.error("Could not create SDL text:", sdl.GetError())
|
||||||
|
return false, Text {}
|
||||||
|
} else {
|
||||||
|
return true, Text {
|
||||||
|
sdl_text,
|
||||||
|
pos,
|
||||||
|
color,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For upload
|
// For upload
|
||||||
TextVert :: struct {
|
TextVert :: struct {
|
||||||
pos_uv: [4]f32,
|
pos_uv: [4]f32,
|
||||||
@@ -383,9 +415,8 @@ draw_text :: proc(
|
|||||||
|
|
||||||
atlas: ^sdl.GPUTexture
|
atlas: ^sdl.GPUTexture
|
||||||
|
|
||||||
layer_text := tmp_text[layer.text_instance_start:layer.text_instance_start +
|
layer_text := tmp_text[layer.text_instance_start:][:layer.text_instance_len]
|
||||||
layer.text_instance_len]
|
index_offset: u32 = layer.text_index_start
|
||||||
index_offset: u32 = layer.text_instance_start
|
|
||||||
vertex_offset: i32 = i32(layer.text_vertex_start)
|
vertex_offset: i32 = i32(layer.text_vertex_start)
|
||||||
instance_offset: u32 = layer.text_instance_start
|
instance_offset: u32 = layer.text_instance_start
|
||||||
|
|
||||||
@@ -396,7 +427,7 @@ draw_text :: proc(
|
|||||||
|
|
||||||
sdl.SetGPUScissor(render_pass, scissor.bounds)
|
sdl.SetGPUScissor(render_pass, scissor.bounds)
|
||||||
|
|
||||||
for &text in layer_text[scissor.text_start:scissor.text_start + scissor.text_len] {
|
for &text in layer_text[scissor.text_start:][:scissor.text_len] {
|
||||||
data := sdl_ttf.GetGPUTextDrawData(text.ref)
|
data := sdl_ttf.GetGPUTextDrawData(text.ref)
|
||||||
|
|
||||||
for data != nil {
|
for data != nil {
|
||||||
|
Reference in New Issue
Block a user