use premultiplied alpha for ui composition
This commit is contained in:
parent
8aa44b5deb
commit
ba8b1667db
@ -260,25 +260,30 @@ Vec4 SrgbFromLinear(Vec4 lin)
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 LinearU32FromSrgb(Vec4 srgb)
|
||||
Vec4 PremulFromLinear(Vec4 lin)
|
||||
{
|
||||
Vec4 result = Zi;
|
||||
result.x = lin.x * lin.w;
|
||||
result.y = lin.y * lin.w;
|
||||
result.z = lin.z * lin.w;
|
||||
result.w = lin.w;
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec4 PremulFromSrgb(Vec4 srgb)
|
||||
{
|
||||
Vec4 lin = LinearFromSrgb(srgb);
|
||||
u32 result = U32FromVec4(lin);
|
||||
return result;
|
||||
Vec4 premul = PremulFromLinear(lin);
|
||||
return premul;
|
||||
}
|
||||
|
||||
Vec4 LerpSrgb(Vec4 v0, Vec4 v1, f32 t)
|
||||
{
|
||||
Vec4 v0_l = LinearFromSrgb(v0);
|
||||
Vec4 v1_l = LinearFromSrgb(v1);
|
||||
Vec4 blend_l = Zi;
|
||||
{
|
||||
blend_l.x = LerpF32(v0_l.x, v1_l.x, t);
|
||||
blend_l.y = LerpF32(v0_l.y, v1_l.y, t);
|
||||
blend_l.z = LerpF32(v0_l.z, v1_l.z, t);
|
||||
blend_l.w = LerpF32(v0_l.w, v1_l.w, t);
|
||||
}
|
||||
Vec4 result = SrgbFromLinear(blend_l);
|
||||
Vec4 result = Zi;
|
||||
Vec4 v0_lin = LinearFromSrgb(v0);
|
||||
Vec4 v1_lin = LinearFromSrgb(v1);
|
||||
Vec4 lerp_lin = LerpVec4(v0_lin, v1_lin, t);
|
||||
result = SrgbFromLinear(lerp_lin);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -494,21 +499,21 @@ Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p)
|
||||
//- Lerp
|
||||
|
||||
// Interpolate position vectors
|
||||
Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t)
|
||||
Vec2 LerpVec2(Vec2 v0, Vec2 v1, f32 t)
|
||||
{
|
||||
return VEC2(LerpF32(val0.x, val1.x, t), LerpF32(val0.y, val1.y, t));
|
||||
return VEC2(LerpF32(v0.x, v1.x, t), LerpF32(v0.y, v1.y, t));
|
||||
}
|
||||
|
||||
Vec2 LerpVec2Vec2(Vec2 val0, Vec2 val1, Vec2 t)
|
||||
Vec2 LerpVec2Vec2(Vec2 v0, Vec2 v1, Vec2 t)
|
||||
{
|
||||
return VEC2(LerpF32(val0.x, val1.x, t.x), LerpF32(val0.y, val1.y, t.y));
|
||||
return VEC2(LerpF32(v0.x, v1.x, t.x), LerpF32(v0.y, v1.y, t.y));
|
||||
}
|
||||
|
||||
// Interpolate direction vectors (spherical lerp)
|
||||
Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t)
|
||||
Vec2 SlerpVec2(Vec2 v0, Vec2 v1, f32 t)
|
||||
{
|
||||
f32 rot = LerpAngleF32(AngleFromVec2(val0), AngleFromVec2(val1), t);
|
||||
f32 len = LerpF32(Vec2Len(val0), Vec2Len(val1), t);
|
||||
f32 rot = LerpAngleF32(AngleFromVec2(v0), AngleFromVec2(v1), t);
|
||||
f32 len = LerpF32(Vec2Len(v0), Vec2Len(v1), t);
|
||||
return MulVec2(Vec2FromAngle(rot), len);
|
||||
}
|
||||
|
||||
@ -560,6 +565,18 @@ Vec4 MulVec4Vec4(Vec4 a, Vec4 b)
|
||||
return VEC4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
|
||||
}
|
||||
|
||||
//- Lerp
|
||||
|
||||
Vec4 LerpVec4(Vec4 v0, Vec4 v1, f32 t)
|
||||
{
|
||||
Vec4 result = Zi;
|
||||
result.x = LerpF32(v0.x, v1.x, t);
|
||||
result.y = LerpF32(v0.y, v1.y, t);
|
||||
result.z = LerpF32(v0.z, v1.z, t);
|
||||
result.w = LerpF32(v0.w, v1.w, t);
|
||||
return result;
|
||||
}
|
||||
|
||||
//- Conversion
|
||||
|
||||
Vec4 Vec4FromU32(u32 v)
|
||||
|
||||
@ -297,9 +297,14 @@ i64 LerpU64(u64 val0, u64 val1, f64 t);
|
||||
|
||||
f32 SrgbFromLinearF32(f32 lin);
|
||||
f32 LinearFromSrgbF32(f32 srgb);
|
||||
|
||||
Vec4 LinearFromSrgb(Vec4 srgb);
|
||||
Vec4 SrgbFromLinear(Vec4 lin);
|
||||
u32 LinearU32FromSrgb(Vec4 srgb);
|
||||
|
||||
Vec4 PremulFromLinear(Vec4 lin);
|
||||
Vec4 PremulFromSrgb(Vec4 srgb);
|
||||
|
||||
// Vec4 LerpLinear(Vec4 v0, Vec4 v1, f32 t);
|
||||
Vec4 LerpSrgb(Vec4 v0, Vec4 v1, f32 t);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -356,9 +361,9 @@ f32 AngleFromVec2Points(Vec2 pt1, Vec2 pt2);
|
||||
Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p);
|
||||
|
||||
//- Lerp
|
||||
Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t);
|
||||
Vec2 LerpVec2Vec2(Vec2 val0, Vec2 val1, Vec2 t);
|
||||
Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t);
|
||||
Vec2 LerpVec2(Vec2 v0, Vec2 v1, f32 t);
|
||||
Vec2 LerpVec2Vec2(Vec2 v0, Vec2 v1, Vec2 t);
|
||||
Vec2 SlerpVec2(Vec2 v0, Vec2 v1, f32 t);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Vec2I32
|
||||
@ -375,6 +380,10 @@ Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b);
|
||||
Vec4 MulVec4(Vec4 v, f32 s);
|
||||
Vec4 MulVec4Vec4(Vec4 a, Vec4 b);
|
||||
|
||||
//- Lerp
|
||||
|
||||
Vec4 LerpVec4(Vec4 v0, Vec4 v1, f32 t);
|
||||
|
||||
//- Conversion
|
||||
Vec4 Vec4FromU32(u32 v);
|
||||
u32 U32FromVec4(Vec4 v);
|
||||
|
||||
@ -86,7 +86,7 @@ u32 countof(T arr[N])
|
||||
|
||||
Vec4 Vec4FromU32(u32 v)
|
||||
{
|
||||
Vec4 result;
|
||||
Vec4 result = 0;
|
||||
result.x = ((v >> 0) & 0xFF) / 255.0;
|
||||
result.y = ((v >> 8) & 0xFF) / 255.0;
|
||||
result.z = ((v >> 16) & 0xFF) / 255.0;
|
||||
@ -96,7 +96,7 @@ Vec4 Vec4FromU32(u32 v)
|
||||
|
||||
u32 U32FromVec4(Vec4 v)
|
||||
{
|
||||
u32 result;
|
||||
u32 result = 0;
|
||||
result |= (((u32)(v.x * 255.0)) & 0xFF) << 0;
|
||||
result |= (((u32)(v.y * 255.0)) & 0xFF) << 8;
|
||||
result |= (((u32)(v.z * 255.0)) & 0xFF) << 16;
|
||||
@ -128,6 +128,14 @@ Vec4 LinearFromSrgb(Vec4 srgb)
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec4 Premul(Vec4 v)
|
||||
{
|
||||
Vec4 result;
|
||||
result.rgb = v.rgb * v.a;
|
||||
result.a = v.a;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Vertex ID helpers
|
||||
|
||||
|
||||
@ -107,6 +107,6 @@ f64 TweakFloat_(String name, f64 initial, TweakFloatDesc desc);
|
||||
.category = Lit("Debug"), \
|
||||
.min = (_min), \
|
||||
.max = (_max), \
|
||||
.precision = 2, \
|
||||
.precision = 3, \
|
||||
__VA_ARGS__ \
|
||||
})
|
||||
|
||||
@ -479,6 +479,13 @@ Enum(G_RasterMode)
|
||||
G_RasterMode_WireTriangleStrip,
|
||||
};
|
||||
|
||||
Enum(G_BlendMode)
|
||||
{
|
||||
G_BlendMode_Opaque,
|
||||
G_BlendMode_CompositeStraightAlpha,
|
||||
G_BlendMode_CompositePremultipliedAlpha,
|
||||
};
|
||||
|
||||
Struct(G_IndexBufferDesc)
|
||||
{
|
||||
G_ResourceHandle resource;
|
||||
@ -486,6 +493,12 @@ Struct(G_IndexBufferDesc)
|
||||
u32 index_count;
|
||||
};
|
||||
|
||||
Struct(G_RenderTargetDesc)
|
||||
{
|
||||
G_ResourceHandle resource;
|
||||
G_BlendMode blend;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Statistic types
|
||||
|
||||
@ -585,6 +598,10 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena, G_CommandListHandle cl, G_R
|
||||
#define G_IdxBuff16(_res) ((G_IndexBufferDesc) { .resource = (_res), .index_size = 2, .index_count = (G_CountBuffer((_res), i16)) })
|
||||
#define G_IdxBuff32(_res) ((G_IndexBufferDesc) { .resource = (_res), .index_size = 4, .index_count = (G_CountBuffer((_res), i32)) })
|
||||
|
||||
//- Render target helpers
|
||||
|
||||
#define G_Rt(_res, _blend_mode) ((G_RenderTargetDesc) { .resource = (_res), .blend = (_blend_mode) })
|
||||
|
||||
//- Count
|
||||
|
||||
u64 G_CountBufferBytes(G_ResourceHandle buffer);
|
||||
@ -765,9 +782,9 @@ void G_Rasterize(
|
||||
G_CommandListHandle cl,
|
||||
VertexShader vs, PixelShader ps,
|
||||
u32 instances_count, G_IndexBufferDesc index_buffer,
|
||||
u32 render_targets_count, G_ResourceHandle *render_targets,
|
||||
u32 render_targets_count, G_RenderTargetDesc *render_targets,
|
||||
Rng3 viewport, Rng2 scissor,
|
||||
G_RasterMode mode
|
||||
G_RasterMode raster_mode
|
||||
);
|
||||
|
||||
//- Clear
|
||||
|
||||
@ -496,6 +496,30 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
ID3D12PipelineState *pso = 0;
|
||||
if (ok && (!IsResourceNil(desc.vs.resource) || !IsResourceNil(desc.ps.resource)))
|
||||
{
|
||||
i32 rts_count = 0;
|
||||
b32 has_multiple_blend_modes = 0;
|
||||
{
|
||||
G_BlendMode last_blend_mode = 0;
|
||||
for (i32 rt_idx = 0; rt_idx < countof(desc.render_target_formats); ++rt_idx)
|
||||
{
|
||||
G_BlendMode blend_mode = desc.render_target_blend_modes[rt_idx];
|
||||
DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(desc.render_target_formats[rt_idx]);
|
||||
if (format == DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rt_idx > 0 && blend_mode != last_blend_mode)
|
||||
{
|
||||
has_multiple_blend_modes = 1;
|
||||
}
|
||||
last_blend_mode = blend_mode;
|
||||
rts_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_RASTERIZER_DESC raster_desc = Zi;
|
||||
{
|
||||
if (desc.is_wireframe)
|
||||
@ -520,16 +544,51 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
|
||||
D3D12_BLEND_DESC blend_desc = Zi;
|
||||
{
|
||||
blend_desc.IndependentBlendEnable = has_multiple_blend_modes;
|
||||
blend_desc.AlphaToCoverageEnable = 0;
|
||||
blend_desc.IndependentBlendEnable = 0;
|
||||
blend_desc.RenderTarget[0].BlendEnable = 1;
|
||||
blend_desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
|
||||
blend_desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
blend_desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
|
||||
blend_desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||
blend_desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
blend_desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
for (i32 rt_idx = 0; rt_idx < rts_count; ++rt_idx)
|
||||
{
|
||||
G_BlendMode blend_mode = desc.render_target_blend_modes[rt_idx];
|
||||
D3D12_RENDER_TARGET_BLEND_DESC *rt = &blend_desc.RenderTarget[rt_idx];
|
||||
switch (blend_mode)
|
||||
{
|
||||
default:
|
||||
{
|
||||
rt->BlendEnable = 0;
|
||||
rt->RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
} break;
|
||||
|
||||
case G_BlendMode_CompositeStraightAlpha:
|
||||
{
|
||||
rt->BlendEnable = 1;
|
||||
|
||||
rt->SrcBlend = D3D12_BLEND_SRC_ALPHA;
|
||||
rt->BlendOp = D3D12_BLEND_OP_ADD;
|
||||
rt->DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
rt->SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||
rt->BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
rt->DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
rt->RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
} break;
|
||||
|
||||
case G_BlendMode_CompositePremultipliedAlpha:
|
||||
{
|
||||
rt->BlendEnable = 1;
|
||||
|
||||
rt->SrcBlend = D3D12_BLEND_ONE;
|
||||
rt->BlendOp = D3D12_BLEND_OP_ADD;
|
||||
rt->DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
rt->SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||
rt->BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
rt->DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
rt->RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_DEPTH_STENCIL_DESC ds_desc = Zi;
|
||||
@ -554,18 +613,11 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
pso_desc.SampleMask = UINT_MAX;
|
||||
pso_desc.SampleDesc.Count = 1;
|
||||
pso_desc.SampleDesc.Quality = 0;
|
||||
for (i32 i = 0; i < (i32)countof(desc.render_target_formats); ++i)
|
||||
pso_desc.NumRenderTargets = rts_count;
|
||||
for (i32 rt_idx = 0; rt_idx < rts_count; ++rt_idx)
|
||||
{
|
||||
StaticAssert(countof(pso_desc.RTVFormats) <= countof(desc.render_target_formats));
|
||||
DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(desc.render_target_formats[i]);
|
||||
if (format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
pso_desc.RTVFormats[pso_desc.NumRenderTargets++] = format;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(desc.render_target_formats[rt_idx]);
|
||||
pso_desc.RTVFormats[rt_idx] = format;
|
||||
}
|
||||
}
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||
@ -1727,7 +1779,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
}
|
||||
{
|
||||
b32 tweak_b32 = TweakBool("GPU tweak-bool", 1);
|
||||
f32 tweak_f32 = TweakFloat("GPU tweak-float", 1, 0, 1, .precision = 3);
|
||||
f32 tweak_f32 = TweakFloat("GPU tweak-float", 1, 0, 1);
|
||||
slotted_constants[G_ShaderConst_TweakB32] = tweak_b32;
|
||||
slotted_constants[G_ShaderConst_TweakF32] = *(u32 *)&tweak_f32;
|
||||
}
|
||||
@ -2029,6 +2081,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
|
||||
case G_D12_CmdKind_Compute:
|
||||
{
|
||||
// Fetch pipeline
|
||||
G_D12_Pipeline *pipeline = 0;
|
||||
{
|
||||
G_D12_PipelineDesc pipeline_desc = Zi;
|
||||
@ -2084,6 +2137,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
|
||||
case G_D12_CmdKind_Rasterize:
|
||||
{
|
||||
// Fetch pipeline
|
||||
G_D12_Pipeline *pipeline = 0;
|
||||
{
|
||||
G_D12_PipelineDesc pipeline_desc = Zi;
|
||||
@ -2091,7 +2145,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
pipeline_desc.ps = cmd->rasterize.ps;
|
||||
{
|
||||
pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED;
|
||||
switch (cmd->rasterize.mode)
|
||||
switch (cmd->rasterize.raster_mode)
|
||||
{
|
||||
default: Assert(0); break;
|
||||
case G_RasterMode_PointList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; break;
|
||||
@ -2103,16 +2157,18 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
case G_RasterMode_WireTriangleStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break;
|
||||
}
|
||||
}
|
||||
if (cmd->rasterize.mode == G_RasterMode_WireTriangleList || cmd->rasterize.mode == G_RasterMode_WireTriangleStrip)
|
||||
if (cmd->rasterize.raster_mode == G_RasterMode_WireTriangleList || cmd->rasterize.raster_mode == G_RasterMode_WireTriangleStrip)
|
||||
{
|
||||
pipeline_desc.is_wireframe = 1;
|
||||
}
|
||||
for (u32 i = 0; i < countof(cmd->rasterize.render_targets); ++i)
|
||||
for (u32 i = 0; i < countof(cmd->rasterize.render_target_descs); ++i)
|
||||
{
|
||||
G_D12_Resource *rt = cmd->rasterize.render_targets[i];
|
||||
G_RenderTargetDesc desc = cmd->rasterize.render_target_descs[i];
|
||||
G_D12_Resource *rt = G_D12_ResourceFromHandle(desc.resource);
|
||||
if (rt)
|
||||
{
|
||||
pipeline_desc.render_target_formats[i] = rt->texture_format;
|
||||
pipeline_desc.render_target_blend_modes[i] = desc.blend;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2226,7 +2282,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
// Set topology
|
||||
{
|
||||
D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
switch (cmd->rasterize.mode)
|
||||
switch (cmd->rasterize.raster_mode)
|
||||
{
|
||||
default: Assert(0); break;
|
||||
case G_RasterMode_PointList: topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; break;
|
||||
@ -2254,9 +2310,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
{
|
||||
b32 om_dirty = 0;
|
||||
u32 rtvs_count = 0;
|
||||
for (u32 i = 0; i < countof(cmd->rasterize.render_targets); ++i)
|
||||
for (u32 i = 0; i < countof(cmd->rasterize.render_target_descs); ++i)
|
||||
{
|
||||
G_D12_Resource *rt = cmd->rasterize.render_targets[i];
|
||||
G_RenderTargetDesc desc = cmd->rasterize.render_target_descs[i];
|
||||
G_D12_Resource *rt = G_D12_ResourceFromHandle(desc.resource);
|
||||
if (rt)
|
||||
{
|
||||
if (bound_render_target_uids[i] != rt->uid)
|
||||
@ -2627,9 +2684,9 @@ void G_Rasterize(
|
||||
G_CommandListHandle cl_handle,
|
||||
VertexShader vs, PixelShader ps,
|
||||
u32 instances_count, G_IndexBufferDesc index_buffer,
|
||||
u32 render_targets_count, G_ResourceHandle *render_targets,
|
||||
u32 render_targets_count, G_RenderTargetDesc *render_targets,
|
||||
Rng3 viewport, Rng2 scissor,
|
||||
G_RasterMode mode
|
||||
G_RasterMode raster_mode
|
||||
)
|
||||
{
|
||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||
@ -2641,11 +2698,11 @@ void G_Rasterize(
|
||||
cmd->rasterize.index_buffer_desc = index_buffer;
|
||||
for (u32 i = 0; i < MinU32(render_targets_count, G_MaxRenderTargets); ++i)
|
||||
{
|
||||
cmd->rasterize.render_targets[i] = G_D12_ResourceFromHandle(render_targets[i]);
|
||||
cmd->rasterize.render_target_descs[i] = render_targets[i];
|
||||
}
|
||||
cmd->rasterize.viewport = viewport;
|
||||
cmd->rasterize.scissor = scissor;
|
||||
cmd->rasterize.mode = mode;
|
||||
cmd->rasterize.raster_mode = raster_mode;
|
||||
}
|
||||
|
||||
//- Clear
|
||||
|
||||
@ -36,6 +36,7 @@ Struct(G_D12_PipelineDesc)
|
||||
b32 is_wireframe;
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE topology_type;
|
||||
G_Format render_target_formats[G_MaxRenderTargets];
|
||||
G_BlendMode render_target_blend_modes[G_MaxRenderTargets];
|
||||
};
|
||||
|
||||
Struct(G_D12_Pipeline)
|
||||
@ -345,10 +346,10 @@ Struct(G_D12_Cmd)
|
||||
PixelShader ps;
|
||||
u32 instances_count;
|
||||
G_IndexBufferDesc index_buffer_desc;
|
||||
G_D12_Resource *render_targets[G_MaxRenderTargets];
|
||||
G_RenderTargetDesc render_target_descs[G_MaxRenderTargets];
|
||||
Rng3 viewport;
|
||||
Rng2 scissor;
|
||||
G_RasterMode mode;
|
||||
G_RasterMode raster_mode;
|
||||
} rasterize;
|
||||
|
||||
struct
|
||||
|
||||
@ -421,9 +421,15 @@ void BuildEntryPoint(WaveLaneCtx *lane)
|
||||
|
||||
//- Dxc
|
||||
{
|
||||
// PushStringToList(perm, &cp.flags_dxc, Lit("-Od"));
|
||||
PushStringToList(perm, &cp.flags_dxc, Lit("-O3"));
|
||||
PushStringToList(perm, &cp.flags_dxc, Lit("-Zi -Qembed_debug"));
|
||||
|
||||
// Enable warnings
|
||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wall"));
|
||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-WX"));
|
||||
|
||||
// Disable warnings
|
||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wno-unused-variable"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -868,13 +874,14 @@ void BuildEntryPoint(WaveLaneCtx *lane)
|
||||
: Lit("vs_6_6");
|
||||
String compile_cmd = StringF(
|
||||
perm,
|
||||
"dxc.exe -T %F -E %F -Fo %F %F %F %F",
|
||||
"dxc.exe -T %F -E %F -Fo %F %F %F %F %F",
|
||||
FmtString(target),
|
||||
FmtString(e->name),
|
||||
FmtString(out_file),
|
||||
FmtString(gpu_out_file),
|
||||
FmtString(StringFromList(perm, cp.defs, Lit(" "))),
|
||||
FmtString(StringFromList(perm, cp.flags_dxc, Lit(" ")))
|
||||
FmtString(StringFromList(perm, cp.flags_dxc, Lit(" "))),
|
||||
FmtString(StringFromList(perm, cp.warnings_dxc, Lit(" ")))
|
||||
);
|
||||
|
||||
OS_CommandResult cmd_result = OS_RunCommand(perm, compile_cmd);
|
||||
|
||||
@ -98,9 +98,7 @@ V_WidgetTheme V_GetWidgetTheme(void)
|
||||
theme.text_padding_x = 5;
|
||||
theme.text_padding_y = 5;
|
||||
|
||||
|
||||
theme.window_bd_sz = 1;
|
||||
theme.window_padding = theme.window_bd_sz - 1;
|
||||
theme.window_padding = 1;
|
||||
|
||||
//- Colors
|
||||
theme.col.window_bg = Rgb32(0xff1a1d1e);
|
||||
@ -1321,7 +1319,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 drag_offset = SubVec2(ui_frame->drag_cursor_pos, palette_reps.drag.screen_anchor);
|
||||
palette->pos = SubVec2(frame->ui_cursor, drag_offset);
|
||||
}
|
||||
window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_reps.draw.hot);
|
||||
window_border_color = LerpSrgb(window_border_color, theme.col.button_active, titlebar_reps.draw.hot);
|
||||
|
||||
f32 scale = LerpF32(0.85, 1, palette->show);
|
||||
UI_Push(Tint, VEC4(1, 1, 1, palette->show));
|
||||
@ -1329,7 +1327,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
UI_Push(BackgroundColor, window_background_color);
|
||||
UI_Push(BorderColor, window_border_color);
|
||||
UI_Push(BorderSize, theme.window_bd_sz);
|
||||
// UI_Push(BorderSize, theme.window_bd_sz);
|
||||
UI_Push(BorderSize, 1);
|
||||
UI_Push(Rounding, UI_RGROW(0.095 * theme.rounding));
|
||||
UI_Push(Width, UI_FNT(40, 0));
|
||||
UI_Push(Height, UI_SHRINK(0, 0));
|
||||
@ -1358,7 +1357,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_BuildRow();
|
||||
|
||||
// Title box
|
||||
UI_SetNext(FontSize, UI_Top(FontSize) * theme.h2);
|
||||
UI_SetNext(FontSize, UI_Top(FontSize) * theme.h3);
|
||||
UI_SetNext(ChildAlignment, UI_Region_Center);
|
||||
UI_SetNext(Width, UI_SHRINK(0, 1));
|
||||
UI_SetNext(Text, Lit("Debug Palette"));
|
||||
@ -1376,7 +1375,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Build palette items list
|
||||
|
||||
f32 window_padding = theme.window_bd_sz;
|
||||
f32 window_padding = theme.window_padding;
|
||||
UI_SetNext(Tint, 0);
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_PushCP(UI_BuildRow());
|
||||
@ -1475,8 +1474,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
|
||||
Vec4 item_color = theme.col.window_bg;
|
||||
Vec4 item_border_color = item_color;
|
||||
// Vec4 item_color = theme.col.window_bg;
|
||||
Vec4 item_color = Zi;
|
||||
// Vec4 item_color = theme.col.hint;
|
||||
Vec4 item_border_color = Zi;
|
||||
if (item->flags & PaletteItemFlag_IsCmd)
|
||||
{
|
||||
item_color = LerpSrgb(item_color, theme.col.button_hot, item_rep.hot);
|
||||
@ -1491,12 +1492,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
f32 item_size_px = UI_FNT(1.5, 1).v;
|
||||
f32 tweak_size_px = UI_FNT(1.25, 1).v;
|
||||
|
||||
UI_SetNext(BorderColor, 0);
|
||||
UI_SetNext(Rounding, UI_RPIX(0));
|
||||
UI_SetNext(Tint, 0);
|
||||
UI_PushCP(UI_BuildRow());
|
||||
{
|
||||
UI_SetNext(BorderColor, item_border_color);
|
||||
UI_SetNext(BackgroundColor, item_color);
|
||||
UI_SetNext(BorderColor, item_border_color);
|
||||
UI_SetNext(BorderSize, 1);
|
||||
UI_SetNext(Rounding, UI_RPIX(5));
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
UI_SetNext(Height, UI_PIX(item_size_px, 1));
|
||||
@ -1701,7 +1702,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_SetNext(BackgroundColor, slider_progress_color);
|
||||
// UI_SetNext(Rounding, UI_RGROW(theme.rounding));
|
||||
UI_SetNext(Rounding, 0);
|
||||
UI_SetNext(BorderColor, slider_border_color);
|
||||
UI_SetNext(BorderColor, 0);
|
||||
UI_SetNext(BorderSize, 1);
|
||||
UI_SetNext(Width, UI_PIX(marker_pos + half_marker_dims.x, 0));
|
||||
UI_SetNext(Height, UI_PIX(tweak_size_px * 0.75, 1));
|
||||
@ -2309,7 +2310,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->cl,
|
||||
V_DVertVS, V_DVertPS,
|
||||
1, dvert_idxs_ib,
|
||||
1, &draw_target,
|
||||
1, &G_Rt(draw_target, G_BlendMode_CompositeStraightAlpha),
|
||||
viewport, scissor,
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
@ -2323,7 +2324,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->cl,
|
||||
V_OverlayVS, V_OverlayPS,
|
||||
1, G_QuadIndices(),
|
||||
1, &draw_target,
|
||||
1, &G_Rt(draw_target, G_BlendMode_CompositeStraightAlpha),
|
||||
viewport, scissor,
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
|
||||
@ -33,9 +33,7 @@ Struct(V_WidgetTheme)
|
||||
|
||||
f32 rounding;
|
||||
|
||||
f32 window_bd_sz;
|
||||
f32 window_padding;
|
||||
|
||||
f32 text_padding_x;
|
||||
f32 text_padding_y;
|
||||
|
||||
|
||||
@ -1499,6 +1499,7 @@ void UI_EndFrame(UI_Frame *frame)
|
||||
} break;
|
||||
}
|
||||
|
||||
// Clamp rounding based on parent rounding
|
||||
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
||||
{
|
||||
Vec2 vtl = SubVec2(VEC2(parent->screen_rect.p0.x, parent->screen_rect.p0.y), VEC2(box->screen_rect.p0.x, box->screen_rect.p0.y));
|
||||
@ -1711,6 +1712,7 @@ void UI_EndFrame(UI_Frame *frame)
|
||||
params.rects = rects_ro;
|
||||
params.sampler = G_BasicSampler();
|
||||
params.cursor_pos = frame->cursor_pos;
|
||||
params.aa = TweakFloat("UI anti-aliasing", 1, 0, 1);
|
||||
}
|
||||
G_ResourceHandle params_buff = G_PushBufferFromString(frame->gpu_arena, frame->cl, StringFromStruct(¶ms));
|
||||
G_StructuredBufferRef params_ro = G_PushStructuredBufferRef(frame->gpu_arena, params_buff, UI_DParams);
|
||||
@ -1742,7 +1744,7 @@ void UI_EndFrame(UI_Frame *frame)
|
||||
frame->cl,
|
||||
UI_DRectVS, UI_DRectPS,
|
||||
rects_count, G_QuadIndices(),
|
||||
1, &draw_target,
|
||||
1, &G_Rt(draw_target, G_BlendMode_CompositePremultipliedAlpha),
|
||||
draw_viewport, draw_scissor,
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
@ -1755,7 +1757,7 @@ void UI_EndFrame(UI_Frame *frame)
|
||||
frame->cl,
|
||||
UI_DRectVS, UI_DRectPS,
|
||||
rects_count, G_QuadIndices(),
|
||||
1, &draw_target,
|
||||
1, &G_Rt(draw_target, G_BlendMode_CompositePremultipliedAlpha),
|
||||
draw_viewport, draw_scissor,
|
||||
G_RasterMode_WireTriangleList
|
||||
);
|
||||
@ -1772,7 +1774,7 @@ void UI_EndFrame(UI_Frame *frame)
|
||||
frame->cl,
|
||||
UI_BlitVS, UI_BlitPS,
|
||||
1, G_QuadIndices(),
|
||||
1, &backbuffer,
|
||||
1, &G_Rt(backbuffer, G_BlendMode_Opaque),
|
||||
monitor_viewport, monitor_scissor,
|
||||
G_RasterMode_TriangleList
|
||||
);
|
||||
|
||||
@ -6,6 +6,8 @@ G_DeclConstant(b32, UI_ShaderConst_DebugDraw, 1);
|
||||
|
||||
Struct(UI_DParams)
|
||||
{
|
||||
f32 aa;
|
||||
|
||||
Vec2I32 target_size;
|
||||
G_Texture2DRef target_ro;
|
||||
|
||||
|
||||
@ -15,14 +15,18 @@ VertexShader(UI_DRectVS, UI_DRectPSInput)
|
||||
Vec2 target_pos = lerp(rect.bounds.p0, rect.bounds.p1, rect_uv);
|
||||
|
||||
UI_DRectPSInput result;
|
||||
{
|
||||
result.sv_position = Vec4(NdcFromPos(target_pos, Vec2(params.target_size).xy), 0, 1);
|
||||
result.background_lin = rect.background_lin;
|
||||
result.border_lin = rect.border_lin;
|
||||
result.tint_lin = rect.tint_lin;
|
||||
result.rect_idx = SV_InstanceID;
|
||||
|
||||
result.base_background_premul = Premul(rect.background_lin);
|
||||
result.base_border_premul = Premul(rect.border_lin);
|
||||
result.tint_premul = Premul(rect.tint_lin);
|
||||
result.debug_premul = Premul(rect.debug_lin);
|
||||
|
||||
result.rect_uv = rect_uv;
|
||||
result.tex_uv = tex_uv;
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -42,7 +46,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
|
||||
Vec2 p0 = rect.bounds.p0;
|
||||
Vec2 p1 = rect.bounds.p1;
|
||||
|
||||
// Compute rect sdf (negative means pixel is inside of rect)
|
||||
//- Compute rect dist (negative means pixel is inside of rect)
|
||||
f32 rect_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y));
|
||||
{
|
||||
f32 tl_radius = rect.tl_rounding;
|
||||
@ -59,62 +63,54 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
|
||||
if (p.x < bl.x && p.y > bl.y) { rect_dist = min(rect_dist, bl_radius - length(bl - p)); }
|
||||
}
|
||||
rect_dist = -rect_dist;
|
||||
f32 rect_dist_fwidth = fwidth(rect_dist);
|
||||
|
||||
// Compute border sdf (negative means pixel is inside of border)
|
||||
f32 border_size = 0;
|
||||
f32 border_dist = 0;
|
||||
Vec4 border_color = 0;
|
||||
{
|
||||
if (rect.border_size > 0)
|
||||
{
|
||||
border_size = rect.border_size;
|
||||
border_color = input.border_lin;
|
||||
}
|
||||
else
|
||||
{
|
||||
border_size = 0;
|
||||
border_color = input.background_lin;
|
||||
}
|
||||
border_dist = abs(rect_dist);
|
||||
if (rect_dist <= 0)
|
||||
{
|
||||
border_dist -= border_size;
|
||||
}
|
||||
}
|
||||
bool is_inside = rect_dist < 0;
|
||||
|
||||
Vec4 final_color = 0;
|
||||
//- Compute background color
|
||||
Vec4 background_premul = 0;
|
||||
if (is_inside)
|
||||
{
|
||||
// Background color
|
||||
if (G_IsRefNil(rect.tex))
|
||||
{
|
||||
final_color = input.background_lin;
|
||||
background_premul = input.base_background_premul;
|
||||
}
|
||||
else
|
||||
{
|
||||
Texture2D<Vec4> tex = G_Dereference<Vec4>(rect.tex);
|
||||
final_color = tex.Sample(sampler, input.tex_uv);
|
||||
background_premul = tex.Sample(sampler, input.tex_uv);
|
||||
background_premul.rgb *= background_premul.a;
|
||||
}
|
||||
}
|
||||
final_color *= rect_dist <= 0;
|
||||
|
||||
// Border color
|
||||
//- Compute borer color
|
||||
Vec4 border_premul = input.base_border_premul;
|
||||
|
||||
//- Compute border dist
|
||||
f32 border_dist = 0;
|
||||
border_dist = abs(rect_dist);
|
||||
if (is_inside)
|
||||
{
|
||||
f32 half_border_dist_fwidth = fwidth(border_dist) * 0.5;
|
||||
f32 border_alpha = smoothstep(half_border_dist_fwidth, -half_border_dist_fwidth, border_dist);
|
||||
final_color = lerp(final_color, border_color, border_alpha);
|
||||
border_dist -= rect.border_size;
|
||||
}
|
||||
|
||||
// Tint
|
||||
final_color *= input.tint_lin;
|
||||
//- Compute anti-aliased border-over-background color
|
||||
Vec4 composite_premul = 0;
|
||||
{
|
||||
f32 smoothness = rect_dist_fwidth * params.aa * 0.5;
|
||||
f32 border_coverage = smoothstep(smoothness, -smoothness, border_dist);
|
||||
composite_premul = lerp(background_premul, border_premul, border_coverage);
|
||||
}
|
||||
|
||||
// Debug color
|
||||
//- Finalize
|
||||
Vec4 result = composite_premul * input.tint_premul;
|
||||
if (UI_ShaderConst_DebugDraw)
|
||||
{
|
||||
final_color = rect.debug_lin;
|
||||
}
|
||||
result = input.debug_premul;
|
||||
}
|
||||
|
||||
UI_DRectPSOutput output;
|
||||
output.sv_target0 = final_color;
|
||||
output.sv_target0 = result;
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@ -5,9 +5,10 @@ Struct(UI_DRectPSInput)
|
||||
{
|
||||
Semantic(Vec4, sv_position);
|
||||
Semantic(nointerpolation u32, rect_idx);
|
||||
Semantic(Vec4, background_lin);
|
||||
Semantic(Vec4, border_lin);
|
||||
Semantic(Vec4, tint_lin);
|
||||
Semantic(Vec4, base_background_premul);
|
||||
Semantic(Vec4, base_border_premul);
|
||||
Semantic(Vec4, tint_premul);
|
||||
Semantic(Vec4, debug_premul);
|
||||
Semantic(Vec2, rect_uv);
|
||||
Semantic(Vec2, tex_uv);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user