Primitive border drawing and rounded corners
This commit is contained in:
		
							parent
							
								
									b063d570b1
								
							
						
					
					
						commit
						9dec588ec1
					
				@ -56,43 +56,28 @@ typedef enum Corner
 | 
				
			|||||||
    CORNER_COUNT,
 | 
					    CORNER_COUNT,
 | 
				
			||||||
} Corner;
 | 
					} Corner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRUCT(U32Vec2)
 | 
					typedef float float2 __attribute__((ext_vector_type(2)));
 | 
				
			||||||
{
 | 
					typedef float float3 __attribute__((ext_vector_type(3)));
 | 
				
			||||||
    struct
 | 
					typedef float float4 __attribute__((ext_vector_type(4)));
 | 
				
			||||||
    {
 | 
					typedef float2 vec2;
 | 
				
			||||||
        u32 x;
 | 
					typedef float3 vec3;
 | 
				
			||||||
        u32 y;
 | 
					typedef float4 vec4;
 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    u32 v[2];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRUCT(F32Vec4)
 | 
					typedef u32 uint2 __attribute__((ext_vector_type(2)));
 | 
				
			||||||
{
 | 
					typedef u32 uint3 __attribute__((ext_vector_type(3)));
 | 
				
			||||||
    f32 v[4];
 | 
					typedef u32 uint4 __attribute__((ext_vector_type(4)));
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef F32Vec4 Color;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
UNION(F32Vec2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        f32 x;
 | 
					 | 
				
			||||||
        f32 y;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    f32 v[2];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
UNION(F32Interval2)
 | 
					UNION(F32Interval2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct
 | 
					    struct
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        F32Vec2 min;
 | 
					        float2 min;
 | 
				
			||||||
        F32Vec2 max;
 | 
					        float2 max;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    struct
 | 
					    struct
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        F32Vec2 p0;
 | 
					        float2 p0;
 | 
				
			||||||
        F32Vec2 p1;
 | 
					        float2 p1;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    struct
 | 
					    struct
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -101,9 +86,11 @@ UNION(F32Interval2)
 | 
				
			|||||||
        f32 x1;
 | 
					        f32 x1;
 | 
				
			||||||
        f32 y1;
 | 
					        f32 y1;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    F32Vec2 v[2];
 | 
					    float2 v[2];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static_assert(sizeof(F32Interval2) == 4 * sizeof(f32));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum Axis2
 | 
					typedef enum Axis2
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AXIS2_X,
 | 
					    AXIS2_X,
 | 
				
			||||||
 | 
				
			|||||||
@ -37,4 +37,4 @@ STRUCT(TextureAtlasCreate)
 | 
				
			|||||||
#include <std/render.h>
 | 
					#include <std/render.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPORT TextureAtlas font_texture_atlas_create(Arena* arena, Renderer* renderer, TextureAtlasCreate create);
 | 
					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);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <std/base.h>
 | 
					#include <std/base.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Renderer Renderer;
 | 
					typedef struct Renderer Renderer;
 | 
				
			||||||
@ -11,41 +10,18 @@ typedef struct Renderer Renderer;
 | 
				
			|||||||
typedef struct RenderWindow RenderWindow;
 | 
					typedef struct RenderWindow RenderWindow;
 | 
				
			||||||
typedef struct Pipeline Pipeline;
 | 
					typedef struct Pipeline Pipeline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRUCT(RenderRect)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    u32 x0;
 | 
					 | 
				
			||||||
    u32 y0;
 | 
					 | 
				
			||||||
    u32 x1;
 | 
					 | 
				
			||||||
    u32 y1;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STRUCT(RectColors)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    F32Vec4 v[4];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STRUCT(RectDraw)
 | 
					STRUCT(RectDraw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RenderRect vertex;
 | 
					    F32Interval2 vertex;
 | 
				
			||||||
    RenderRect texture;
 | 
					    F32Interval2 texture;
 | 
				
			||||||
    RectColors colors;
 | 
					    vec4 colors[4];
 | 
				
			||||||
    u32 texture_index;
 | 
					    u32 texture_index;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRUCT(RectVertex)
 | 
					#include "../std/shaders/rect.inc"
 | 
				
			||||||
{
 | 
					typedef struct RectVertex RectVertex;
 | 
				
			||||||
    f32 x;
 | 
					 | 
				
			||||||
    f32 y;
 | 
					 | 
				
			||||||
    f32 uv_x;
 | 
					 | 
				
			||||||
    f32 uv_y;
 | 
					 | 
				
			||||||
    RectColors colors;
 | 
					 | 
				
			||||||
    u32 texture_index;
 | 
					 | 
				
			||||||
    u32 reserved[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
decl_vb(RectVertex);
 | 
					decl_vb(RectVertex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define Color4(r, g, b, a) ((F32Vec4){ .v = { r, g, b, a } })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum BBPipeline
 | 
					typedef enum BBPipeline
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    BB_PIPELINE_RECT,
 | 
					    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_begin(Renderer* renderer, RenderWindow* window);
 | 
				
			||||||
EXPORT void renderer_window_frame_end(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 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_begin(RenderWindow* window);
 | 
				
			||||||
EXPORT void window_command_end(RenderWindow* window);
 | 
					EXPORT void window_command_end(RenderWindow* window);
 | 
				
			||||||
EXPORT void window_render_begin(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 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_pipeline_add_indices(RenderWindow* window, BBPipeline pipeline_index, Slice(u32) indices);
 | 
				
			||||||
EXPORT void window_render_rect(RenderWindow* window, RectDraw draw);
 | 
					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);
 | 
				
			||||||
 | 
				
			|||||||
@ -87,19 +87,19 @@ STRUCT(UI_Widget)
 | 
				
			|||||||
    UI_WidgetFlags flags;
 | 
					    UI_WidgetFlags flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Data known after size determination happens
 | 
					    // Data known after size determination happens
 | 
				
			||||||
    F32Vec2 computed_size;
 | 
					    float2 computed_size;
 | 
				
			||||||
    F32Vec2 computed_relative_position;
 | 
					    float2 computed_relative_position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Data known after layout computation happens
 | 
					    // Data known after layout computation happens
 | 
				
			||||||
    F32Interval2 relative_rect;
 | 
					    F32Interval2 relative_rect;
 | 
				
			||||||
    F32Interval2 rect;
 | 
					    F32Interval2 rect;
 | 
				
			||||||
    F32Vec2 relative_corner_delta[CORNER_COUNT];
 | 
					    float2 relative_corner_delta[CORNER_COUNT];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Persistent data across frames
 | 
					    // Persistent data across frames
 | 
				
			||||||
    u64 last_build_touched;
 | 
					    u64 last_build_touched;
 | 
				
			||||||
    F32Vec2 view_offset;
 | 
					    float2 view_offset;
 | 
				
			||||||
    Color background_color;
 | 
					    float4 background_color;
 | 
				
			||||||
    Color text_color;
 | 
					    float4 text_color;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
decl_vbp(UI_Widget);
 | 
					decl_vbp(UI_Widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +111,7 @@ STRUCT(UI_WidgetSlot)
 | 
				
			|||||||
declare_slice(UI_WidgetSlot);
 | 
					declare_slice(UI_WidgetSlot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
decl_vb(Axis2);
 | 
					decl_vb(Axis2);
 | 
				
			||||||
decl_vb(Color);
 | 
					decl_vb(float4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRUCT(UI_StateStackAutoPops)
 | 
					STRUCT(UI_StateStackAutoPops)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -131,8 +131,8 @@ STRUCT(UI_StateStackNulls)
 | 
				
			|||||||
    UI_Size pref_width;
 | 
					    UI_Size pref_width;
 | 
				
			||||||
    UI_Size pref_height;
 | 
					    UI_Size pref_height;
 | 
				
			||||||
    Axis2 child_layout_axis;
 | 
					    Axis2 child_layout_axis;
 | 
				
			||||||
    Color text_color;
 | 
					    float4 text_color;
 | 
				
			||||||
    Color background_color;
 | 
					    float4 background_color;
 | 
				
			||||||
    f32 font_size;
 | 
					    f32 font_size;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -142,8 +142,8 @@ STRUCT(UI_StateStacks)
 | 
				
			|||||||
    VirtualBuffer(UI_Size) pref_width;
 | 
					    VirtualBuffer(UI_Size) pref_width;
 | 
				
			||||||
    VirtualBuffer(UI_Size) pref_height;
 | 
					    VirtualBuffer(UI_Size) pref_height;
 | 
				
			||||||
    VirtualBuffer(Axis2) child_layout_axis;
 | 
					    VirtualBuffer(Axis2) child_layout_axis;
 | 
				
			||||||
    VirtualBuffer(Color) text_color;
 | 
					    VirtualBuffer(float4) text_color;
 | 
				
			||||||
    VirtualBuffer(Color) background_color;
 | 
					    VirtualBuffer(float4) background_color;
 | 
				
			||||||
    VirtualBuffer(f32) font_size;
 | 
					    VirtualBuffer(f32) font_size;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
struct FragmentShaderInput
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    vec4 color;
 | 
					 | 
				
			||||||
    vec2 uv;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -108,7 +108,7 @@ TextureAtlas font_texture_atlas_create(Arena* arena, Renderer* renderer, Texture
 | 
				
			|||||||
    return result;
 | 
					    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;
 | 
					    auto height = atlas->ascent - atlas->descent;
 | 
				
			||||||
    u32 x_offset = 0;
 | 
					    u32 x_offset = 0;
 | 
				
			||||||
@ -122,5 +122,5 @@ U32Vec2 texture_atlas_compute_string_rect(String string, const TextureAtlas* atl
 | 
				
			|||||||
        x_offset += character->advance + kerning;
 | 
					        x_offset += character->advance + kerning;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (U32Vec2) { .x = x_offset, .y = y_offset };
 | 
					    return (uint2) { x_offset, y_offset };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,6 @@
 | 
				
			|||||||
#include <stb_image.h>
 | 
					#include <stb_image.h>
 | 
				
			||||||
#pragma clang diagnostic pop
 | 
					#pragma clang diagnostic pop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
EXPORT TextureMemory texture_load_from_file(Arena* arena, String path)
 | 
					EXPORT TextureMemory texture_load_from_file(Arena* arena, String path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto file = file_read(arena, path);
 | 
					    auto file = file_read(arena, path);
 | 
				
			||||||
 | 
				
			|||||||
@ -313,11 +313,15 @@ void buffer_copy_to_host(VulkanBuffer buffer, Slice(HostBufferCopy) regions)
 | 
				
			|||||||
        auto region = regions.pointer[i];
 | 
					        auto region = regions.pointer[i];
 | 
				
			||||||
        auto* destination = buffer_pointer + region.destination_offset;
 | 
					        auto* destination = buffer_pointer + region.destination_offset;
 | 
				
			||||||
        assert(destination + region.source.length <= (u8*)buffer.address + buffer.size);
 | 
					        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)
 | 
					        for (u64 i = 0; i < region.source.length; i += 1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            destination[i] = region.source.pointer[i];
 | 
					            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[] = {
 | 
					    String shader_source_paths[] = {
 | 
				
			||||||
        strlit("bootstrap/shaders/rect.vert"),
 | 
					        strlit("bootstrap/std/shaders/rect.vert"),
 | 
				
			||||||
        strlit("bootstrap/shaders/rect.frag"),
 | 
					        strlit("bootstrap/std/shaders/rect.frag"),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PipelineLayoutCreate pipeline_layouts[] = {
 | 
					    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)
 | 
					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 vertices[] = {
 | 
				
			||||||
        (RectVertex) {
 | 
					        (RectVertex) {
 | 
				
			||||||
            .x = draw.vertex.x0,
 | 
					            .p0 = p0,
 | 
				
			||||||
            .y = draw.vertex.y0,
 | 
					            .uv0 = uv0,
 | 
				
			||||||
            .uv_x = draw.texture.x0,
 | 
					            .extent = extent,
 | 
				
			||||||
            .uv_y = draw.texture.y0,
 | 
					 | 
				
			||||||
            .colors = draw.colors,
 | 
					 | 
				
			||||||
            .texture_index = draw.texture_index,
 | 
					            .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) {
 | 
					        (RectVertex) {
 | 
				
			||||||
            .x = draw.vertex.x1,
 | 
					            .p0 = p0,
 | 
				
			||||||
            .y = draw.vertex.y0,
 | 
					            .uv0 = uv0,
 | 
				
			||||||
            .uv_x = draw.texture.x1,
 | 
					            .extent = extent,
 | 
				
			||||||
            .uv_y = draw.texture.y0,
 | 
					 | 
				
			||||||
            .colors = draw.colors,
 | 
					 | 
				
			||||||
            .texture_index = draw.texture_index,
 | 
					            .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) {
 | 
					        (RectVertex) {
 | 
				
			||||||
            .x = draw.vertex.x0,
 | 
					            .p0 = p0,
 | 
				
			||||||
            .y = draw.vertex.y1,
 | 
					            .uv0 = uv0,
 | 
				
			||||||
            .uv_x = draw.texture.x0,
 | 
					            .extent = extent,
 | 
				
			||||||
            .uv_y = draw.texture.y1,
 | 
					 | 
				
			||||||
            .colors = draw.colors,
 | 
					 | 
				
			||||||
            .texture_index = draw.texture_index,
 | 
					            .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) {
 | 
					        (RectVertex) {
 | 
				
			||||||
            .x = draw.vertex.x1,
 | 
					            .p0 = p0,
 | 
				
			||||||
            .y = draw.vertex.y1,
 | 
					            .uv0 = uv0,
 | 
				
			||||||
            .uv_x = draw.texture.x1,
 | 
					            .extent = extent,
 | 
				
			||||||
            .uv_y = draw.texture.y1,
 | 
					 | 
				
			||||||
            .colors = draw.colors,
 | 
					 | 
				
			||||||
            .texture_index = draw.texture_index,
 | 
					            .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));
 | 
					    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* texture_atlas = &renderer->fonts[font_type];
 | 
				
			||||||
    auto height = texture_atlas->ascent - texture_atlas->descent;
 | 
					    auto height = texture_atlas->ascent - texture_atlas->descent;
 | 
				
			||||||
    auto texture_index = texture_atlas->texture.value;
 | 
					    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)
 | 
					    for (u64 i = 0; i < string.length; i += 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto ch = string.pointer[i];
 | 
					        auto ch = string.pointer[i];
 | 
				
			||||||
        auto* character = &texture_atlas->characters[ch];
 | 
					        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_x = character->x;
 | 
				
			||||||
        auto uv_y = character->y;
 | 
					        auto uv_y = character->y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto uv_width = character->width;
 | 
					        auto char_width = character->width;
 | 
				
			||||||
        auto uv_height = character->height;
 | 
					        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 vertices[] = {
 | 
				
			||||||
            (RectVertex) {
 | 
					            (RectVertex) {
 | 
				
			||||||
                .x = pos_x,
 | 
					                .p0 = p0,
 | 
				
			||||||
                .y = pos_y,
 | 
					                .uv0 = uv0,
 | 
				
			||||||
                .uv_x = (f32)uv_x,
 | 
					                .extent = extent,
 | 
				
			||||||
                .uv_y = (f32)uv_y,
 | 
					 | 
				
			||||||
                .colors = colors,
 | 
					 | 
				
			||||||
                .texture_index = texture_index,
 | 
					                .texture_index = texture_index,
 | 
				
			||||||
 | 
					                .colors = { color, color, color, color },
 | 
				
			||||||
 | 
					                .softness = 1.0,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            (RectVertex) {
 | 
					            (RectVertex) {
 | 
				
			||||||
                .x = pos_x + character->width,
 | 
					                .p0 = p0,
 | 
				
			||||||
                .y = pos_y,
 | 
					                .uv0 = uv0,
 | 
				
			||||||
                .uv_x = (f32)(uv_x + uv_width),
 | 
					                .extent = extent,
 | 
				
			||||||
                .uv_y = (f32)uv_y,
 | 
					 | 
				
			||||||
                .colors = colors,
 | 
					 | 
				
			||||||
                .texture_index = texture_index,
 | 
					                .texture_index = texture_index,
 | 
				
			||||||
 | 
					                .colors = { color, color, color, color },
 | 
				
			||||||
 | 
					                .softness = 1.0,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            (RectVertex) {
 | 
					            (RectVertex) {
 | 
				
			||||||
                .x = pos_x,
 | 
					                .p0 = p0,
 | 
				
			||||||
                .y = pos_y + character->height,
 | 
					                .uv0 = uv0,
 | 
				
			||||||
                .uv_x = (f32)uv_x,
 | 
					                .extent = extent,
 | 
				
			||||||
                .uv_y = (f32)(uv_y + uv_height),
 | 
					 | 
				
			||||||
                .colors = colors,
 | 
					 | 
				
			||||||
                .texture_index = texture_index,
 | 
					                .texture_index = texture_index,
 | 
				
			||||||
 | 
					                .colors = { color, color, color, color },
 | 
				
			||||||
 | 
					                .softness = 1.0,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            (RectVertex) {
 | 
					            (RectVertex) {
 | 
				
			||||||
                .x = pos_x + character->width,
 | 
					                .p0 = p0,
 | 
				
			||||||
                .y = pos_y + character->height,
 | 
					                .uv0 = uv0,
 | 
				
			||||||
                .uv_x = (f32)(uv_x + uv_width),
 | 
					                .extent = extent,
 | 
				
			||||||
                .uv_y = (f32)(uv_y + uv_height),
 | 
					                .colors = { color, color, color, color },
 | 
				
			||||||
                .colors = colors,
 | 
					 | 
				
			||||||
                .texture_index = texture_index,
 | 
					                .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* texture_atlas = &renderer->fonts[type];
 | 
				
			||||||
    auto result = texture_atlas_compute_string_rect(string, texture_atlas);
 | 
					    auto result = texture_atlas_compute_string_rect(string, texture_atlas);
 | 
				
			||||||
 | 
				
			|||||||
@ -89,7 +89,6 @@ fn SpirVBinary compileShaderToSPIRV_Vulkan(Arena* arena, glslang_stage_t stage,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
String compile_shader(Arena* arena, String path, ShaderStage shader_stage)
 | 
					String compile_shader(Arena* arena, String path, ShaderStage shader_stage)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    print("Compile shader\n");
 | 
					 | 
				
			||||||
#if SHADER_COMPILATION_USE_SOURCE
 | 
					#if SHADER_COMPILATION_USE_SOURCE
 | 
				
			||||||
    auto file = file_read(arena, path);
 | 
					    auto file = file_read(arena, path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								bootstrap/std/shaders/rect.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								bootstrap/std/shaders/rect.frag
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								bootstrap/std/shaders/rect.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								bootstrap/std/shaders/rect.inc
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										61
									
								
								bootstrap/std/shaders/rect.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								bootstrap/std/shaders/rect.vert
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -248,8 +248,8 @@ UI_Widget* ui_widget_make_from_key(UI_WidgetFlags flags, UI_Key key)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    auto color = count % 3 == 0;
 | 
					    auto color = count % 3 == 0;
 | 
				
			||||||
    widget->key = key;
 | 
					    widget->key = key;
 | 
				
			||||||
    widget->background_color = Color4(color, color, color, 1);
 | 
					    widget->background_color = (float4) { color, color, color, 1 };
 | 
				
			||||||
    widget->text_color = Color4(!color, !color, !color, 1);
 | 
					    widget->text_color = (float4) { !color, !color, !color, 1 };
 | 
				
			||||||
    widget->flags = flags;
 | 
					    widget->flags = flags;
 | 
				
			||||||
    widget->first = 0;
 | 
					    widget->first = 0;
 | 
				
			||||||
    widget->last = 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(parent, root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ui_push(font_size, 12);
 | 
					        ui_push(font_size, 12);
 | 
				
			||||||
        ui_push(text_color, Color4(1, 1, 1, 1));
 | 
					        ui_push(text_color, ((float4) { 1, 1, 1, 1 }));
 | 
				
			||||||
        ui_push(background_color, Color4(0, 0, 0, 1));
 | 
					        ui_push(background_color, ((float4) { 0, 0, 0, 1 }));
 | 
				
			||||||
        ui_push(pref_width, ui_percentage(1.0, 0.0));
 | 
					        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_percentage(1.0, 0.0));
 | 
				
			||||||
        // ui_push(pref_height, ui_em(1.8, 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();
 | 
					            default: break; case UI_SIZE_COUNT: unreachable();
 | 
				
			||||||
            case UI_SIZE_PIXEL_COUNT:
 | 
					            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;
 | 
					                } 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)
 | 
					                    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;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -547,7 +547,7 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    for (Axis2 axis = 0; axis < AXIS2_COUNT; axis += 1)
 | 
					    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 taken_space = 0;
 | 
				
			||||||
        f32 total_fixup_budget = 0;
 | 
					        f32 total_fixup_budget = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -559,13 +559,13 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (axis == widget->child_layout_axis)
 | 
					                    if (axis == widget->child_layout_axis)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        taken_space += child_widget->computed_size.v[axis];
 | 
					                        taken_space += child_widget->computed_size[axis];
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    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;
 | 
					                    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)))
 | 
					                    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;
 | 
					                        f32 fixup_size_this_child = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if (axis == widget->child_layout_axis)
 | 
					                        if (axis == widget->child_layout_axis)
 | 
				
			||||||
@ -587,11 +587,11 @@ fn void ui_resolve_conflicts(UI_Widget* widget)
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else
 | 
					                        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);
 | 
					                        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)))
 | 
					                if (!(child_widget->flags.v & (UI_WIDGET_FLAG_FLOATING_X << axis)))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    child_widget->computed_relative_position.v[axis] = p;
 | 
					                    child_widget->computed_relative_position[axis] = p;
 | 
				
			||||||
                    p += child_widget->computed_size.v[axis];
 | 
					                    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)))
 | 
					                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)
 | 
					        for (UI_Widget* child_widget = widget->first; child_widget; child_widget = child_widget->next)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            auto last_relative_rect = child_widget->relative_rect;
 | 
					            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.p0[axis] = child_widget->computed_relative_position[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.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 };
 | 
					            float2 last_corner_01 = { last_relative_rect.x0, last_relative_rect.y1 };
 | 
				
			||||||
            F32Vec2 last_corner_10 = { .x = last_relative_rect.x1, .y = last_relative_rect.y0 };
 | 
					            float2 last_corner_10 = { last_relative_rect.x1, last_relative_rect.y0 };
 | 
				
			||||||
            F32Vec2 this_corner_01 = { .x = child_widget->relative_rect.x0, .y = child_widget->relative_rect.y1 };
 | 
					            float2 this_corner_01 = { child_widget->relative_rect.x0, child_widget->relative_rect.y1 };
 | 
				
			||||||
            F32Vec2 this_corner_10 = { .x = child_widget->relative_rect.x1, .y = child_widget->relative_rect.y0 };
 | 
					            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_00][axis] = child_widget->relative_rect.p0[axis] - last_relative_rect.p0[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_01][axis] = this_corner_01[axis] - last_corner_01[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_10][axis] = this_corner_10[axis] - last_corner_10[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_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.p0[axis] = widget->rect.p0[axis] + child_widget->relative_rect.p0[axis] - widget->view_offset[axis];
 | 
				
			||||||
            child_widget->rect.p1.v[axis] = child_widget->rect.p0.v[axis] + child_widget->computed_size.v[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)))
 | 
					            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.p0[axis] = floorf(child_widget->rect.p0[axis]);
 | 
				
			||||||
                child_widget->rect.p1.v[axis] = floorf(child_widget->rect.p1.v[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);
 | 
					    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)
 | 
					STRUCT(WidgetIterator)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    UI_Widget* next;
 | 
					    UI_Widget* next;
 | 
				
			||||||
@ -734,8 +724,8 @@ void ui_draw()
 | 
				
			|||||||
        if (widget->flags.draw_background)
 | 
					        if (widget->flags.draw_background)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            window_render_rect(window, (RectDraw) {
 | 
					            window_render_rect(window, (RectDraw) {
 | 
				
			||||||
                .colors = (RectColors) { .v = { Color4(1, 1, 1, 1), Color4(1, 1, 1, 1), widget->background_color, widget->background_color } },
 | 
					                .colors = { (float4) {1, 1, 1, 1 }, (float4) {1, 1, 1, 1}, widget->background_color, widget->background_color },
 | 
				
			||||||
                .vertex = render_rect(widget->rect),
 | 
					                .vertex = widget->rect,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -105,6 +105,7 @@ cmake . \
 | 
				
			|||||||
    $CXX_COMPILER_OPT_ARG \
 | 
					    $CXX_COMPILER_OPT_ARG \
 | 
				
			||||||
    $ASM_COMPILER_OPT_ARG
 | 
					    $ASM_COMPILER_OPT_ARG
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					export VK_LAYER_PRINTF_BUFFER_SIZE=1000000
 | 
				
			||||||
cd $BUILD_DIR
 | 
					cd $BUILD_DIR
 | 
				
			||||||
ninja -v
 | 
					ninja -v
 | 
				
			||||||
cd $ORIGINAL_DIR/build
 | 
					cd $ORIGINAL_DIR/build
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user