add proper tab implementation
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "renderer/renderer.h"
|
||||
#include "ui/ui_core.h"
|
||||
#include "ui/ui_theme.h"
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_5.h>
|
||||
@@ -41,7 +42,7 @@ struct UIVertex {
|
||||
float col[4];
|
||||
float rect_min[2];
|
||||
float rect_max[2];
|
||||
float corner_radius;
|
||||
float corner_radii[4]; // TL, TR, BR, BL
|
||||
float border_thickness;
|
||||
float softness;
|
||||
float mode; // 0 = rect SDF, 1 = textured
|
||||
@@ -66,7 +67,7 @@ struct VSInput {
|
||||
float4 col : COLOR0;
|
||||
float2 rect_min : TEXCOORD1;
|
||||
float2 rect_max : TEXCOORD2;
|
||||
float corner_radius : TEXCOORD3;
|
||||
float4 corner_radii : TEXCOORD3;
|
||||
float border_thickness : TEXCOORD4;
|
||||
float softness : TEXCOORD5;
|
||||
float mode : TEXCOORD6;
|
||||
@@ -78,7 +79,7 @@ struct PSInput {
|
||||
float4 col : COLOR0;
|
||||
float2 rect_min : TEXCOORD1;
|
||||
float2 rect_max : TEXCOORD2;
|
||||
float corner_radius : TEXCOORD3;
|
||||
float4 corner_radii : TEXCOORD3;
|
||||
float border_thickness : TEXCOORD4;
|
||||
float softness : TEXCOORD5;
|
||||
float mode : TEXCOORD6;
|
||||
@@ -102,7 +103,7 @@ PSInput VSMain(VSInput input) {
|
||||
output.col = input.col;
|
||||
output.rect_min = input.rect_min;
|
||||
output.rect_max = input.rect_max;
|
||||
output.corner_radius = input.corner_radius;
|
||||
output.corner_radii = input.corner_radii;
|
||||
output.border_thickness = input.border_thickness;
|
||||
output.softness = input.softness;
|
||||
output.mode = input.mode;
|
||||
@@ -126,7 +127,10 @@ float4 PSMain(PSInput input) : SV_TARGET {
|
||||
float2 pixel_pos = input.pos.xy;
|
||||
float2 rect_center = (input.rect_min + input.rect_max) * 0.5;
|
||||
float2 rect_half_size = (input.rect_max - input.rect_min) * 0.5;
|
||||
float radius = input.corner_radius;
|
||||
// corner_radii = (TL, TR, BR, BL) — select radius by quadrant
|
||||
float radius = (pixel_pos.x < rect_center.x)
|
||||
? ((pixel_pos.y < rect_center.y) ? input.corner_radii.x : input.corner_radii.w)
|
||||
: ((pixel_pos.y < rect_center.y) ? input.corner_radii.y : input.corner_radii.z);
|
||||
float softness = max(input.softness, 0.5);
|
||||
float dist = rounded_rect_sdf(pixel_pos, rect_center, rect_half_size, radius);
|
||||
|
||||
@@ -692,7 +696,7 @@ static bool create_ui_pipeline(Renderer *r) {
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(UIVertex, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(UIVertex, rect_min), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(UIVertex, rect_max), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 3, DXGI_FORMAT_R32_FLOAT, 0, offsetof(UIVertex, corner_radius), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(UIVertex, corner_radii), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 4, DXGI_FORMAT_R32_FLOAT, 0, offsetof(UIVertex, border_thickness), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 5, DXGI_FORMAT_R32_FLOAT, 0, offsetof(UIVertex, softness), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 6, DXGI_FORMAT_R32_FLOAT, 0, offsetof(UIVertex, mode), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
@@ -809,7 +813,8 @@ static void emit_quad(DrawBatch *batch,
|
||||
float u0, float v0, float u1, float v1,
|
||||
float cr, float cg, float cb, float ca,
|
||||
float rmin_x, float rmin_y, float rmax_x, float rmax_y,
|
||||
float corner_radius, float border_thickness, float softness, float mode)
|
||||
float cr_tl, float cr_tr, float cr_br, float cr_bl,
|
||||
float border_thickness, float softness, float mode)
|
||||
{
|
||||
if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES)
|
||||
return;
|
||||
@@ -833,7 +838,8 @@ static void emit_quad(DrawBatch *batch,
|
||||
v[i].col[0] = cr; v[i].col[1] = cg; v[i].col[2] = cb; v[i].col[3] = ca;
|
||||
v[i].rect_min[0] = rmin_x; v[i].rect_min[1] = rmin_y;
|
||||
v[i].rect_max[0] = rmax_x; v[i].rect_max[1] = rmax_y;
|
||||
v[i].corner_radius = corner_radius;
|
||||
v[i].corner_radii[0] = cr_tl; v[i].corner_radii[1] = cr_tr;
|
||||
v[i].corner_radii[2] = cr_br; v[i].corner_radii[3] = cr_bl;
|
||||
v[i].border_thickness = border_thickness;
|
||||
v[i].softness = softness;
|
||||
v[i].mode = mode;
|
||||
@@ -850,13 +856,60 @@ static void emit_quad(DrawBatch *batch,
|
||||
static void emit_rect(DrawBatch *batch,
|
||||
float x0, float y0, float x1, float y1,
|
||||
float cr, float cg, float cb, float ca,
|
||||
float corner_radius, float border_thickness, float softness)
|
||||
float cr_tl, float cr_tr, float cr_br, float cr_bl,
|
||||
float border_thickness, float softness)
|
||||
{
|
||||
emit_quad(batch, x0, y0, x1, y1,
|
||||
0, 0, 0, 0,
|
||||
cr, cg, cb, ca,
|
||||
x0, y0, x1, y1,
|
||||
corner_radius, border_thickness, softness, 0.0f);
|
||||
cr_tl, cr_tr, cr_br, cr_bl,
|
||||
border_thickness, softness, 0.0f);
|
||||
}
|
||||
|
||||
static void emit_rect_vgradient(DrawBatch *batch,
|
||||
float x0, float y0, float x1, float y1,
|
||||
float tr, float tg, float tb, float ta,
|
||||
float br, float bg, float bb_, float ba,
|
||||
float cr_tl, float cr_tr, float cr_br, float cr_bl,
|
||||
float softness)
|
||||
{
|
||||
if (batch->vertex_count + 4 > MAX_VERTICES || batch->index_count + 6 > MAX_INDICES)
|
||||
return;
|
||||
|
||||
U32 base = batch->vertex_count;
|
||||
UIVertex *v = &batch->vertices[base];
|
||||
|
||||
float pad = softness + 1.0f;
|
||||
float px0 = x0 - pad, py0 = y0 - pad, px1 = x1 + pad, py1 = y1 + pad;
|
||||
|
||||
v[0].pos[0] = px0; v[0].pos[1] = py0; v[0].uv[0] = 0; v[0].uv[1] = 0;
|
||||
v[1].pos[0] = px1; v[1].pos[1] = py0; v[1].uv[0] = 0; v[1].uv[1] = 0;
|
||||
v[2].pos[0] = px1; v[2].pos[1] = py1; v[2].uv[0] = 0; v[2].uv[1] = 0;
|
||||
v[3].pos[0] = px0; v[3].pos[1] = py1; v[3].uv[0] = 0; v[3].uv[1] = 0;
|
||||
|
||||
// Top vertices get top color, bottom vertices get bottom color
|
||||
v[0].col[0] = tr; v[0].col[1] = tg; v[0].col[2] = tb; v[0].col[3] = ta;
|
||||
v[1].col[0] = tr; v[1].col[1] = tg; v[1].col[2] = tb; v[1].col[3] = ta;
|
||||
v[2].col[0] = br; v[2].col[1] = bg; v[2].col[2] = bb_; v[2].col[3] = ba;
|
||||
v[3].col[0] = br; v[3].col[1] = bg; v[3].col[2] = bb_; v[3].col[3] = ba;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
v[i].rect_min[0] = x0; v[i].rect_min[1] = y0;
|
||||
v[i].rect_max[0] = x1; v[i].rect_max[1] = y1;
|
||||
v[i].corner_radii[0] = cr_tl; v[i].corner_radii[1] = cr_tr;
|
||||
v[i].corner_radii[2] = cr_br; v[i].corner_radii[3] = cr_bl;
|
||||
v[i].border_thickness = 0;
|
||||
v[i].softness = softness;
|
||||
v[i].mode = 0;
|
||||
}
|
||||
|
||||
U32 *idx = &batch->indices[batch->index_count];
|
||||
idx[0] = base; idx[1] = base + 1; idx[2] = base + 2;
|
||||
idx[3] = base; idx[4] = base + 2; idx[5] = base + 3;
|
||||
|
||||
batch->vertex_count += 4;
|
||||
batch->index_count += 6;
|
||||
}
|
||||
|
||||
static void emit_text_glyphs(DrawBatch *batch, Renderer *r,
|
||||
@@ -901,7 +954,8 @@ static void emit_text_glyphs(DrawBatch *batch, Renderer *r,
|
||||
g->u0, g->v0, g->u1, g->v1,
|
||||
cr, cg, cb, ca,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
0, 0, 0, 0,
|
||||
0, 0, 1.0f);
|
||||
|
||||
x += g->x_advance * scale;
|
||||
}
|
||||
@@ -1075,13 +1129,12 @@ void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) {
|
||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||
Clay_RectangleRenderData *rect = &cmd->renderData.rectangle;
|
||||
Clay_Color c = rect->backgroundColor;
|
||||
// Use average corner radius for SDF
|
||||
float cr = (rect->cornerRadius.topLeft + rect->cornerRadius.topRight +
|
||||
rect->cornerRadius.bottomLeft + rect->cornerRadius.bottomRight) * 0.25f;
|
||||
emit_rect(&batch,
|
||||
bb.x, bb.y, bb.x + bb.width, bb.y + bb.height,
|
||||
c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f,
|
||||
cr, 0, 1.0f);
|
||||
rect->cornerRadius.topLeft, rect->cornerRadius.topRight,
|
||||
rect->cornerRadius.bottomRight, rect->cornerRadius.bottomLeft,
|
||||
0, 1.0f);
|
||||
} break;
|
||||
|
||||
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
|
||||
@@ -1095,19 +1148,19 @@ void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) {
|
||||
// Draw individual border sides as thin rects
|
||||
if (border->width.top > 0) {
|
||||
emit_rect(&batch, bb.x, bb.y, bb.x + bb.width, bb.y + border->width.top,
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 1.0f);
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 0, 0, 0, 1.0f);
|
||||
}
|
||||
if (border->width.bottom > 0) {
|
||||
emit_rect(&batch, bb.x, bb.y + bb.height - border->width.bottom, bb.x + bb.width, bb.y + bb.height,
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 1.0f);
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 0, 0, 0, 1.0f);
|
||||
}
|
||||
if (border->width.left > 0) {
|
||||
emit_rect(&batch, bb.x, bb.y, bb.x + border->width.left, bb.y + bb.height,
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 1.0f);
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 0, 0, 0, 1.0f);
|
||||
}
|
||||
if (border->width.right > 0) {
|
||||
emit_rect(&batch, bb.x + bb.width - border->width.right, bb.y, bb.x + bb.width, bb.y + bb.height,
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 1.0f);
|
||||
cr_norm, cg_norm, cb_norm, ca_norm, 0, 0, 0, 0, 0, 1.0f);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1137,8 +1190,26 @@ void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) {
|
||||
r->command_list->RSSetScissorRects(1, &full_scissor);
|
||||
} break;
|
||||
|
||||
case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
|
||||
Clay_CustomRenderData *custom = &cmd->renderData.custom;
|
||||
if (custom->customData) {
|
||||
CustomRenderType type = *(CustomRenderType *)custom->customData;
|
||||
if (type == CUSTOM_RENDER_VGRADIENT) {
|
||||
CustomGradientData *grad = (CustomGradientData *)custom->customData;
|
||||
Clay_Color tc = grad->top_color;
|
||||
Clay_Color bc = grad->bottom_color;
|
||||
emit_rect_vgradient(&batch,
|
||||
bb.x, bb.y, bb.x + bb.width, bb.y + bb.height,
|
||||
tc.r / 255.f, tc.g / 255.f, tc.b / 255.f, tc.a / 255.f,
|
||||
bc.r / 255.f, bc.g / 255.f, bc.b / 255.f, bc.a / 255.f,
|
||||
custom->cornerRadius.topLeft, custom->cornerRadius.topRight,
|
||||
custom->cornerRadius.bottomRight, custom->cornerRadius.bottomLeft,
|
||||
1.0f);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE:
|
||||
case CLAY_RENDER_COMMAND_TYPE_CUSTOM:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user