cache atlasses on demand

This commit is contained in:
jrkb 2023-04-08 17:15:20 +02:00
parent 244abc777a
commit 903b03b6c3
2 changed files with 74 additions and 30 deletions

View file

@ -1,7 +1,9 @@
#include "Atlas.h" #include "Atlas.h"
#include "GlyphGeometry.h"
#include "conversion.h" #include "conversion.h"
#include "edge-coloring.h" #include "edge-coloring.h"
#include "import-font.h" #include "import-font.h"
#include "ofFileUtils.h"
namespace ofxMsdfgen { namespace ofxMsdfgen {
@ -122,10 +124,20 @@ void Atlas::addVariations(vector <FontVariation> variations){
} }
} }
bool Atlas::generate(){ bool Atlas::generate(bool useCache,
bool saveToCache){
cout << "Atlas::generate()" << endl; cout << "Atlas::generate()" << endl;
bool success = false; bool success = false;
//{ bool foundAtlasCacheImage = false;
if(useCache){
ofFile atlasPathFile(getAtlasPath());
if(atlasPathFile.isFile()){
foundAtlasCacheImage = true;
if(atlasImage.load(getAtlasPath())){
foundAtlasCacheImage = true;
}
}
}
if(ft){ if(ft){
if(font){ if(font){
// Storage for glyph geometry and their coordinates in the atlas // Storage for glyph geometry and their coordinates in the atlas
@ -208,34 +220,44 @@ bool Atlas::generate(){
packer.setMiterLimit(settings.miterLimit); packer.setMiterLimit(settings.miterLimit);
// Compute atlas layout - pack glyphs // Compute atlas layout - pack glyphs
packer.pack(glyphs.data(), glyphs.size()); packer.pack(glyphs.data(), glyphs.size());
// Get final atlas dimensions if(!useCache || !foundAtlasCacheImage){
int width = 0, height = 0; // Get final atlas dimensions
packer.getDimensions(width, height); int width = 0, height = 0;
// The ImmediateAtlasGenerator class facilitates the generation of the atlas bitmap. packer.getDimensions(width, height);
msdf_atlas::ImmediateAtlasGenerator < // The ImmediateAtlasGenerator class facilitates the generation of the atlas bitmap.
float, // pixel type of buffer for individual glyphs depends on generator function msdf_atlas::ImmediateAtlasGenerator <
3, // number of atlas color channels float, // pixel type of buffer for individual glyphs depends on generator function
& msdf_atlas::msdfGenerator, // function to generate bitmaps for individual glyphs 3, // number of atlas color channels
msdf_atlas::BitmapAtlasStorage <float, 3> // class that stores the atlas bitmap & msdf_atlas::msdfGenerator, // function to generate bitmaps for individual glyphs
// For example, a custom atlas storage class that stores it in VRAM can be used. msdf_atlas::BitmapAtlasStorage <float, 3> // class that stores the atlas bitmap
> generator(width, height); // For example, a custom atlas storage class that stores it in VRAM can be used.
// GeneratorAttributes can be modified to change the generator's default settings. > generator(width, height);
msdf_atlas::GeneratorAttributes attributes; // GeneratorAttributes can be modified to change the generator's default settings.
generator.setAttributes(attributes); msdf_atlas::GeneratorAttributes attributes;
generator.setThreadCount(settings.threadCount); generator.setAttributes(attributes);
// Generate atlas bitmap generator.setThreadCount(settings.threadCount);
generator.generate(glyphs.data(), glyphs.size()); // Generate atlas bitmap
// The atlas bitmap can now be retrieved via atlasStorage as a BitmapConstRef. generator.generate(glyphs.data(), glyphs.size());
// The glyphs array (or fontGeometry) contains positioning data for typesetting text. // The atlas bitmap can now be retrieved via atlasStorage as a BitmapConstRef.
msdfgen::Bitmap <float, 3> bitmap(generator.atlasStorage()); // The glyphs array (or fontGeometry) contains positioning data for typesetting text.
toOfImage(bitmap, atlasImage); msdfgen::Bitmap <float, 3> bitmap(generator.atlasStorage());
atlasImage.update(); toOfImage(bitmap, atlasImage);
atlasImage.update();
if(saveToCache){
ofDirectory dir(getAtlasPathDir());
dir.create();
atlasImage.save(getAtlasPath());
}
}
std::vector <msdf_atlas::GlyphBox> layout = generator.getLayout(); //std::vector <msdf_atlas::GlyphBox> layout = generator.getLayout();
int i = 0; //int i = 0;
for(const msdf_atlas::GlyphBox & gb : layout){ //for(const msdf_atlas::GlyphBox & gb : layout){
msdf_atlas::GlyphGeometry gg = glyphs[i]; //msdf_atlas::GlyphGeometry gg = glyphs[i];
i++; //i++;
//glyphGeometries.push_back(gg);
//}
for(const msdf_atlas::GlyphGeometry & gg : glyphs){
glyphGeometries.push_back(gg); glyphGeometries.push_back(gg);
} }
// Cleanup // Cleanup
@ -345,4 +367,23 @@ const FontGeometry & Atlas::getFontGeometry(){
const vector <ofxMsdfgen::FontVariationAxis> & Atlas::getVariationAxesAvailable(){ const vector <ofxMsdfgen::FontVariationAxis> & Atlas::getVariationAxesAvailable(){
return variationAxesAvailable; return variationAxesAvailable;
} }
// private
string Atlas::getAtlasPathDir(){
string fontPathNoData = fontPath;
ofStringReplace(fontPathNoData, "data/", "");
string atlasPath = "data/atlascache/" + fontPathNoData;
return atlasPath;
}
string Atlas::getAtlasPath(){
string atlasPath = getAtlasPathDir() + "/"
+ ofToString(settings.scale) + "_"
+ ofToString(settings.minimumScale) + "_"
+ ofToString(settings.maxInterpolationStepSize);
for(auto & ve : variationExtremes){
atlasPath += ve.name + "_" + ofToString(ve.value) + "_";
}
atlasPath += ".png";
return atlasPath;
}
} }

View file

@ -87,7 +87,8 @@ class Atlas {
void setup(string _fontPath); void setup(string _fontPath);
void setup(string _fontPath, AtlasSettings _settings); void setup(string _fontPath, AtlasSettings _settings);
void addVariations(vector <FontVariation> variations); void addVariations(vector <FontVariation> variations);
bool generate(); bool generate(bool useCache = true,
bool saveToCache = false);
const ofImage & getAtlasImage(); const ofImage & getAtlasImage();
const vector <GlyphGeometry> & getGlyphGeometries(); const vector <GlyphGeometry> & getGlyphGeometries();
const GlyphGeometry & getGlyphGeometry(unsigned char character); const GlyphGeometry & getGlyphGeometry(unsigned char character);
@ -106,6 +107,8 @@ class Atlas {
msdfgen::FontHandle * font; msdfgen::FontHandle * font;
msdfgen::FreetypeHandle * ft; msdfgen::FreetypeHandle * ft;
private: private:
string getAtlasPathDir();
string getAtlasPath();
string fontPath; string fontPath;
ofImage atlasImage; ofImage atlasImage;
vector <GlyphGeometry> glyphGeometries; vector <GlyphGeometry> glyphGeometries;