2
0
Эх сурвалжийг харах

Shadows: WIP fixes for latest. (broken UV caching)

ocornut 4 сар өмнө
parent
commit
82a7edea6b
2 өөрчлөгдсөн 73 нэмэгдсэн , 42 устгасан
  1. 1 1
      imgui.h
  2. 72 41
      imgui_draw.cpp

+ 1 - 1
imgui.h

@@ -3763,7 +3763,7 @@ struct ImFontAtlas
     ImGuiContext*               OwnerContext;       // Context which own the atlas will be in charge of updating and destroying it.
     ImGuiContext*               OwnerContext;       // Context which own the atlas will be in charge of updating and destroying it.
 
 
     // [Internal] Shadow data
     // [Internal] Shadow data
-    int                         ShadowRectIds[2];   // IDs of rect for shadow textures
+    ImFontAtlasRectId           ShadowRectIds[2];   // IDs of rect for shadow textures
     ImVec4                      ShadowRectUvs[10];  // UV coordinates for shadow textures, 9 for the rectangle shadows and the final entry for the convex shape shadows
     ImVec4                      ShadowRectUvs[10];  // UV coordinates for shadow textures, 9 for the rectangle shadows and the final entry for the convex shape shadows
     ImFontAtlasShadowTexConfig  ShadowTexConfig;    // Shadow texture baking config
     ImFontAtlasShadowTexConfig  ShadowTexConfig;    // Shadow texture baking config
 
 

+ 72 - 41
imgui_draw.cpp

@@ -2594,8 +2594,8 @@ void ImDrawList::AddShadowConvexPoly(const ImVec2* points, int points_count, ImU
 
 
     const ImVec4 uvs = _Data->ShadowRectUvs[9];
     const ImVec4 uvs = _Data->ShadowRectUvs[9];
 
 
-    int tex_width = _Data->Font->ContainerAtlas->TexWidth;
-    int tex_height = _Data->Font->ContainerAtlas->TexHeight;
+    int tex_width = _Data->Font->ContainerAtlas->TexData->Width;
+    int tex_height = _Data->Font->ContainerAtlas->TexData->Height;
     float inv_tex_width = 1.0f / (float)tex_width;
     float inv_tex_width = 1.0f / (float)tex_width;
     float inv_tex_height = 1.0f / (float)tex_height;
     float inv_tex_height = 1.0f / (float)tex_height;
 
 
@@ -4936,8 +4936,8 @@ static void ImFontAtlasBuildRegisterShadowCustomRects(ImFontAtlas* atlas)
     // The actual size we want to reserve, including padding
     // The actual size we want to reserve, including padding
     const ImFontAtlasShadowTexConfig* shadow_cfg = &atlas->ShadowTexConfig;
     const ImFontAtlasShadowTexConfig* shadow_cfg = &atlas->ShadowTexConfig;
     const unsigned int effective_size = shadow_cfg->CalcRectTexSize() + shadow_cfg->GetRectTexPadding();
     const unsigned int effective_size = shadow_cfg->CalcRectTexSize() + shadow_cfg->GetRectTexPadding();
-    atlas->ShadowRectIds[0] = atlas->AddCustomRectRegular(effective_size, effective_size);
-    atlas->ShadowRectIds[1] = atlas->AddCustomRectRegular(shadow_cfg->CalcConvexTexWidth() + shadow_cfg->GetConvexTexPadding(), shadow_cfg->CalcConvexTexHeight() + shadow_cfg->GetConvexTexPadding());
+    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
@@ -4999,8 +4999,8 @@ 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 ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
 {
 {
-    IM_ASSERT(atlas->TexPixelsAlpha8 != NULL || atlas->TexPixelsRGBA32 != NULL);
-    IM_ASSERT(atlas->ShadowRectIds[0] >= 0 && atlas->ShadowRectIds[1] >= 0);
+    IM_ASSERT(atlas->TexData && atlas->TexData->Pixels != NULL);
+    IM_ASSERT(atlas->ShadowRectIds[0] != ImFontAtlasRectId_Invalid && atlas->ShadowRectIds[1] != ImFontAtlasRectId_Invalid);
 
 
     // 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.
@@ -5017,12 +5017,15 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
         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
-        ImFontAtlasCustomRect r = atlas->CustomRects[atlas->ShadowRectIds[0]];
+        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.Y += (unsigned short)padding;
-        r.Width -= (unsigned short)padding * 2;
-        r.Height -= (unsigned short)padding * 2;
+        r.x += (unsigned short)padding;
+        r.y += (unsigned short)padding;
+        r.w -= (unsigned short)padding * 2;
+        r.h -= (unsigned short)padding * 2;
 
 
         // Generate distance field
         // Generate distance field
         // We draw the actual texture content by evaluating the distance field for the inner rectangle
         // We draw the actual texture content by evaluating the distance field for the inner rectangle
@@ -5041,18 +5044,30 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
             GaussianBlur(tex_data, size);
             GaussianBlur(tex_data, size);
 
 
         // Copy to texture, truncating to the actual required texture size (the bottom/right of the source data is chopped off, as we don't need it - see below). The truncated size is essentially the top 2x2 of our data, plus a little bit of padding for sampling.
         // Copy to texture, truncating to the actual required texture size (the bottom/right of the source data is chopped off, as we don't need it - see below). The truncated size is essentially the top 2x2 of our data, plus a little bit of padding for sampling.
-        const int tex_w = atlas->TexWidth;
+        ImTextureData* tex = atlas->TexData;
         const int shadow_tex_size = shadow_cfg->CalcRectTexSize();
         const int shadow_tex_size = shadow_cfg->CalcRectTexSize();
         for (int y = 0; y < shadow_tex_size; y++)
         for (int y = 0; y < shadow_tex_size; y++)
             for (int x = 0; x < shadow_tex_size; x++)
             for (int x = 0; x < shadow_tex_size; x++)
             {
             {
-                const unsigned int offset = (int)(r.X + x) + (int)(r.Y + y) * tex_w;
                 const float alpha_f = tex_data[x + (y * size)];
                 const float alpha_f = tex_data[x + (y * size)];
                 const unsigned char alpha_8 = (unsigned char)(0xFF * alpha_f);
                 const unsigned char alpha_8 = (unsigned char)(0xFF * alpha_f);
-                if (atlas->TexPixelsAlpha8)
-                    atlas->TexPixelsAlpha8[offset] = alpha_8;
-                else
-                    atlas->TexPixelsRGBA32[offset] = IM_COL32(255, 255, 255, alpha_8);
+
+                // FIXME-SHADOWS: May be optimized.
+                switch (atlas->TexData->Format)
+                {
+                case ImTextureFormat_Alpha8:
+                {
+                    ImU8* out_p = (ImU8*)(void*)tex->GetPixelsAt(r.x + x, r.y + y);
+                    *out_p = alpha_8;
+                    break;
+                }
+                case ImTextureFormat_RGBA32:
+                {
+                    ImU32* out_p = (ImU32*)(void*)tex->GetPixelsAt(r.x + x, r.y + y);
+                    *out_p = IM_COL32(255, 255, 255, alpha_8);;
+                    break;
+                }
+                }
             }
             }
 
 
         // 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
         // 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
@@ -5062,23 +5077,24 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
             bool flip_h = false; // Do we need to flip the UVs horizontally?
             bool flip_h = false; // Do we need to flip the UVs horizontally?
             bool flip_v = false; // Do we need to flip the UVs vertically?
             bool flip_v = false; // Do we need to flip the UVs vertically?
 
 
-            ImFontAtlasCustomRect sub_rect = r;
+            ImFontAtlasRect sub_rect = r;
             switch (i % 3)
             switch (i % 3)
             {
             {
-            case 0: sub_rect.Width = (unsigned short)corner_size; break;
-            case 1: sub_rect.X    += (unsigned short)corner_size; sub_rect.Width = (unsigned short)edge_size; break;
-            case 2: sub_rect.Width = (unsigned short)corner_size; flip_h = true; break;
+            case 0: sub_rect.w = (unsigned short)corner_size; break;
+            case 1: sub_rect.x += (unsigned short)corner_size; sub_rect.w = (unsigned short)edge_size; break;
+            case 2: sub_rect.w = (unsigned short)corner_size; flip_h = true; break;
             }
             }
 
 
             switch (i / 3)
             switch (i / 3)
             {
             {
-            case 0: sub_rect.Height = (unsigned short)corner_size; break;
-            case 1: sub_rect.Y     += (unsigned short)corner_size; sub_rect.Height = (unsigned short)edge_size; break;
-            case 2: sub_rect.Height = (unsigned short)corner_size; flip_v = true; break;
+            case 0: sub_rect.h = (unsigned short)corner_size; break;
+            case 1: sub_rect.y += (unsigned short)corner_size; sub_rect.h = (unsigned short)edge_size; break;
+            case 2: sub_rect.h = (unsigned short)corner_size; flip_v = true; break;
             }
             }
 
 
-            ImVec2 uv0, uv1;
-            atlas->CalcCustomRectUV(&sub_rect, &uv0, &uv1);
+            // FIXME-SHADOWS: caching UV !!
+            ImVec2 uv0 = ImVec2((float)(sub_rect.x), (float)(sub_rect.y)) * atlas->TexUvScale;
+            ImVec2 uv1 = ImVec2((float)(sub_rect.x + sub_rect.w), (float)(sub_rect.y + sub_rect.h)) * atlas->TexUvScale;
             atlas->ShadowRectUvs[i] = ImVec4(flip_h ? uv1.x : uv0.x, flip_v ? uv1.y : uv0.y, flip_h ? uv0.x : uv1.x, flip_v ? uv0.y : uv1.y);
             atlas->ShadowRectUvs[i] = ImVec4(flip_h ? uv1.x : uv0.x, flip_v ? uv1.y : uv0.y, flip_h ? uv0.x : uv1.x, flip_v ? uv0.y : uv1.y);
         }
         }
     }
     }
@@ -5090,7 +5106,9 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
 
 
         // 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
-        ImFontAtlasCustomRect r = atlas->CustomRects[atlas->ShadowRectIds[1]];
+        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++)
@@ -5114,7 +5132,7 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
 
 
         const int tex_width = shadow_cfg->CalcConvexTexWidth();
         const int tex_width = shadow_cfg->CalcConvexTexWidth();
         const int tex_height = shadow_cfg->CalcConvexTexHeight();
         const int tex_height = shadow_cfg->CalcConvexTexHeight();
-        const int tex_w = atlas->TexWidth;
+        ImTextureData* tex = atlas->TexData;
         for (int y = 0; y < tex_height; y++)
         for (int y = 0; y < tex_height; y++)
             for (int x = 0; x < tex_width; x++)
             for (int x = 0; x < tex_width; x++)
             {
             {
@@ -5122,22 +5140,35 @@ static void ImFontAtlasBuildRenderShadowTexData(ImFontAtlas* atlas)
                 const int src_y = ImClamp(y - src_y_offset, 0, size - 1);
                 const int src_y = ImClamp(y - src_y_offset, 0, size - 1);
                 const float alpha_f = tex_data[src_x + (src_y * size)];
                 const float alpha_f = tex_data[src_x + (src_y * size)];
                 const unsigned char alpha_8 = (unsigned char)(0xFF * alpha_f);
                 const unsigned char alpha_8 = (unsigned char)(0xFF * alpha_f);
-                const unsigned int offset = (int)(r.X + x) + (int)(r.Y + y) * tex_w;
-                if (atlas->TexPixelsAlpha8)
-                    atlas->TexPixelsAlpha8[offset] = alpha_8;
-                else
-                    atlas->TexPixelsRGBA32[offset] = IM_COL32(255, 255, 255, alpha_8);
+
+                // FIXME-SHADOWS: May be optimized.
+                switch (atlas->TexData->Format)
+                {
+                case ImTextureFormat_Alpha8:
+                {
+                    ImU8* out_p = (ImU8*)(void*)tex->GetPixelsAt(r.x + x, r.y + y);
+                    *out_p = alpha_8;
+                    break;
+                }
+                case ImTextureFormat_RGBA32:
+                {
+                    ImU32* out_p = (ImU32*)(void*)tex->GetPixelsAt(r.x + x, r.y + y);
+                    *out_p = IM_COL32(255, 255, 255, alpha_8);;
+                    break;
+                }
+                }
             }
             }
 
 
         // Remove the padding we added
         // Remove the padding we added
-        r.X += (unsigned short)padding;
-        r.Y += (unsigned short)padding;
-        r.Width = (unsigned short)(tex_width - (padding * 2));
-        r.Height = (unsigned short)(tex_height - (padding * 2));
+        r.x += (unsigned short)padding;
+        r.y += (unsigned short)padding;
+        r.w = (unsigned short)(tex_width - (padding * 2));
+        r.h = (unsigned short)(tex_height - (padding * 2));
 
 
         // Generate UVs
         // Generate UVs
-        ImVec2 uv0, uv1;
-        atlas->CalcCustomRectUV(&r, &uv0, &uv1);
+        // FIXME-SHADOWS: caching UV !!
+        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;
         atlas->ShadowRectUvs[9] = ImVec4(uv0.x, uv0.y, uv1.x, uv1.y);
         atlas->ShadowRectUvs[9] = ImVec4(uv0.x, uv0.y, uv1.x, uv1.y);
     }
     }
 }
 }
@@ -5176,8 +5207,8 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
     // Add required texture data
     // Add required texture data
     ImFontAtlasBuildUpdateLinesTexData(atlas);
     ImFontAtlasBuildUpdateLinesTexData(atlas);
     ImFontAtlasBuildUpdateBasicTexData(atlas);
     ImFontAtlasBuildUpdateBasicTexData(atlas);
-    ImFontAtlasBuildRegisterShadowCustomRects(atlas); // FIXME-SHADOWS
-    ImFontAtlasBuildRenderShadowTexData(atlas); // FIXME-SHADOWS
+    ImFontAtlasBuildRegisterShadowCustomRects(atlas); // FIXME-SHADOWS: Both may be merged now.
+    ImFontAtlasBuildRenderShadowTexData(atlas); // FIXME-SHADOWS: Both may be merged now.
 
 
     // Register fonts
     // Register fonts
     ImFontAtlasBuildUpdatePointers(atlas);
     ImFontAtlasBuildUpdatePointers(atlas);