mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-19 09:48:26 +00:00
Shadows: WIP for latest (refreshing UV coordinates).
This commit is contained in:
@@ -4324,6 +4324,8 @@ static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImFontAtlasBuildUpdateShadowTexData(ImFontAtlas* atlas); // FIXME-SHADOWS: Move impl here.
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Was tempted to lazily init FontSrc but wouldn't save much + makes it more complicated to detect invalid data at AddFont()
|
// Was tempted to lazily init FontSrc but wouldn't save much + makes it more complicated to detect invalid data at AddFont()
|
||||||
@@ -4808,6 +4810,7 @@ void ImFontAtlasTextureRepack(ImFontAtlas* atlas, int w, int h)
|
|||||||
// Update other cached UV
|
// Update other cached UV
|
||||||
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
||||||
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
||||||
|
ImFontAtlasBuildUpdateShadowTexData(atlas);
|
||||||
|
|
||||||
builder->LockDisableResize = false;
|
builder->LockDisableResize = false;
|
||||||
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
ImFontAtlasUpdateDrawListsSharedData(atlas);
|
||||||
@@ -4924,22 +4927,6 @@ void ImFontAtlasTextureCompact(ImFontAtlas* atlas)
|
|||||||
ImFontAtlasTextureRepack(atlas, new_tex_size.x, new_tex_size.y);
|
ImFontAtlasTextureRepack(atlas, new_tex_size.x, new_tex_size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the rectangles we need for the rounded corner images
|
|
||||||
static void ImFontAtlasBuildRegisterShadowCustomRects(ImFontAtlas* atlas)
|
|
||||||
{
|
|
||||||
if (atlas->ShadowRectIds[0] >= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// ShadowRectIds[0] is the rectangle for rectangular shadows
|
|
||||||
// ShadowRectIds[1] is the rectangle for convex shadows
|
|
||||||
|
|
||||||
// The actual size we want to reserve, including padding
|
|
||||||
const ImFontAtlasShadowTexConfig* shadow_cfg = &atlas->ShadowTexConfig;
|
|
||||||
const unsigned int effective_size = shadow_cfg->CalcRectTexSize() + shadow_cfg->GetRectTexPadding();
|
|
||||||
atlas->ShadowRectIds[0] = atlas->AddCustomRect(effective_size, effective_size);
|
|
||||||
atlas->ShadowRectIds[1] = atlas->AddCustomRect(shadow_cfg->CalcConvexTexWidth() + shadow_cfg->GetConvexTexPadding(), shadow_cfg->CalcConvexTexHeight() + shadow_cfg->GetConvexTexPadding());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculates the signed distance from sample_pos to the nearest point on the rectangle defined by rect_min->rect_max
|
// Calculates the signed distance from sample_pos to the nearest point on the rectangle defined by rect_min->rect_max
|
||||||
static float DistanceFromRectangle(const ImVec2& sample_pos, const ImVec2& rect_min, const ImVec2& rect_max)
|
static float DistanceFromRectangle(const ImVec2& sample_pos, const ImVec2& rect_min, const ImVec2& rect_max)
|
||||||
{
|
{
|
||||||
@@ -4997,30 +4984,32 @@ static void GaussianBlur(float* data, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the actual pixel data for rounded corners in the atlas
|
// Generate the actual pixel data for rounded corners in the atlas
|
||||||
static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
|
static void ImFontAtlasBuildUpdateShadowTexData(ImFontAtlas* atlas)
|
||||||
{
|
{
|
||||||
IM_ASSERT(atlas->TexData && atlas->TexData->Pixels != NULL);
|
// The actual size we want to reserve, including padding
|
||||||
IM_ASSERT(atlas->ShadowRectIds[0] != ImFontAtlasRectId_Invalid && atlas->ShadowRectIds[1] != ImFontAtlasRectId_Invalid);
|
const ImFontAtlasShadowTexConfig* shadow_cfg = &atlas->ShadowTexConfig;
|
||||||
|
const unsigned int effective_size = shadow_cfg->CalcRectTexSize() + shadow_cfg->GetRectTexPadding();
|
||||||
|
const int corner_size = shadow_cfg->TexCornerSize;
|
||||||
|
const int edge_size = shadow_cfg->TexEdgeSize;
|
||||||
|
|
||||||
// Because of the blur, we have to generate the full 3x3 texture here, and then we chop that down to just the 2x2 section we need later.
|
// Because of the blur, we have to generate the full 3x3 texture here, and then we chop that down to just the 2x2 section we need later.
|
||||||
// 'size' correspond to the our 3x3 size, whereas 'shadow_tex_size' correspond to our 2x2 version where duplicate mirrored corners are not stored.
|
// 'size' correspond to the our 3x3 size, whereas 'shadow_tex_size' correspond to our 2x2 version where duplicate mirrored corners are not stored.
|
||||||
const ImFontAtlasShadowTexConfig* shadow_cfg = &atlas->ShadowTexConfig;
|
|
||||||
|
|
||||||
// The rectangular shadow texture
|
// The rectangular shadow texture
|
||||||
|
ImFontAtlasRect r;
|
||||||
|
bool add_and_draw = (atlas->GetCustomRect(atlas->ShadowRectIds[0], &r) == false);
|
||||||
|
if (add_and_draw)
|
||||||
{
|
{
|
||||||
|
atlas->ShadowRectIds[0] = atlas->AddCustomRect(effective_size, effective_size, &r);
|
||||||
|
IM_ASSERT(atlas->ShadowRectIds[0] != ImFontAtlasRectId_Invalid);
|
||||||
|
|
||||||
const int size = shadow_cfg->TexCornerSize + shadow_cfg->TexEdgeSize + shadow_cfg->TexCornerSize;
|
const int size = shadow_cfg->TexCornerSize + shadow_cfg->TexEdgeSize + shadow_cfg->TexCornerSize;
|
||||||
const int corner_size = shadow_cfg->TexCornerSize;
|
|
||||||
const int edge_size = shadow_cfg->TexEdgeSize;
|
|
||||||
|
|
||||||
// The bounds of the rectangle we are generating the shadow from
|
// The bounds of the rectangle we are generating the shadow from
|
||||||
const ImVec2 shadow_rect_min((float)corner_size, (float)corner_size);
|
const ImVec2 shadow_rect_min((float)corner_size, (float)corner_size);
|
||||||
const ImVec2 shadow_rect_max((float)(corner_size + edge_size), (float)(corner_size + edge_size));
|
const ImVec2 shadow_rect_max((float)(corner_size + edge_size), (float)(corner_size + edge_size));
|
||||||
|
|
||||||
// Remove the padding we added
|
// Remove the padding we added
|
||||||
ImFontAtlasRect r;
|
|
||||||
if (!atlas->GetCustomRect(atlas->ShadowRectIds[0], &r))
|
|
||||||
IM_ASSERT(0);
|
|
||||||
|
|
||||||
const int padding = shadow_cfg->GetRectTexPadding();
|
const int padding = shadow_cfg->GetRectTexPadding();
|
||||||
r.x += (unsigned short)padding;
|
r.x += (unsigned short)padding;
|
||||||
r.y += (unsigned short)padding;
|
r.y += (unsigned short)padding;
|
||||||
@@ -5069,8 +5058,19 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh UV coordinates
|
||||||
|
// Generate UVs for each of the nine sections, which are arranged in a 3x3 grid starting from 0 in the top-left and going across then down
|
||||||
|
if (atlas->GetCustomRect(atlas->ShadowRectIds[0], &r))
|
||||||
|
{
|
||||||
|
// Remove the padding we added
|
||||||
|
const int padding = shadow_cfg->GetRectTexPadding();
|
||||||
|
r.x += (unsigned short)padding;
|
||||||
|
r.y += (unsigned short)padding;
|
||||||
|
r.w -= (unsigned short)padding * 2;
|
||||||
|
r.h -= (unsigned short)padding * 2;
|
||||||
|
|
||||||
// Generate UVs for each of the nine sections, which are arranged in a 3x3 grid starting from 0 in the top-left and going across then down
|
|
||||||
for (int i = 0; i < 9; i++)
|
for (int i = 0; i < 9; i++)
|
||||||
{
|
{
|
||||||
// The third row/column of the 3x3 grid are generated by flipping the appropriate chunks of the upper 2x2 grid.
|
// The third row/column of the 3x3 grid are generated by flipping the appropriate chunks of the upper 2x2 grid.
|
||||||
@@ -5100,15 +5100,17 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The convex shape shadow texture
|
// The convex shape shadow texture
|
||||||
|
add_and_draw = (atlas->GetCustomRect(atlas->ShadowRectIds[1], &r) == false);
|
||||||
|
if (add_and_draw)
|
||||||
{
|
{
|
||||||
|
atlas->ShadowRectIds[1] = atlas->AddCustomRect(shadow_cfg->CalcConvexTexWidth() + shadow_cfg->GetConvexTexPadding(), shadow_cfg->CalcConvexTexHeight() + shadow_cfg->GetConvexTexPadding(), &r);
|
||||||
|
IM_ASSERT(atlas->ShadowRectIds[1] != ImFontAtlasRectId_Invalid);
|
||||||
|
|
||||||
const int size = shadow_cfg->TexCornerSize * 2;
|
const int size = shadow_cfg->TexCornerSize * 2;
|
||||||
const int padding = shadow_cfg->GetConvexTexPadding();
|
const int padding = shadow_cfg->GetConvexTexPadding();
|
||||||
|
|
||||||
// Generate distance field
|
// Generate distance field
|
||||||
// We draw the actual texture content by evaluating the distance field for the distance from a center point
|
// We draw the actual texture content by evaluating the distance field for the distance from a center point
|
||||||
ImFontAtlasRect r;
|
|
||||||
if (!atlas->GetCustomRect(atlas->ShadowRectIds[1], &r))
|
|
||||||
IM_ASSERT(0);
|
|
||||||
ImVec2 center_point(size * 0.5f, size * 0.5f);
|
ImVec2 center_point(size * 0.5f, size * 0.5f);
|
||||||
float* tex_data = (float*)alloca(size * size * sizeof(float));
|
float* tex_data = (float*)alloca(size * size * sizeof(float));
|
||||||
for (int y = 0; y < size; y++)
|
for (int y = 0; y < size; y++)
|
||||||
@@ -5158,15 +5160,20 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh UV coordinates
|
||||||
|
if (atlas->GetCustomRect(atlas->ShadowRectIds[1], &r))
|
||||||
|
{
|
||||||
// Remove the padding we added
|
// Remove the padding we added
|
||||||
|
const int padding = shadow_cfg->GetConvexTexPadding();
|
||||||
|
const int tex_width = shadow_cfg->CalcConvexTexWidth();
|
||||||
|
const int tex_height = shadow_cfg->CalcConvexTexHeight();
|
||||||
r.x += (unsigned short)padding;
|
r.x += (unsigned short)padding;
|
||||||
r.y += (unsigned short)padding;
|
r.y += (unsigned short)padding;
|
||||||
r.w = (unsigned short)(tex_width - (padding * 2));
|
r.w = (unsigned short)(tex_width - (padding * 2));
|
||||||
r.h = (unsigned short)(tex_height - (padding * 2));
|
r.h = (unsigned short)(tex_height - (padding * 2));
|
||||||
|
|
||||||
// Generate UVs
|
|
||||||
// FIXME-SHADOWS: caching UV !!
|
|
||||||
ImVec2 uv0 = ImVec2((float)(r.x), (float)(r.y)) * atlas->TexUvScale;
|
ImVec2 uv0 = ImVec2((float)(r.x), (float)(r.y)) * atlas->TexUvScale;
|
||||||
ImVec2 uv1 = ImVec2((float)(r.x + r.w), (float)(r.y + r.h)) * atlas->TexUvScale;
|
ImVec2 uv1 = ImVec2((float)(r.x + r.w), (float)(r.y + r.h)) * atlas->TexUvScale;
|
||||||
atlas->ShadowRectUvs[9] = ImVec4(uv0.x, uv0.y, uv1.x, uv1.y);
|
atlas->ShadowRectUvs[9] = ImVec4(uv0.x, uv0.y, uv1.x, uv1.y);
|
||||||
@@ -5207,8 +5214,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
|||||||
// Add required texture data
|
// Add required texture data
|
||||||
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
ImFontAtlasBuildUpdateLinesTexData(atlas);
|
||||||
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
ImFontAtlasBuildUpdateBasicTexData(atlas);
|
||||||
ImFontAtlasBuildRegisterShadowCustomRects(atlas); // FIXME-SHADOWS: Both may be merged now.
|
ImFontAtlasBuildUpdateShadowTexData(atlas);
|
||||||
ImFontAtlasBuildRenderShadowTexData(atlas); // FIXME-SHADOWS: Both may be merged now.
|
|
||||||
|
|
||||||
// Register fonts
|
// Register fonts
|
||||||
ImFontAtlasBuildUpdatePointers(atlas);
|
ImFontAtlasBuildUpdatePointers(atlas);
|
||||||
|
Reference in New Issue
Block a user