@@ -18,49 +18,71 @@ namespace ext
18
18
namespace TextRendering
19
19
{
20
20
21
- core::smart_refctd_ptr<ICPUImage> TextRenderer::generateShapeMSDF (msdfgen::Shape glyph, uint32_t msdfPixelRange, uint32_t2 msdfExtents, uint32_t msdfMipLevels, float32_t2 scale, float32_t2 translate)
21
+ // TODO find an alternative for this (we need it because msdfgen consumes the glyphs when doing generateMSDF)
22
+ msdfgen::Shape deepCloneShape (const msdfgen::Shape& original) {
23
+ msdfgen::Shape copy;
24
+ for (uint32_t contour = 0 ; contour < original.contours .size (); contour++)
25
+ {
26
+ msdfgen::Contour c;
27
+ auto originalEdges = original.contours [contour].edges ;
28
+ c.edges .reserve (originalEdges.size ());
29
+
30
+ for (uint32_t edge = 0 ; edge < originalEdges.size (); edge++)
31
+ {
32
+ auto segment = msdfgen::EdgeHolder ();
33
+ segment = originalEdges[edge];
34
+ c.edges .push_back (segment);
35
+ }
36
+
37
+ copy.contours .push_back (c);
38
+ }
39
+ return copy;
40
+ }
41
+
42
+ core::smart_refctd_ptr<ICPUBuffer> TextRenderer::generateShapeMSDF (msdfgen::Shape glyph, uint32_t msdfPixelRange, uint32_t2 msdfExtents, uint32_t msdfMipLevels, float32_t2 scale, float32_t2 translate)
22
43
{
23
44
uint32_t glyphW = msdfExtents.x ;
24
45
uint32_t glyphH = msdfExtents.y ;
25
46
26
- auto shapeBounds = glyph.getBounds ();
47
+ uint32_t size = 0 ;
48
+ auto cpuBuf = core::make_smart_refctd_ptr<ICPUBuffer>(size);
49
+ int8_t * data = reinterpret_cast <int8_t *>(cpuBuf->getPointer ());
50
+
51
+ auto floatToSNORM8 = [](const float fl) -> int8_t
52
+ {
53
+ // we need to invert values because msdfgen assigns positive values for shape interior which is the exact opposite of our convention
54
+ return -1 * (int8_t )(std::clamp (fl * 2 .0f - 1 .0f , -1 .0f , 1 .0f ) * 127 .f );
55
+ };
27
56
28
57
msdfgen::edgeColoringSimple (glyph, 3.0 );
29
- msdfgen::Bitmap<float , 4 > msdfMap (glyphW, glyphH);
30
58
31
- msdfgen::generateMTSDF (msdfMap, glyph, msdfPixelRange, { scale.x , scale.y }, { translate.x , translate.y });
59
+ for (uint32_t mip = 0 ; mip < msdfMipLevels; mip++)
60
+ {
61
+ msdfgen::Shape glyphCopy = deepCloneShape (glyph);
62
+ uint32_t mipW = glyphW / (1 << mip);
63
+ uint32_t mipH = glyphH / (1 << mip);
32
64
65
+ auto shapeBounds = glyphCopy.getBounds ();
33
66
34
- asset::ICPUImage::SCreationParams creationParams;
35
- creationParams.type = asset::IImage::ET_2D;
36
- creationParams.samples = asset::IImage::ESCF_1_BIT;
37
- creationParams.format = TextRenderer::MSDFTextureFormat;
38
- creationParams.extent = { msdfExtents.x , msdfExtents.y , 1 };
39
- creationParams.mipLevels = msdfMipLevels;
40
- creationParams.arrayLayers = 1 ;
41
- auto image = asset::ICPUImage::create (std::move (creationParams));
67
+ msdfgen::Bitmap<float , 4 > msdfMap (mipW, mipH);
42
68
43
- int8_t * data = reinterpret_cast <int8_t *>(image->getBuffer ()->getPointer ());
44
-
45
- auto floatToSNORM8 = [](const float fl) -> int8_t
46
- {
47
- // we need to invert values because msdfgen assigns positive values for shape interior which is the exact opposite of our convention
48
- return -1 * (int8_t )(std::clamp (fl * 2 .0f - 1 .0f , -1 .0f , 1 .0f ) * 127 .f );
49
- };
69
+ msdfgen::generateMTSDF (msdfMap, glyphCopy, msdfPixelRange, { scale.x , scale.y }, { translate.x , translate.y });
50
70
51
- for (int y = 0 ; y < msdfMap.height (); ++y)
52
- {
53
- for (int x = 0 ; x < msdfMap.width (); ++x)
71
+ for (int y = 0 ; y < mipW; ++y)
54
72
{
55
- auto pixel = msdfMap (x, glyphH - 1 - y);
56
- data[(x + y * glyphW) * 4 + 0 ] = floatToSNORM8 (pixel[0 ]);
57
- data[(x + y * glyphW) * 4 + 1 ] = floatToSNORM8 (pixel[1 ]);
58
- data[(x + y * glyphW) * 4 + 2 ] = floatToSNORM8 (pixel[2 ]);
59
- data[(x + y * glyphW) * 4 + 3 ] = floatToSNORM8 (pixel[3 ]);
73
+ for (int x = 0 ; x < mipH; ++x)
74
+ {
75
+ auto pixel = msdfMap (x, mipH - 1 - y);
76
+ data[(x + y * mipW) * 4 + 0 ] = floatToSNORM8 (pixel[0 ]);
77
+ data[(x + y * mipW) * 4 + 1 ] = floatToSNORM8 (pixel[1 ]);
78
+ data[(x + y * mipW) * 4 + 2 ] = floatToSNORM8 (pixel[2 ]);
79
+ data[(x + y * mipW) * 4 + 3 ] = floatToSNORM8 (pixel[3 ]);
80
+ }
60
81
}
82
+ data += mipW * mipH * 4 ;
61
83
}
62
84
63
- return std::move (image );
85
+ return std::move (cpuBuf );
64
86
}
65
87
66
88
constexpr double FreeTypeFontScaling = 1.0 / 64.0 ;
@@ -76,7 +98,7 @@ FontFace::GlyphMetrics FontFace::getGlyphMetricss(uint32_t glyphId)
76
98
};
77
99
}
78
100
79
- core::smart_refctd_ptr<ICPUImage > FontFace::generateGlyphMSDF (uint32_t msdfPixelRange, uint32_t glyphId, uint32_t2 textureExtents, uint32_t mipLevels)
101
+ core::smart_refctd_ptr<ICPUBuffer > FontFace::generateGlyphMSDF (uint32_t msdfPixelRange, uint32_t glyphId, uint32_t2 textureExtents, uint32_t mipLevels)
80
102
{
81
103
auto shape = generateGlyphShape (glyphId);
82
104
0 commit comments