mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Atlas build use GetCustomRectByIndex() + comments, rename, and shallow merge from tex_antialiasing_lines branch.
This commit is contained in:
		
							
								
								
									
										101
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							| @@ -666,11 +666,9 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|         return; | ||||
|  | ||||
|     const ImVec2 opaque_uv = _Data->TexUvWhitePixel; | ||||
|     int count = points_count; | ||||
|     if (!closed) | ||||
|         count = points_count - 1; | ||||
|  | ||||
|     const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw | ||||
|     const bool thick_line = (thickness > 1.0f); | ||||
|  | ||||
|     if (Flags & ImDrawListFlags_AntiAliasedLines) | ||||
|     { | ||||
|         // Anti-aliased stroke | ||||
| @@ -682,9 +680,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|         PrimReserve(idx_count, vtx_count); | ||||
|  | ||||
|         // Temporary buffer | ||||
|         // The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point | ||||
|         ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); //-V630 | ||||
|         ImVec2* temp_points = temp_normals + points_count; | ||||
|  | ||||
|         // Calculate normals (tangents) for each line segment | ||||
|         for (int i1 = 0; i1 < count; i1++) | ||||
|         { | ||||
|             const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; | ||||
| @@ -707,12 +707,14 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|                 temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * AA_SIZE; | ||||
|             } | ||||
|  | ||||
|             // Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges | ||||
|             // This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps) | ||||
|             // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. | ||||
|             unsigned int idx1 = _VtxCurrentIdx; | ||||
|             for (int i1 = 0; i1 < count; i1++) | ||||
|             unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment | ||||
|             for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment | ||||
|             { | ||||
|                 const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; | ||||
|                 unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : idx1 + 3; | ||||
|                 const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : idx1 + 3; | ||||
|  | ||||
|                 // Average normals | ||||
|                 float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; | ||||
| @@ -721,14 +723,14 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|                 dm_x *= AA_SIZE; | ||||
|                 dm_y *= AA_SIZE; | ||||
|  | ||||
|                 // Add temporary vertices | ||||
|                 // Add temporary vertexes for the outer edges | ||||
|                 ImVec2* out_vtx = &temp_points[i2 * 2]; | ||||
|                 out_vtx[0].x = points[i2].x + dm_x; | ||||
|                 out_vtx[0].y = points[i2].y + dm_y; | ||||
|                 out_vtx[1].x = points[i2].x - dm_x; | ||||
|                 out_vtx[1].y = points[i2].y - dm_y; | ||||
|  | ||||
|                 // Add indexes | ||||
|                 // Add indexes for four triangles | ||||
|                 _IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); | ||||
|                 _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+0); | ||||
|                 _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); | ||||
| @@ -738,7 +740,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|                 idx1 = idx2; | ||||
|             } | ||||
|  | ||||
|             // Add vertices | ||||
|             // Add vertexes for each point on the line | ||||
|             for (int i = 0; i < points_count; i++) | ||||
|             { | ||||
|                 _VtxWritePtr[0].pos = points[i];          _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; | ||||
| @@ -749,7 +751,10 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Non texture-based lines (thick): we need to draw the solid line core and thus require four vertices per point | ||||
|             const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; | ||||
|  | ||||
|             // If line is not closed, the first and last points need to be generated differently as there are no normals to blend | ||||
|             if (!closed) | ||||
|             { | ||||
|                 const int points_last = points_count - 1; | ||||
| @@ -763,9 +768,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|                 temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE); | ||||
|             } | ||||
|  | ||||
|             // Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges | ||||
|             // This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps) | ||||
|             // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. | ||||
|             unsigned int idx1 = _VtxCurrentIdx; | ||||
|             for (int i1 = 0; i1 < count; i1++) | ||||
|             unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment | ||||
|             for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment | ||||
|             { | ||||
|                 const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment | ||||
|                 const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment | ||||
| @@ -816,7 +823,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Non Anti-aliased Stroke | ||||
|         // Non texture-based, Non anti-aliased lines | ||||
|         const int idx_count = count * 6; | ||||
|         const int vtx_count = count * 4;    // FIXME-OPT: Not sharing edges | ||||
|         PrimReserve(idx_count, vtx_count); | ||||
| @@ -1656,8 +1663,7 @@ ImFontAtlas::ImFontAtlas() | ||||
|     TexWidth = TexHeight = 0; | ||||
|     TexUvScale = ImVec2(0.0f, 0.0f); | ||||
|     TexUvWhitePixel = ImVec2(0.0f, 0.0f); | ||||
|     for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) | ||||
|         CustomRectIds[n] = -1; | ||||
|     PackIdMouseCursors = -1; | ||||
| } | ||||
|  | ||||
| ImFontAtlas::~ImFontAtlas() | ||||
| @@ -1685,8 +1691,7 @@ void    ImFontAtlas::ClearInputData() | ||||
|         } | ||||
|     ConfigData.clear(); | ||||
|     CustomRects.clear(); | ||||
|     for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) | ||||
|         CustomRectIds[n] = -1; | ||||
|     PackIdMouseCursors = -1; | ||||
| } | ||||
|  | ||||
| void    ImFontAtlas::ClearTexData() | ||||
| @@ -1926,9 +1931,9 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou | ||||
|     if (Flags & ImFontAtlasFlags_NoMouseCursors) | ||||
|         return false; | ||||
|  | ||||
|     IM_ASSERT(CustomRectIds[0] != -1); | ||||
|     ImFontAtlasCustomRect& r = CustomRects[CustomRectIds[0]]; | ||||
|     ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); | ||||
|     IM_ASSERT(PackIdMouseCursors != -1); | ||||
|     ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors); | ||||
|     ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y); | ||||
|     ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; | ||||
|     *out_size = size; | ||||
|     *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; | ||||
| @@ -2256,17 +2261,6 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| // Register default custom rectangles (this is called/shared by both the stb_truetype and the FreeType builder) | ||||
| void ImFontAtlasBuildInit(ImFontAtlas* atlas) | ||||
| { | ||||
|     if (atlas->CustomRectIds[0] >= 0) | ||||
|         return; | ||||
|     if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) | ||||
|         atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H); | ||||
|     else | ||||
|         atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(2, 2); | ||||
| } | ||||
|  | ||||
| void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) | ||||
| { | ||||
|     if (!font_config->MergeMode) | ||||
| @@ -2310,20 +2304,18 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa | ||||
|  | ||||
| static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) | ||||
| { | ||||
|     IM_ASSERT(atlas->CustomRectIds[0] >= 0); | ||||
|     IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); | ||||
|     ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; | ||||
|     IM_ASSERT(r.IsPacked()); | ||||
|     ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors); | ||||
|     IM_ASSERT(r->IsPacked()); | ||||
|  | ||||
|     const int w = atlas->TexWidth; | ||||
|     if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) | ||||
|     { | ||||
|         // Render/copy pixels | ||||
|         IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); | ||||
|         IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); | ||||
|         for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) | ||||
|             for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) | ||||
|             { | ||||
|                 const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w; | ||||
|                 const int offset0 = (int)(r->X + x) + (int)(r->Y + y) * w; | ||||
|                 const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; | ||||
|                 atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; | ||||
|                 atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; | ||||
| @@ -2331,29 +2323,46 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         IM_ASSERT(r.Width == 2 && r.Height == 2); | ||||
|         const int offset = (int)(r.X) + (int)(r.Y) * w; | ||||
|         // Render 4 white pixels | ||||
|         IM_ASSERT(r->Width == 2 && r->Height == 2); | ||||
|         const int offset = (int)r->X + (int)r->Y * w; | ||||
|         atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; | ||||
|     } | ||||
|     atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); | ||||
|     atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y); | ||||
| } | ||||
|  | ||||
|  | ||||
| // Note: this is called / shared by both the stb_truetype and the FreeType builder | ||||
| void ImFontAtlasBuildInit(ImFontAtlas* atlas) | ||||
| { | ||||
|     // Register texture region for mouse cursors or standard white pixels | ||||
|     if (atlas->PackIdMouseCursors < 0) | ||||
|     { | ||||
|         if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) | ||||
|             atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H); | ||||
|         else | ||||
|             atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // This is called/shared by both the stb_truetype and the FreeType builder. | ||||
| void ImFontAtlasBuildFinish(ImFontAtlas* atlas) | ||||
| { | ||||
|     // Render into our custom data block | ||||
|     // Render into our custom data blocks | ||||
|     IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); | ||||
|     ImFontAtlasBuildRenderDefaultTexData(atlas); | ||||
|  | ||||
|     // Register custom rectangle glyphs | ||||
|     for (int i = 0; i < atlas->CustomRects.Size; i++) | ||||
|     { | ||||
|         const ImFontAtlasCustomRect& r = atlas->CustomRects[i]; | ||||
|         if (r.Font == NULL || r.GlyphID == 0) | ||||
|         const ImFontAtlasCustomRect* r = &atlas->CustomRects[i]; | ||||
|         if (r->Font == NULL || r->GlyphID == 0) | ||||
|             continue; | ||||
|  | ||||
|         IM_ASSERT(r.Font->ContainerAtlas == atlas); | ||||
|         IM_ASSERT(r->Font->ContainerAtlas == atlas); | ||||
|         ImVec2 uv0, uv1; | ||||
|         atlas->CalcCustomRectUV(&r, &uv0, &uv1); | ||||
|         r.Font->AddGlyph((ImWchar)r.GlyphID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); | ||||
|         atlas->CalcCustomRectUV(r, &uv0, &uv1); | ||||
|         r->Font->AddGlyph((ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX); | ||||
|     } | ||||
|  | ||||
|     // Build all fonts lookup tables | ||||
|   | ||||
		Reference in New Issue
	
	Block a user