Primitive border drawing and rounded corners

This commit is contained in:
David Gonzalez Martin 2024-12-24 18:56:25 -06:00 committed by David
parent b063d570b1
commit 9dec588ec1
17 changed files with 262 additions and 246 deletions

View File

@ -56,43 +56,28 @@ typedef enum Corner
CORNER_COUNT,
} Corner;
STRUCT(U32Vec2)
{
struct
{
u32 x;
u32 y;
};
u32 v[2];
};
typedef float float2 __attribute__((ext_vector_type(2)));
typedef float float3 __attribute__((ext_vector_type(3)));
typedef float float4 __attribute__((ext_vector_type(4)));
typedef float2 vec2;
typedef float3 vec3;
typedef float4 vec4;
STRUCT(F32Vec4)
{
f32 v[4];
};
typedef F32Vec4 Color;
UNION(F32Vec2)
{
struct
{
f32 x;
f32 y;
};
f32 v[2];
};
typedef u32 uint2 __attribute__((ext_vector_type(2)));
typedef u32 uint3 __attribute__((ext_vector_type(3)));
typedef u32 uint4 __attribute__((ext_vector_type(4)));
UNION(F32Interval2)
{
struct
{
F32Vec2 min;
F32Vec2 max;
float2 min;
float2 max;
};
struct
{
F32Vec2 p0;
F32Vec2 p1;
float2 p0;
float2 p1;
};
struct
{
@ -101,9 +86,11 @@ UNION(F32Interval2)
f32 x1;
f32 y1;
};
F32Vec2 v[2];
float2 v[2];
};
static_assert(sizeof(F32Interval2) == 4 * sizeof(f32));
typedef enum Axis2
{
AXIS2_X,

View File

@ -37,4 +37,4 @@ STRUCT(TextureAtlasCreate)
#include <std/render.h>
EXPORT TextureAtlas font_texture_atlas_create(Arena* arena, Renderer* renderer, TextureAtlasCreate create);
EXPORT U32Vec2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atlas);
EXPORT uint2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atlas);

View File

@ -1,6 +1,5 @@
#pragma once
#include <std/base.h>
typedef struct Renderer Renderer;
@ -11,41 +10,18 @@ typedef struct Renderer Renderer;
typedef struct RenderWindow RenderWindow;
typedef struct Pipeline Pipeline;
STRUCT(RenderRect)
{
u32 x0;
u32 y0;
u32 x1;
u32 y1;
};
STRUCT(RectColors)
{
F32Vec4 v[4];
};
STRUCT(RectDraw)
{
RenderRect vertex;
RenderRect texture;
RectColors colors;
F32Interval2 vertex;
F32Interval2 texture;
vec4 colors[4];
u32 texture_index;
};
STRUCT(RectVertex)
{
f32 x;
f32 y;
f32 uv_x;
f32 uv_y;
RectColors colors;
u32 texture_index;
u32 reserved[3];
};
#include "../std/shaders/rect.inc"
typedef struct RectVertex RectVertex;
decl_vb(RectVertex);
#define Color4(r, g, b, a) ((F32Vec4){ .v = { r, g, b, a } })
typedef enum BBPipeline
{
BB_PIPELINE_RECT,
@ -187,7 +163,7 @@ EXPORT PipelineLayoutIndex renderer_pipeline_get_layout(PipelineIndex pipeline);
EXPORT void renderer_window_frame_begin(Renderer* renderer, RenderWindow* window);
EXPORT void renderer_window_frame_end(Renderer* renderer, RenderWindow* window);
EXPORT TextureIndex renderer_texture_create(Renderer* renderer, TextureMemory texture_memory);
EXPORT U32Vec2 renderer_font_compute_string_rect(Renderer* renderer, RenderFontType type, String string);
EXPORT uint2 renderer_font_compute_string_rect(Renderer* renderer, RenderFontType type, String string);
EXPORT void window_command_begin(RenderWindow* window);
EXPORT void window_command_end(RenderWindow* window);
EXPORT void window_render_begin(RenderWindow* window);
@ -203,4 +179,4 @@ EXPORT void window_rect_texture_update_end(Renderer* renderer, RenderWindow* win
EXPORT u32 window_pipeline_add_vertices(RenderWindow* window, BBPipeline pipeline_index, String vertex_memory, u32 vertex_count);
EXPORT void window_pipeline_add_indices(RenderWindow* window, BBPipeline pipeline_index, Slice(u32) indices);
EXPORT void window_render_rect(RenderWindow* window, RectDraw draw);
EXPORT void window_render_text(Renderer* renderer, RenderWindow* window, String string, Color color, RenderFontType font_type, u32 x_offset, u32 y_offset);
EXPORT void window_render_text(Renderer* renderer, RenderWindow* window, String string, float4 color, RenderFontType font_type, u32 x_offset, u32 y_offset);

View File

@ -87,19 +87,19 @@ STRUCT(UI_Widget)
UI_WidgetFlags flags;
// Data known after size determination happens
F32Vec2 computed_size;
F32Vec2 computed_relative_position;
float2 computed_size;
float2 computed_relative_position;
// Data known after layout computation happens
F32Interval2 relative_rect;
F32Interval2 rect;
F32Vec2 relative_corner_delta[CORNER_COUNT];
float2 relative_corner_delta[CORNER_COUNT];
// Persistent data across frames
u64 last_build_touched;
F32Vec2 view_offset;
Color background_color;
Color text_color;
float2 view_offset;
float4 background_color;
float4 text_color;
};
decl_vbp(UI_Widget);
@ -111,7 +111,7 @@ STRUCT(UI_WidgetSlot)
declare_slice(UI_WidgetSlot);
decl_vb(Axis2);
decl_vb(Color);
decl_vb(float4);
STRUCT(UI_StateStackAutoPops)
{
@ -131,8 +131,8 @@ STRUCT(UI_StateStackNulls)
UI_Size pref_width;
UI_Size pref_height;
Axis2 child_layout_axis;
Color text_color;
Color background_color;
float4 text_color;
float4 background_color;
f32 font_size;
};
@ -142,8 +142,8 @@ STRUCT(UI_StateStacks)
VirtualBuffer(UI_Size) pref_width;
VirtualBuffer(UI_Size) pref_height;
VirtualBuffer(Axis2) child_layout_axis;
VirtualBuffer(Color) text_color;
VirtualBuffer(Color) background_color;
VirtualBuffer(float4) text_color;
VirtualBuffer(float4) background_color;
VirtualBuffer(f32) font_size;
};

View File

@ -1,21 +0,0 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : require
#extension GL_EXT_debug_printf : require
#extension GL_GOOGLE_include_directive : require
#include "rect.h"
layout (location = 0) in flat uint texture_index;
layout (location = 1) in FragmentShaderInput inputs;
layout (location = 0) out vec4 color;
layout(set = 0, binding = 0) uniform sampler2D textures[];
void main()
{
vec2 texture_size = textureSize(textures[nonuniformEXT(texture_index)], 0);
vec2 uv = vec2(inputs.uv.x / texture_size.x, inputs.uv.y / texture_size.y);
vec4 sampled = texture(textures[nonuniformEXT(texture_index)], uv);
color = inputs.color * sampled;
}

View File

@ -1,5 +0,0 @@
struct FragmentShaderInput
{
vec4 color;
vec2 uv;
};

View File

@ -1,47 +0,0 @@
#version 450
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_debug_printf : require
#extension GL_GOOGLE_include_directive : require
#include "rect.h"
layout (location = 0) out uint texture_index;
layout (location = 1) out FragmentShaderInput outputs;
struct Vertex {
float x;
float y;
float uv_x;
float uv_y;
vec4 colors[4];
uint texture_index;
uint r[3];
};
layout(buffer_reference, std430) readonly buffer VertexBuffer{
Vertex vertices[];
};
//push constants block
layout(push_constant) uniform constants
{
VertexBuffer vertex_buffer;
float width;
float height;
} PushConstants;
void main()
{
Vertex v = PushConstants.vertex_buffer.vertices[gl_VertexIndex];
float width = PushConstants.width;
float height = PushConstants.height;
gl_Position = vec4(2 * v.x / width - 1, 2 * v.y / height - 1, 0, 1);
outputs.uv = vec2(v.uv_x, v.uv_y);
outputs.color = v.colors[gl_VertexIndex % 4];
texture_index = v.texture_index;
//debugPrintfEXT("Vertex index: (%u)\n", gl_VertexIndex);
//debugPrintfEXT("UV: (%f, %f)\n", v.uv_x, v.uv_y);
}

View File

@ -108,7 +108,7 @@ TextureAtlas font_texture_atlas_create(Arena* arena, Renderer* renderer, Texture
return result;
}
U32Vec2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atlas)
uint2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atlas)
{
auto height = atlas->ascent - atlas->descent;
u32 x_offset = 0;
@ -122,5 +122,5 @@ U32Vec2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atl
x_offset += character->advance + kerning;
}
return (U32Vec2) { .x = x_offset, .y = y_offset };
return (uint2) { x_offset, y_offset };
}

View File

@ -7,7 +7,6 @@
#include <stb_image.h>
#pragma clang diagnostic pop
EXPORT TextureMemory texture_load_from_file(Arena* arena, String path)
{
auto file = file_read(arena, path);

View File

@ -313,11 +313,15 @@ void buffer_copy_to_host(VulkanBuffer buffer, Slice(HostBufferCopy) regions)
auto region = regions.pointer[i];
auto* destination = buffer_pointer + region.destination_offset;
assert(destination + region.source.length <= (u8*)buffer.address + buffer.size);
#define USE_MEMCPY 1
#if USE_MEMCPY
memcpy(destination, region.source.pointer, region.source.length);
#else
for (u64 i = 0; i < region.source.length; i += 1)
{
destination[i] = region.source.pointer[i];
}
// memcpy(destination, region.source.pointer, region.source.length);
#endif
}
}
@ -1095,8 +1099,8 @@ Renderer* renderer_initialize(Arena* arena)
}
String shader_source_paths[] = {
strlit("bootstrap/shaders/rect.vert"),
strlit("bootstrap/shaders/rect.frag"),
strlit("bootstrap/std/shaders/rect.vert"),
strlit("bootstrap/std/shaders/rect.frag"),
};
PipelineLayoutCreate pipeline_layouts[] = {
@ -2201,38 +2205,53 @@ void window_pipeline_add_indices(RenderWindow* window, BBPipeline pipeline_index
void window_render_rect(RenderWindow* window, RectDraw draw)
{
auto p0 = draw.vertex.p0;
auto uv0 = draw.texture.p0;
if (draw.texture.p1.x != 0)
{
assert(draw.texture.p1.x - draw.texture.p0.x == draw.vertex.p1.x - draw.vertex.p0.x);
assert(draw.texture.p1.y - draw.texture.p0.y == draw.vertex.p1.y - draw.vertex.p0.y);
}
auto corner_radius = 10.0f;
auto extent = draw.vertex.p1 - p0;
RectVertex vertices[] = {
(RectVertex) {
.x = draw.vertex.x0,
.y = draw.vertex.y0,
.uv_x = draw.texture.x0,
.uv_y = draw.texture.y0,
.colors = draw.colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = draw.texture_index,
.colors = { draw.colors[0], draw.colors[1], draw.colors[2], draw.colors[3] },
.softness = 1.0,
.corner_radius = corner_radius,
},
(RectVertex) {
.x = draw.vertex.x1,
.y = draw.vertex.y0,
.uv_x = draw.texture.x1,
.uv_y = draw.texture.y0,
.colors = draw.colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = draw.texture_index,
.colors = { draw.colors[0], draw.colors[1], draw.colors[2], draw.colors[3] },
.softness = 1.0,
.corner_radius = corner_radius,
},
(RectVertex) {
.x = draw.vertex.x0,
.y = draw.vertex.y1,
.uv_x = draw.texture.x0,
.uv_y = draw.texture.y1,
.colors = draw.colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = draw.texture_index,
.colors = { draw.colors[0], draw.colors[1], draw.colors[2], draw.colors[3] },
.softness = 1.0,
.corner_radius = corner_radius,
},
(RectVertex) {
.x = draw.vertex.x1,
.y = draw.vertex.y1,
.uv_x = draw.texture.x1,
.uv_y = draw.texture.y1,
.colors = draw.colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = draw.texture_index,
.colors = { draw.colors[0], draw.colors[1], draw.colors[2], draw.colors[3] },
.softness = 1.0,
.corner_radius = corner_radius,
},
};
@ -2250,63 +2269,63 @@ void window_render_rect(RenderWindow* window, RectDraw draw)
window_pipeline_add_indices(window, BB_PIPELINE_RECT, (Slice(u32))array_to_slice(indices));
}
void window_render_text(Renderer* renderer, RenderWindow* window, String string, Color color, RenderFontType font_type, u32 x_offset, u32 y_offset)
// TODO: support gradient
void window_render_text(Renderer* renderer, RenderWindow* window, String string, float4 color, RenderFontType font_type, u32 x_offset, u32 y_offset)
{
auto* texture_atlas = &renderer->fonts[font_type];
auto height = texture_atlas->ascent - texture_atlas->descent;
auto texture_index = texture_atlas->texture.value;
// TODO: support gradient
RectColors colors = {
.v = { color, color, color, color }
};
for (u64 i = 0; i < string.length; i += 1)
{
auto ch = string.pointer[i];
auto* character = &texture_atlas->characters[ch];
auto pos_x = x_offset;
auto pos_y = y_offset + character->y_offset + height + texture_atlas->descent; // Offset of the height to render the character from the bottom (y + height) up (y)
//
auto uv_x = character->x;
auto uv_y = character->y;
auto uv_width = character->width;
auto uv_height = character->height;
auto char_width = character->width;
auto char_height = character->height;
auto pos_x = x_offset;
auto pos_y = y_offset + character->y_offset + height + texture_atlas->descent; // Offset of the height to render the character from the bottom (y + height) up (y)
vec2 p0 = { pos_x, pos_y };
vec2 uv0 = { uv_x, uv_y };
vec2 extent = { char_width, char_height };
// print("P0: ({u32}, {u32}). P1: ({u32}, {u32})\n", (u32)p0.x, (u32)p0.y, (u32)p1.x, (u32)p1.y);
RectVertex vertices[] = {
(RectVertex) {
.x = pos_x,
.y = pos_y,
.uv_x = (f32)uv_x,
.uv_y = (f32)uv_y,
.colors = colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = texture_index,
.colors = { color, color, color, color },
.softness = 1.0,
},
(RectVertex) {
.x = pos_x + character->width,
.y = pos_y,
.uv_x = (f32)(uv_x + uv_width),
.uv_y = (f32)uv_y,
.colors = colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = texture_index,
.colors = { color, color, color, color },
.softness = 1.0,
},
(RectVertex) {
.x = pos_x,
.y = pos_y + character->height,
.uv_x = (f32)uv_x,
.uv_y = (f32)(uv_y + uv_height),
.colors = colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.texture_index = texture_index,
.colors = { color, color, color, color },
.softness = 1.0,
},
(RectVertex) {
.x = pos_x + character->width,
.y = pos_y + character->height,
.uv_x = (f32)(uv_x + uv_width),
.uv_y = (f32)(uv_y + uv_height),
.colors = colors,
.p0 = p0,
.uv0 = uv0,
.extent = extent,
.colors = { color, color, color, color },
.texture_index = texture_index,
.softness = 1.0,
},
};
@ -2328,7 +2347,7 @@ void window_render_text(Renderer* renderer, RenderWindow* window, String string,
}
}
U32Vec2 renderer_font_compute_string_rect(Renderer* renderer, RenderFontType type, String string)
uint2 renderer_font_compute_string_rect(Renderer* renderer, RenderFontType type, String string)
{
auto* texture_atlas = &renderer->fonts[type];
auto result = texture_atlas_compute_string_rect(string, texture_atlas);

View File

@ -89,7 +89,6 @@ fn SpirVBinary compileShaderToSPIRV_Vulkan(Arena* arena, glslang_stage_t stage,
String compile_shader(Arena* arena, String path, ShaderStage shader_stage)
{
print("Compile shader\n");
#if SHADER_COMPILATION_USE_SOURCE
auto file = file_read(arena, path);

View File

@ -0,0 +1,35 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : require
#extension GL_EXT_debug_printf : require
#extension GL_GOOGLE_include_directive : require
#include "rect.inc"
layout (location = 0) in flat uint texture_index;
layout (location = 1) in RectFragmentShaderInput inputs;
layout (location = 0) out vec4 color;
layout(set = 0, binding = 0) uniform sampler2D textures[];
float rounded_rect_sdf(vec2 position, vec2 center, vec2 half_size, float radius)
{
vec2 d2 = abs(center - position) - half_size + vec2(radius, radius);
float result = min(max(d2.x, d2.y), 0.0) + length(max(d2, 0.0)) - radius;
return result;
}
void main()
{
uint sampler_index = nonuniformEXT(texture_index);
vec2 texture_size = textureSize(textures[sampler_index], 0);
vec2 uv = vec2(inputs.uv.x / texture_size.x, inputs.uv.y / texture_size.y);
vec4 sampled = texture(textures[sampler_index], uv);
float softness = inputs.softness;
float softness_padding_scalar = max(0, softness * 2 - 1);
vec2 softness_padding = vec2(softness_padding_scalar, softness_padding_scalar);
float distance = rounded_rect_sdf(inputs.position, inputs.center, inputs.half_size - softness_padding, inputs.corner_radius);
float sdf_factor = 1.0 - smoothstep(0, 2 * softness, distance);
color = inputs.color * sampled * sdf_factor;
}

View File

@ -0,0 +1,22 @@
struct RectVertex
{
vec2 p0;
vec2 uv0;
vec2 extent;
float corner_radius;
float softness;
vec4 colors[4];
uint texture_index;
uint reserved[3];
};
struct RectFragmentShaderInput
{
vec4 color;
vec2 uv;
vec2 position;
vec2 center;
vec2 half_size;
float corner_radius;
float softness;
};

View File

@ -0,0 +1,61 @@
#version 450
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_debug_printf : require
#extension GL_GOOGLE_include_directive : require
#include "rect.inc"
layout (location = 0) out uint texture_index;
layout (location = 1) out RectFragmentShaderInput outputs;
layout(buffer_reference, std430) readonly buffer VertexBuffer{
RectVertex vertices[];
};
layout(push_constant) uniform constants
{
VertexBuffer vertex_buffer;
float width;
float height;
} PushConstants;
const vec2 vertices[] = {
{ -1, -1 },
{ +1, -1 },
{ -1, +1 },
{ +1, +1 },
};
void main()
{
RectVertex v = PushConstants.vertex_buffer.vertices[gl_VertexIndex];
uint vertex_id = gl_VertexIndex % 4;
float width = PushConstants.width;
float height = PushConstants.height;
vec2 extent = v.extent;
vec2 p0 = v.p0;
vec2 p1 = p0 + extent;
vec2 position_center = (p1 + p0) / 2;
vec2 half_size = (p1 - p0) / 2;
vec2 position = vertices[vertex_id] * half_size + position_center;
//debugPrintfEXT("Vertex index: (%u). P0: (%f, %f). P1: (%f, %f). Center: (%f, %f). Half size: (%f, %f). Position: (%f, %f)\n", gl_VertexIndex, p0.x, p0.y, p1.x, p1.y, center.x, center.y, half_size.x, half_size.y, position.x, position.y);
gl_Position = vec4(2 * position.x / width - 1, 2 * position.y / height - 1, 0, 1);
vec2 uv0 = v.uv0;
vec2 uv1 = uv0 + extent;
vec2 texture_center = (uv1 + uv0) / 2;
vec2 uv = vertices[vertex_id] * half_size + texture_center;
texture_index = v.texture_index;
outputs.color = v.colors[vertex_id];
outputs.uv = uv;
outputs.position = position;
outputs.center = position_center;
outputs.half_size = half_size;
outputs.corner_radius = v.corner_radius;
outputs.softness = v.softness;
}

View File

@ -248,8 +248,8 @@ UI_Widget* ui_widget_make_from_key(UI_WidgetFlags flags, UI_Key key)
auto color = count % 3 == 0;
widget->key = key;
widget->background_color = Color4(color, color, color, 1);
widget->text_color = Color4(!color, !color, !color, 1);
widget->background_color = (float4) { color, color, color, 1 };
widget->text_color = (float4) { !color, !color, !color, 1 };
widget->flags = flags;
widget->first = 0;
widget->last = 0;
@ -462,8 +462,8 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue)
ui_push(parent, root);
ui_push(font_size, 12);
ui_push(text_color, Color4(1, 1, 1, 1));
ui_push(background_color, Color4(0, 0, 0, 1));
ui_push(text_color, ((float4) { 1, 1, 1, 1 }));
ui_push(background_color, ((float4) { 0, 0, 0, 1 }));
ui_push(pref_width, ui_percentage(1.0, 0.0));
ui_push(pref_height, ui_percentage(1.0, 0.0));
// ui_push(pref_height, ui_em(1.8, 0.0));
@ -482,7 +482,7 @@ fn void ui_compute_independent_sizes(UI_Widget* widget)
default: break; case UI_SIZE_COUNT: unreachable();
case UI_SIZE_PIXEL_COUNT:
{
widget->computed_size.v[axis] = floorf(widget->pref_size[axis].value);
widget->computed_size[axis] = floorf(widget->pref_size[axis].value);
} break;
}
}
@ -508,7 +508,7 @@ fn void ui_compute_upward_dependent_sizes(UI_Widget* widget)
{
if (ancestor->pref_size[axis].kind != UI_SIZE_BY_CHILDREN)
{
widget->computed_size.v[axis] = floorf(ancestor->computed_size.v[axis] * widget->pref_size[axis].value);
widget->computed_size[axis] = floorf(ancestor->computed_size[axis] * widget->pref_size[axis].value);
break;
}
}
@ -547,7 +547,7 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
{
for (Axis2 axis = 0; axis < AXIS2_COUNT; axis += 1)
{
auto available_space = widget->computed_size.v[axis];
auto available_space = widget->computed_size[axis];
f32 taken_space = 0;
f32 total_fixup_budget = 0;
@ -559,13 +559,13 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
{
if (axis == widget->child_layout_axis)
{
taken_space += child_widget->computed_size.v[axis];
taken_space += child_widget->computed_size[axis];
}
else
{
taken_space = MAX(taken_space, child_widget->computed_size.v[axis]);
taken_space = MAX(taken_space, child_widget->computed_size[axis]);
}
auto fixup_budget_this_child = child_widget->computed_size.v[axis] * (1 - child_widget->pref_size[axis].strictness);
auto fixup_budget_this_child = child_widget->computed_size[axis] * (1 - child_widget->pref_size[axis].strictness);
total_fixup_budget += fixup_budget_this_child;
}
}
@ -578,7 +578,7 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
{
if (!(child_widget->flags.v & (UI_WIDGET_FLAG_FLOATING_X << axis)))
{
auto fixup_budget_this_child = child_widget->computed_size.v[axis] * (1 - child_widget->pref_size[axis].strictness);
auto fixup_budget_this_child = child_widget->computed_size[axis] * (1 - child_widget->pref_size[axis].strictness);
f32 fixup_size_this_child = 0;
if (axis == widget->child_layout_axis)
@ -587,11 +587,11 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
}
else
{
fixup_size_this_child = child_widget->computed_size.v[axis] - available_space;
fixup_size_this_child = child_widget->computed_size[axis] - available_space;
}
fixup_size_this_child = CLAMP(0, fixup_size_this_child, fixup_budget_this_child);
child_widget->computed_size.v[axis] = floorf(child_widget->computed_size.v[axis] - fixup_size_this_child);
child_widget->computed_size[axis] = floorf(child_widget->computed_size[axis] - fixup_size_this_child);
}
}
}
@ -605,8 +605,8 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
{
if (!(child_widget->flags.v & (UI_WIDGET_FLAG_FLOATING_X << axis)))
{
child_widget->computed_relative_position.v[axis] = p;
p += child_widget->computed_size.v[axis];
child_widget->computed_relative_position[axis] = p;
p += child_widget->computed_size[axis];
}
}
}
@ -616,7 +616,7 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
{
if (!(child_widget->flags.v & (UI_WIDGET_FLAG_FLOATING_X << axis)))
{
child_widget->computed_relative_position.v[axis] = 0;
child_widget->computed_relative_position[axis] = 0;
}
}
}
@ -624,26 +624,26 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
for (UI_Widget* child_widget = widget->first; child_widget; child_widget = child_widget->next)
{
auto last_relative_rect = child_widget->relative_rect;
child_widget->relative_rect.p0.v[axis] = child_widget->computed_relative_position.v[axis];
child_widget->relative_rect.p1.v[axis] = child_widget->relative_rect.p0.v[axis] + child_widget->computed_size.v[axis];
child_widget->relative_rect.p0[axis] = child_widget->computed_relative_position[axis];
child_widget->relative_rect.p1[axis] = child_widget->relative_rect.p0[axis] + child_widget->computed_size[axis];
F32Vec2 last_corner_01 = { .x = last_relative_rect.x0, .y = last_relative_rect.y1 };
F32Vec2 last_corner_10 = { .x = last_relative_rect.x1, .y = last_relative_rect.y0 };
F32Vec2 this_corner_01 = { .x = child_widget->relative_rect.x0, .y = child_widget->relative_rect.y1 };
F32Vec2 this_corner_10 = { .x = child_widget->relative_rect.x1, .y = child_widget->relative_rect.y0 };
float2 last_corner_01 = { last_relative_rect.x0, last_relative_rect.y1 };
float2 last_corner_10 = { last_relative_rect.x1, last_relative_rect.y0 };
float2 this_corner_01 = { child_widget->relative_rect.x0, child_widget->relative_rect.y1 };
float2 this_corner_10 = { child_widget->relative_rect.x1, child_widget->relative_rect.y0 };
child_widget->relative_corner_delta[CORNER_00].v[axis] = child_widget->relative_rect.p0.v[axis] - last_relative_rect.p0.v[axis];
child_widget->relative_corner_delta[CORNER_01].v[axis] = this_corner_01.v[axis] - last_corner_01.v[axis];
child_widget->relative_corner_delta[CORNER_10].v[axis] = this_corner_10.v[axis] - last_corner_10.v[axis];
child_widget->relative_corner_delta[CORNER_11].v[axis] = child_widget->relative_rect.p1.v[axis] - last_relative_rect.p1.v[axis];
child_widget->relative_corner_delta[CORNER_00][axis] = child_widget->relative_rect.p0[axis] - last_relative_rect.p0[axis];
child_widget->relative_corner_delta[CORNER_01][axis] = this_corner_01[axis] - last_corner_01[axis];
child_widget->relative_corner_delta[CORNER_10][axis] = this_corner_10[axis] - last_corner_10[axis];
child_widget->relative_corner_delta[CORNER_11][axis] = child_widget->relative_rect.p1[axis] - last_relative_rect.p1[axis];
child_widget->rect.p0.v[axis] = widget->rect.p0.v[axis] + child_widget->relative_rect.p0.v[axis] - widget->view_offset.v[axis];
child_widget->rect.p1.v[axis] = child_widget->rect.p0.v[axis] + child_widget->computed_size.v[axis];
child_widget->rect.p0[axis] = widget->rect.p0[axis] + child_widget->relative_rect.p0[axis] - widget->view_offset[axis];
child_widget->rect.p1[axis] = child_widget->rect.p0[axis] + child_widget->computed_size[axis];
if (!(child_widget->flags.v & (UI_WIDGET_FLAG_FLOATING_X << axis)))
{
child_widget->rect.p0.v[axis] = floorf(child_widget->rect.p0.v[axis]);
child_widget->rect.p1.v[axis] = floorf(child_widget->rect.p1.v[axis]);
child_widget->rect.p0[axis] = floorf(child_widget->rect.p0[axis]);
child_widget->rect.p1[axis] = floorf(child_widget->rect.p1[axis]);
}
}
@ -674,16 +674,6 @@ void ui_build_end()
ui_resolve_conflicts(ui_state->root);
}
fn RenderRect render_rect(F32Interval2 rect)
{
return (RenderRect) {
.x0 = rect.x0,
.y0 = rect.y0,
.x1 = rect.x1,
.y1 = rect.y1,
};
}
STRUCT(WidgetIterator)
{
UI_Widget* next;
@ -734,8 +724,8 @@ void ui_draw()
if (widget->flags.draw_background)
{
window_render_rect(window, (RectDraw) {
.colors = (RectColors) { .v = { Color4(1, 1, 1, 1), Color4(1, 1, 1, 1), widget->background_color, widget->background_color } },
.vertex = render_rect(widget->rect),
.colors = { (float4) {1, 1, 1, 1 }, (float4) {1, 1, 1, 1}, widget->background_color, widget->background_color },
.vertex = widget->rect,
});
}

View File

@ -105,6 +105,7 @@ cmake . \
$CXX_COMPILER_OPT_ARG \
$ASM_COMPILER_OPT_ARG
export VK_LAYER_PRINTF_BUFFER_SIZE=1000000
cd $BUILD_DIR
ninja -v
cd $ORIGINAL_DIR/build