GPUFont with layers
This commit is contained in:
parent
dce5e7c57a
commit
70eb4f97f4
8 changed files with 236 additions and 109 deletions
|
@ -19,6 +19,9 @@
|
|||
|
||||
namespace ofxVariableLab {
|
||||
|
||||
struct AtlasLayerComboSettings {
|
||||
};
|
||||
|
||||
struct ComboIdentifier {
|
||||
std::string fontPath = "data/celines-fonts/Version-2-var.ttf";
|
||||
Layer::Type type = Layer::MSDFGEN;
|
||||
|
@ -31,9 +34,11 @@ struct ComboIdentifier {
|
|||
|
||||
class AtlasLayerCombo {
|
||||
public:
|
||||
virtual void setup(const ComboIdentifier & identifier) = 0;
|
||||
virtual void setup(const ComboIdentifier & identifier,
|
||||
AtlasLayerComboSettings settings) = 0;
|
||||
virtual void update() = 0;
|
||||
virtual void careForChild(shared_ptr <Layer> layer) = 0;
|
||||
virtual void abandonChild(shared_ptr <Layer> layer) = 0;
|
||||
virtual const ComboIdentifier & getIdentifier() const = 0;
|
||||
virtual void setVFlip(VFlipState vFlipState) = 0;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "GPUFontAtlasLayerCombo.h"
|
||||
#include "Utils.h"
|
||||
#include "font.hpp"
|
||||
#include "ofColor.h"
|
||||
#include "ofEvents.h"
|
||||
#include "ofGraphics.h"
|
||||
|
@ -7,8 +8,10 @@
|
|||
|
||||
namespace ofxVariableLab {
|
||||
|
||||
void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier){
|
||||
void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier,
|
||||
AtlasLayerComboSettings settings){
|
||||
this->identifier = identifier;
|
||||
this->settings = static_cast <GPUFontAtlasLayerComboSettings &>(settings);
|
||||
#ifdef TARGET_EMSCRIPTEN
|
||||
string shaderDir = "data/ofxGPUFont/shaders/DEBUG_ES3";
|
||||
#else
|
||||
|
@ -25,16 +28,14 @@ void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier){
|
|||
ofExit();
|
||||
}
|
||||
}
|
||||
currentFontPath = "data/celines-fonts/Version-2-var.ttf";
|
||||
mainText = "whatever";
|
||||
ofxGPUFont::tryUpdateMainFont(library,
|
||||
currentFontPath,
|
||||
this->identifier.fontPath,
|
||||
mainText,
|
||||
font,
|
||||
bb);
|
||||
this->settings.gpuTextureOffset);
|
||||
|
||||
font->listFontVariationAxes(fontVariationAxesParameters, library);
|
||||
cout << currentFontPath << " : fontVariationAxes :" << endl;
|
||||
cout << this->identifier.fontPath << " : fontVariationAxes :" << endl;
|
||||
for(const auto & axis : fontVariationAxesParameters){
|
||||
cout << std::fixed << std::setprecision(10) << axis.name << " :\n"
|
||||
<< "\tmin: " << std::to_string(axis.minValue)
|
||||
|
@ -49,29 +50,76 @@ void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier){
|
|||
cout << "Render type " << r->getType() << endl;
|
||||
}
|
||||
void GPUFontAtlasLayerCombo::update(){
|
||||
//#ifndef TARGET_OPENGLES
|
||||
//if(ofGetFrameNum() % 10 == 0){
|
||||
//shaderCatalog->requestUpdate("font");
|
||||
//}else if(ofGetFrameNum() % 10 == 5){
|
||||
//shaderCatalog->update();
|
||||
//float animationSpeed = 1.0;
|
||||
//float threshold = 1.0;
|
||||
//for(int i = 0; i < fontVariationAxes.size(); i++){
|
||||
//ofxGPUFont::Font::FontVariationAxis & axis = fontVariationAxes[i];
|
||||
//ofxGPUFont::Font::FontVariationAxisParameters & axisParams = fontVariationAxesParameters[i];
|
||||
//double newValue = ofMap(sin(ofGetElapsedTimef() * animationSpeed),
|
||||
//-1, 1,
|
||||
//axisParams.minValue, axisParams.maxValue);
|
||||
//if(abs(newValue - axis.value) > threshold){
|
||||
//font->setFontVariationAxis(library, axis.name, newValue);
|
||||
//axis.value = newValue;
|
||||
//font->prepareGlyphsForText(mainText, true);
|
||||
//}
|
||||
//#endif
|
||||
float animationSpeed = 1.0;
|
||||
float threshold = 1.0;
|
||||
for(int i = 0; i < fontVariationAxes.size(); i++){
|
||||
ofxGPUFont::Font::FontVariationAxis & axis = fontVariationAxes[i];
|
||||
ofxGPUFont::Font::FontVariationAxisParameters & axisParams = fontVariationAxesParameters[i];
|
||||
double newValue = ofMap(sin(ofGetElapsedTimef() * animationSpeed),
|
||||
-1, 1,
|
||||
axisParams.minValue, axisParams.maxValue);
|
||||
if(abs(newValue - axis.value) > threshold){
|
||||
font->setFontVariationAxis(library, axis.name, newValue);
|
||||
axis.value = newValue;
|
||||
font->prepareGlyphsForText(mainText, true);
|
||||
}
|
||||
//}
|
||||
if(isDirty){
|
||||
//ofxGPUFont::tryUpdateMainFont(library,
|
||||
//this->identifier.fontPath,
|
||||
//mainText,
|
||||
//font,
|
||||
//this->settings.gpuTextureOffset);
|
||||
font->prepareGlyphsForText(mainText, true);
|
||||
isDirty = false;
|
||||
}
|
||||
}
|
||||
void GPUFontAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
|
||||
if(layer->getType() == Layer::GPUFONT){
|
||||
shared_ptr <GPUFontLayer> gpuFontLayer = static_pointer_cast <GPUFontLayer>(layer);
|
||||
layers.push_back(gpuFontLayer);
|
||||
std::string oldText = mainText;
|
||||
std::string layerText = gpuFontLayer->getProps().text;
|
||||
std::string text = oldText + layerText;
|
||||
totalCharacters += layerText.length();
|
||||
removeDuplicateCharacters(text);
|
||||
// check if we added any characters
|
||||
// TODO: check for variation variations
|
||||
if(text.length() != oldText.length()){
|
||||
mainText = text;
|
||||
isDirty = true;
|
||||
}
|
||||
}else{
|
||||
ofLogError("GPUFontAtlasLayerCombo::careForChild()") << __LINE__ << ": child is not recognized as Layer::GPUFONT";
|
||||
}
|
||||
}
|
||||
void GPUFontAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){
|
||||
// TODO: handle removing child text from buffer
|
||||
shared_ptr <GPUFontLayer> gpuFontLayer = static_pointer_cast <GPUFontLayer>(layer);
|
||||
layers.erase(
|
||||
std::remove_if(
|
||||
layers.begin(),
|
||||
layers.end(),
|
||||
[gpuFontLayer](shared_ptr <GPUFontLayer> const & l)
|
||||
{
|
||||
return l == gpuFontLayer;
|
||||
}), layers.end());
|
||||
|
||||
// update the text
|
||||
// this doesn't happen very often, so let's just
|
||||
// iterate over all layers and calculate fresh
|
||||
std::string text = "";
|
||||
totalCharacters = 0;
|
||||
for(const auto & layer : layers){
|
||||
std::string layerText = layer->getProps().text;
|
||||
totalCharacters += layerText.length();
|
||||
text += layerText;
|
||||
}
|
||||
removeDuplicateCharacters(text);
|
||||
mainText = text;
|
||||
// NOTE: we do not want to update buffers now,
|
||||
// as it's probably more costly than just keeping
|
||||
// the old glyphs around...
|
||||
}
|
||||
const ComboIdentifier & GPUFontAtlasLayerCombo::getIdentifier() const {
|
||||
return identifier;
|
||||
|
@ -89,13 +137,6 @@ void GPUFontAtlasLayerCombo::draw(){
|
|||
int height = ofGetHeight();
|
||||
glm::vec2 mouse = glm::vec2(ofGetMouseX(), ofGetMouseY());
|
||||
|
||||
float targetFontSize = 128;
|
||||
|
||||
float width_unit = 1;
|
||||
float height_unit = (float)height / width;
|
||||
|
||||
//ofClear(125, 255, 125, 255);
|
||||
|
||||
//glm::mat4 projection = transform.getProjectionMatrix((float)width / height);
|
||||
glm::mat4 projection = transform.getOrthoProjectionMatrix(width,
|
||||
height,
|
||||
|
@ -158,37 +199,20 @@ void GPUFontAtlasLayerCombo::draw(){
|
|||
//mouse.y = 0;
|
||||
std::vector <ofxGPUFont::Font::BufferVertex> vertices;
|
||||
std::vector <int32_t> indices;
|
||||
string text = "whatever";
|
||||
int n_texts = 240;
|
||||
vertices.resize(text.length() * n_texts * 4);
|
||||
indices.resize(text.length() * n_texts * 6);
|
||||
cx = 0.5f * (bb.minX + bb.maxX);
|
||||
cy = 0.5f * (bb.minY + bb.maxY);
|
||||
|
||||
for(int i = 0; i < n_texts - 1; i++){
|
||||
float pipi = ((PI * 2 * i) / (n_texts - 1));
|
||||
float shift = (400 * cos(ofGetElapsedTimef() * 0.125 + pipi));
|
||||
float shift_x = (600 * sin(ofGetElapsedTimef() * 0.125 + pipi));
|
||||
float shift_o = (100 * sin(ofGetElapsedTimef() * 0.4 + pipi));
|
||||
font->collectVerticesAndIndices(
|
||||
glm::vec3(mouse.x + shift_x,
|
||||
mouse.y + shift + shift_o,
|
||||
0),
|
||||
text,
|
||||
vertices,
|
||||
indices,
|
||||
true,
|
||||
int(ofMap(sin(ofGetElapsedTimef() + pipi), -1, 1, 42, 96)));
|
||||
for(const auto & layer : layers){
|
||||
font->collectVerticesAndIndices(glm::vec3(layer->getProps().x,
|
||||
layer->getProps().y,
|
||||
0),
|
||||
layer->getProps().text,
|
||||
vertices, indices, true,
|
||||
layer->getProps().fontSize_px);
|
||||
}
|
||||
font->collectVerticesAndIndices(
|
||||
glm::vec3(mouse.x,
|
||||
mouse.y,
|
||||
0),
|
||||
text,
|
||||
vertices,
|
||||
indices,
|
||||
true,
|
||||
ofMap(sin(ofGetElapsedTimef() * 0.25f), -1.0f, 1.0f, 42.0f, 96.0f));
|
||||
vertices.resize(totalCharacters * 4);
|
||||
indices.resize(totalCharacters * 6);
|
||||
//cx = 0.5f * (bb.minX + bb.maxX);
|
||||
//cy = 0.5f * (bb.minY + bb.maxY);
|
||||
|
||||
font->draw(vertices, indices);
|
||||
//ofRectangle rectangle(0, 0, width, height);
|
||||
//ofDrawRectangle(rectangle);
|
||||
|
@ -208,9 +232,7 @@ void GPUFontAtlasLayerCombo::draw(){
|
|||
|
||||
ofDrawBitmapStringHighlight(
|
||||
"fps: " + ofToString(ofGetFrameRate()) + "\n"
|
||||
+ "font: " + currentFontPath + "\n"
|
||||
+ "cx: " + ofToString(cx) + "\n"
|
||||
+ "cy: " + ofToString(cy) + "\n"
|
||||
+ "font: " + this->identifier.fontPath + "\n"
|
||||
, 20, 20);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#endif
|
||||
|
||||
namespace ofxVariableLab {
|
||||
struct GPUFontAtlasLayerComboSettings : public AtlasLayerComboSettings {
|
||||
int gpuTextureOffset = 0;
|
||||
};
|
||||
class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
||||
struct Transform {
|
||||
enum Origin {
|
||||
|
@ -53,9 +56,11 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
|||
}
|
||||
};
|
||||
public:
|
||||
void setup(const ComboIdentifier & identifier) override;
|
||||
void setup(const ComboIdentifier & identifier,
|
||||
AtlasLayerComboSettings settings = GPUFontAtlasLayerComboSettings()) override;
|
||||
void update() override;
|
||||
void careForChild(shared_ptr <Layer> layer) override;
|
||||
void abandonChild(shared_ptr <Layer> layer) override;
|
||||
const ComboIdentifier & getIdentifier() const override;
|
||||
void setVFlip(VFlipState vFlipState) override;
|
||||
|
||||
|
@ -63,8 +68,11 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
|||
void draw();
|
||||
|
||||
shared_ptr <ofxGPUFont::Font> font;
|
||||
string mainText = "";
|
||||
|
||||
bool isDirty = false;
|
||||
private:
|
||||
GPUFontAtlasLayerComboSettings settings;
|
||||
FT_Library library;
|
||||
vector <shared_ptr <GPUFontLayer> > layers;
|
||||
ComboIdentifier identifier;
|
||||
|
@ -76,12 +84,8 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
|||
//std::shared_ptr <ShaderCatalog::Entry> backgroundShader;
|
||||
std::shared_ptr <ofxGPUFont::ShaderCatalog::Entry> fontShader;
|
||||
|
||||
ofxGPUFont::Font::BoundingBox bb;
|
||||
|
||||
Transform transform;
|
||||
|
||||
string currentFontPath;
|
||||
string mainText;
|
||||
// Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays.
|
||||
// 0 - no anti-aliasing
|
||||
// 1 - normal anti-aliasing
|
||||
|
@ -97,7 +101,7 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
|
|||
std::vector <ofxGPUFont::Font::FontVariationAxis> fontVariationAxes;
|
||||
|
||||
VFlipState vFlip;
|
||||
bool isDirty = false;
|
||||
int totalCharacters = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "LayerComposition.h"
|
||||
#include "Atlas.h"
|
||||
#include "GPUFontAtlasLayerCombo.h"
|
||||
#include "MsdfLayer.h"
|
||||
#include "Utils.h"
|
||||
#include "ofUtils.h"
|
||||
|
@ -8,10 +9,10 @@
|
|||
namespace ofxVariableLab {
|
||||
|
||||
void LayerComposition::setup(){
|
||||
auto combo = make_shared <GPUFontAtlasLayerCombo>();
|
||||
ComboIdentifier comboIdentifier = {"lol", Layer::GPUFONT};
|
||||
combo->setup(comboIdentifier);
|
||||
atlasLayerCombos[comboIdentifier] = combo;
|
||||
//auto combo = make_shared <GPUFontAtlasLayerCombo>();
|
||||
//ComboIdentifier comboIdentifier = {"lol", Layer::GPUFONT};
|
||||
//combo->setup(comboIdentifier);
|
||||
//atlasLayerCombos[comboIdentifier] = combo;
|
||||
}
|
||||
|
||||
void LayerComposition::update(){
|
||||
|
@ -35,40 +36,66 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
|
|||
const Layer::Props & props,
|
||||
const std::vector <FontVariation> & variations){
|
||||
string layerID = "";
|
||||
if(atlasLayerCombos.count(identifier) <= 0){
|
||||
switch(identifier.type){
|
||||
case Layer::GPUFONT: {
|
||||
ofLogError("LayerComposition::addLayer")
|
||||
<< "GPUFont not implemented" << endl;
|
||||
break;
|
||||
switch(identifier.type){
|
||||
case Layer::GPUFONT: {
|
||||
shared_ptr <GPUFontAtlasLayerCombo> combo;
|
||||
auto comboIterator = atlasLayerCombos.find(identifier);
|
||||
if(comboIterator == atlasLayerCombos.end()){
|
||||
// we don't have one yet
|
||||
// so let's create it
|
||||
combo = make_shared <GPUFontAtlasLayerCombo>();
|
||||
GPUFontAtlasLayerComboSettings settings;
|
||||
settings.gpuTextureOffset = nextGpuTextureOffset;
|
||||
combo->setup(identifier, settings);
|
||||
nextGpuTextureOffset++;
|
||||
atlasLayerCombos[identifier] = combo;
|
||||
}else{
|
||||
// use existing combo
|
||||
combo = dynamic_pointer_cast <GPUFontAtlasLayerCombo>(comboIterator->second);
|
||||
}
|
||||
|
||||
default:
|
||||
case Layer::MSDFGEN: {
|
||||
// TODO: put most stuff in combo setup
|
||||
auto combo = make_shared <MsdfAtlasLayerCombo>();
|
||||
combo->setup(identifier); // TODO: add here text and variations
|
||||
auto layer = make_shared <MsdfLayer>();
|
||||
layer->vFlip = vFlipState;
|
||||
layer->setProps(props);
|
||||
layer->setup();
|
||||
std::vector <ofxMsdfgen::FontVariation> msdfVariations;
|
||||
for(const auto & v : variations){
|
||||
msdfVariations.push_back({v.name, v.value});
|
||||
}
|
||||
// TODO: do not add Variation to atlas, but to combo,
|
||||
// so we know it's dirty
|
||||
combo->atlas->addVariations(msdfVariations);
|
||||
combo->careForChild(layer);
|
||||
layers[layer->getId()] = layer;
|
||||
atlasLayerCombos[identifier] = std::move(combo);
|
||||
layerID = layer->getId();
|
||||
auto layer = make_shared <GPUFontLayer>();
|
||||
layer->setProps(props);
|
||||
combo->careForChild(layer);
|
||||
layerID = layer->getId();
|
||||
layers[layerID] = layer;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
case Layer::MSDFGEN: {
|
||||
// TODO: put most stuff in combo setup
|
||||
auto combo = make_shared <MsdfAtlasLayerCombo>();
|
||||
combo->setup(identifier); // TODO: add here text and variations
|
||||
auto layer = make_shared <MsdfLayer>();
|
||||
layer->vFlip = vFlipState;
|
||||
layer->setProps(props);
|
||||
layer->setup();
|
||||
std::vector <ofxMsdfgen::FontVariation> msdfVariations;
|
||||
for(const auto & v : variations){
|
||||
msdfVariations.push_back({v.name, v.value});
|
||||
}
|
||||
}
|
||||
// TODO: do not add Variation to atlas, but to combo,
|
||||
// so we know it's dirty
|
||||
combo->atlas->addVariations(msdfVariations);
|
||||
combo->careForChild(layer);
|
||||
layers[layer->getId()] = layer;
|
||||
atlasLayerCombos[identifier] = std::move(combo);
|
||||
layerID = layer->getId();
|
||||
}
|
||||
}
|
||||
return layerID;
|
||||
}
|
||||
|
||||
void LayerComposition::removeLayer(const LayerID & id){
|
||||
auto layer = getLayer(id);
|
||||
for(auto & it : atlasLayerCombos){
|
||||
it.second->abandonChild(layer);
|
||||
}
|
||||
layers.erase(id);
|
||||
}
|
||||
|
||||
shared_ptr <Layer> LayerComposition::getLayer(const LayerID & layerID){
|
||||
return layers[layerID];
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "MsdfLayer.h"
|
||||
#include "GPUFontAtlasLayerCombo.h"
|
||||
#include "GPUFontLayer.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace ofxVariableLab {
|
||||
|
||||
|
@ -20,14 +21,22 @@ class LayerComposition {
|
|||
LayerID addLayer(const ComboIdentifier & identifier,
|
||||
const Layer::Props & props,
|
||||
const std::vector <FontVariation> & variations);
|
||||
shared_ptr <ofxVariableLab::Layer> getLayer(const LayerID & layerID);
|
||||
void removeLayer(const LayerID & id); // TODO: make bool, to catch nonexisting
|
||||
shared_ptr <Layer> getLayer(const LayerID & layerID);
|
||||
const unordered_map <ComboIdentifier, shared_ptr <AtlasLayerCombo> > & getAtlasLayerCombos() const;
|
||||
void setVFlip(bool vFlip);
|
||||
|
||||
private:
|
||||
VFlipState vFlipState = V_FLIP_UNKNOWN;
|
||||
unordered_map <LayerID, shared_ptr <ofxVariableLab::Layer> > layers;
|
||||
unordered_map <LayerID, shared_ptr <Layer> > layers;
|
||||
unordered_map <ComboIdentifier, shared_ptr <AtlasLayerCombo> > atlasLayerCombos;
|
||||
|
||||
/**
|
||||
* @brief lastGpuTextureOffset GL_TEXTURE0 + offset
|
||||
* we want to different textures for different fonts
|
||||
* this value is incremented/decremented when adding/removing GPUFont layers
|
||||
*/
|
||||
int nextGpuTextureOffset = 0;
|
||||
//unordered_map <LayerIdentifier, shared_ptr <ofxVariableLab::Layer> > layers;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
#include "MsdfAtlasLayerCombo.h"
|
||||
#include "AtlasLayerCombo.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace ofxVariableLab {
|
||||
|
||||
void MsdfAtlasLayerCombo::setup(const ComboIdentifier & layerIdentifier){
|
||||
void MsdfAtlasLayerCombo::setup(const ComboIdentifier & layerIdentifier,
|
||||
AtlasLayerComboSettings settings){
|
||||
this->identifier = layerIdentifier;
|
||||
this->settings = static_cast <MsdfAtlasLayerComboSettings &>(settings);
|
||||
ofxMsdfgen::AtlasSettings atlasSettings;
|
||||
//settings.characters = "ABCDEFGHIJKL";
|
||||
atlasSettings.scale = 64;
|
||||
atlasSettings.minimumScale = 64;
|
||||
atlasSettings.scale = this->settings.scale;
|
||||
atlasSettings.minimumScale = this->settings.minimumScale;
|
||||
atlasSettings.characters = "";
|
||||
atlasSettings.maxInterpolationStepSize = 50.0;
|
||||
atlasSettings.maxInterpolationStepSize = this->settings.maxInterpolationStepSize;
|
||||
|
||||
atlas = make_shared <ofxMsdfgen::Atlas>();
|
||||
|
||||
|
@ -45,6 +48,17 @@ void MsdfAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
|
|||
}
|
||||
layers.push_back(msdfLayer);
|
||||
}
|
||||
void MsdfAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){
|
||||
shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(layer);
|
||||
layers.erase(
|
||||
std::remove_if(
|
||||
layers.begin(),
|
||||
layers.end(),
|
||||
[msdfLayer](shared_ptr <MsdfLayer> const & l)
|
||||
{
|
||||
return l == msdfLayer;
|
||||
}), layers.end());
|
||||
}
|
||||
|
||||
const ComboIdentifier & MsdfAtlasLayerCombo::getIdentifier() const {
|
||||
return identifier;
|
||||
|
|
|
@ -5,11 +5,18 @@
|
|||
#include "Utils.h"
|
||||
|
||||
namespace ofxVariableLab {
|
||||
struct MsdfAtlasLayerComboSettings : public AtlasLayerComboSettings {
|
||||
float scale = 64;
|
||||
float minimumScale = 64;
|
||||
float maxInterpolationStepSize = 50.0;
|
||||
};
|
||||
class MsdfAtlasLayerCombo : public AtlasLayerCombo {
|
||||
public:
|
||||
void setup(const ComboIdentifier & identifier) override;
|
||||
void setup(const ComboIdentifier & identifier,
|
||||
AtlasLayerComboSettings settings = MsdfAtlasLayerComboSettings()) override;
|
||||
void update() override;
|
||||
void careForChild(shared_ptr <Layer> layer) override;
|
||||
void abandonChild(shared_ptr <Layer> layer) override;
|
||||
const ComboIdentifier & getIdentifier() const override;
|
||||
void setVFlip(VFlipState vFlipState) override;
|
||||
const ofImage & getAtlasImage();
|
||||
|
@ -18,6 +25,7 @@ class MsdfAtlasLayerCombo : public AtlasLayerCombo {
|
|||
shared_ptr <ofxMsdfgen::Atlas> atlas;
|
||||
|
||||
private:
|
||||
MsdfAtlasLayerComboSettings settings;
|
||||
vector <shared_ptr <MsdfLayer> > layers;
|
||||
vector <ofxMsdfgen::GlyphGeometry> glyphGeometries;
|
||||
shared_ptr <ofShader> msdfShader;
|
||||
|
|
38
src/Utils.h
38
src/Utils.h
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace ofxVariableLab {
|
||||
|
@ -22,6 +24,42 @@ inline void hash_combine(std::size_t & seed, const T & v){
|
|||
std::hash <T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
//template <class ForwardIt, class UnaryPredicate>
|
||||
//ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p){
|
||||
//first = std::find_if(first, last, p);
|
||||
//if(first != last){
|
||||
//for(ForwardIt i = first; ++i != last;){
|
||||
//if(!p(*i)){
|
||||
//*first++ = std::move(*i);
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//return first;
|
||||
//}
|
||||
|
||||
inline void removeDuplicateCharacters(std::string & str){
|
||||
std::set <char> chars;
|
||||
|
||||
str.erase(
|
||||
std::remove_if(
|
||||
str.begin(),
|
||||
str.end(),
|
||||
[&chars](char i){
|
||||
// If encountered character, remove this one.
|
||||
if(chars.count(i)){
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, mark this character encountered and don't remove.
|
||||
chars.insert(i);
|
||||
return false;
|
||||
}
|
||||
),
|
||||
str.end()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
enum VFlipState {
|
||||
V_FLIP_UNKNOWN = 0,
|
||||
V_FLIP_ON,
|
||||
|
|
Loading…
Reference in a new issue