ofxVariableLab/src/LayerComposition.cpp

245 lines
8.6 KiB
C++

#include "LayerComposition.h"
#include "Atlas.h"
#include "AtlasLayerCombo.h"
#include "GPUFontAtlasLayerCombo.h"
#include "GPUFontLayer.h"
#include "MsdfAtlasLayerCombo.h"
#include "MsdfLayer.h"
#include "Utils.h"
#include "ofUtils.h"
#include <memory>
namespace ofxVariableLab {
void LayerComposition::setup(){
}
void LayerComposition::update(){
for(auto & l: layers){
if(l.second->wantsNewMom()){
const auto momIdentifier = l.second->getMomsComboIdentifier();
atlasLayerCombos[momIdentifier]->abandonChild(l.second);
if(!atlasLayerCombos[momIdentifier]->hasChildren()){
atlasLayerCombos.erase(momIdentifier);
}
ComboIdentifier idealMom{
l.second->getProps().fontPath,
momIdentifier.type
};
//cout << "ideal mom looks like this: " << l.second->getProps().fontPath
//<< (momIdentifier.type == LayerType::GPUFONT ? " gpufont" : " msdfgen")
//<< endl;
findOrCreateNewMomForLayer(l.second, idealMom);
}
}
for(const auto & atlasLayerCombo : atlasLayerCombos){
atlasLayerCombo.second->update();
}
}
void LayerComposition::findOrCreateNewMomForLayer(shared_ptr <Layer> layer,
ComboIdentifier idealMom){
auto comboIterator = atlasLayerCombos.find(idealMom);
if(comboIterator != atlasLayerCombos.end()){
comboIterator->second->careForChild(layer);
}else{
switch(idealMom.type){
case LayerType::GPUFONT: {
auto combo = make_shared <GPUFontAtlasLayerCombo>();
GPUFontAtlasLayerComboSettings settings;
combo->setup(idealMom, settings);
combo->careForChild(layer);
atlasLayerCombos[idealMom] = std::move(combo);
break;
}
default:
case LayerType::MSDFGEN: {
auto combo = make_shared <MsdfAtlasLayerCombo>();
combo->setup(idealMom);
std::vector <ofxMsdfgen::FontVariation> msdfVariations;
for(const auto & v : layer->getProps().fontVariations){
msdfVariations.push_back({v.name, v.value});
}
combo->atlas->addVariations(msdfVariations);
combo->careForChild(layer);
atlasLayerCombos[idealMom] = std::move(combo);
}
}
}
}
LayerID LayerComposition::addLayer(const Layer::Props & props,
LayerID layerID){
ComboIdentifier identifier;
identifier.fontPath = props.fontPath;
identifier.type = LayerType::GPUFONT;
GPUFontAtlasLayerComboSettings s;
return addLayer(identifier,
props,
props.fontVariations,
s,
layerID);
}
LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
const string & text,
const std::vector <FontVariation> & variations,
AtlasLayerComboSettings & s,
LayerID layerID){
auto props = Layer::Props();
props.text = text;
props.fontPath = identifier.fontPath;
return addLayer(identifier,
props,
variations,
s,
layerID);
}
LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
const Layer::Props & props,
const std::vector <FontVariation> & variations,
AtlasLayerComboSettings & s,
LayerID layerID){
switch(identifier.type){
case LayerType::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 = static_cast <GPUFontAtlasLayerComboSettings &>(s);
combo->setup(identifier, settings);
atlasLayerCombos[identifier] = combo;
}else{
// use existing combo
combo = dynamic_pointer_cast <GPUFontAtlasLayerCombo>(comboIterator->second);
}
auto layer = make_shared <GPUFontLayer>();
layer->vFlip = vFlipState;
layer->setProps(props);
layer->setup();
if(layerID == ""){
layerID = layer->getId();
}else{
layer->setId(layerID);
}
combo->careForChild(layer);
layers[layerID] = layer;
break;
}
default:
case LayerType::MSDFGEN: {
// TODO: put most stuff in combo setup
auto combo = make_shared <MsdfAtlasLayerCombo>();
MsdfAtlasLayerComboSettings settings = static_cast <MsdfAtlasLayerComboSettings &>(s);
cout << "LayerComposition::addLayer scale " << settings.scale << endl;
combo->setup(identifier, settings); // TODO: add here text and variations
auto layer = make_shared <MsdfLayer>();
layer->vFlip = vFlipState;
layer->setProps(props);
layer->setup();
if(layerID == ""){
layerID = layer->getId();
}else{
layer->setId(layerID);
}
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);
Layer::n_layers--;
}
const unordered_map <LayerID, shared_ptr <Layer> > & LayerComposition::getLayers(){
return layers;
}
shared_ptr <Layer> LayerComposition::getLayer(const LayerID & layerID){
return layers[layerID];
}
void LayerComposition::draw(int width, int height) const {
for(const auto & [identifier, layerCombo] : atlasLayerCombos){
if(identifier.type == LayerType::MSDFGEN){
auto combo = static_pointer_cast <MsdfAtlasLayerCombo>(layerCombo);
//combo->draw();
}
}
for(unsigned int i = layerOrder.size(); i-- > 0;){
LayerID layerID = layerOrder[i];
if(layers.count(layerID) > 0){
auto layer = layers.at(layerID);
if(layers.at(layerID)->getType() == LayerType::MSDFGEN){
//layer->draw(glm::vec3(200, 200, 0));
}else{
auto combo =
static_pointer_cast <GPUFontAtlasLayerCombo>(atlasLayerCombos.at(layer->getMomsComboIdentifier()));
auto gpulayer =
static_pointer_cast <GPUFontLayer>(layer);
combo->draw(width, height, gpulayer);
}
}
}
//for(const auto & layer_it : layers){
//if(layer_it.second->getType() == LayerType::MSDFGEN){
//layer_it.second->draw(glm::vec3(200, 200, 0));
//}
//}
//for(const auto & combo_it : atlasLayerCombos){
//if(combo_it.first.type == LayerType::GPUFONT){
//auto combo =
//static_pointer_cast <GPUFontAtlasLayerCombo>(combo_it.second);
//combo->draw(width, height);
//}
//}
}
void LayerComposition::drawCamera(const ofCamera & camera) const {
for(const auto & [identifier, layerCombo] : atlasLayerCombos){
if(identifier.type == LayerType::MSDFGEN){
auto combo = static_pointer_cast <MsdfAtlasLayerCombo>(layerCombo);
combo->draw(camera);
}
}
}
const unordered_map <ComboIdentifier, shared_ptr <AtlasLayerCombo> > & LayerComposition::getAtlasLayerCombos() const {
return atlasLayerCombos;
}
void LayerComposition::setVFlip(bool vFlip){
vFlipState = vFlip ? V_FLIP_ON : V_FLIP_OFF;
for(auto & layer : layers){
layer.second->setVFlip(vFlipState);
}
for(const auto & combo_it : atlasLayerCombos){
combo_it.second->setVFlip(vFlipState);
}
}
void LayerComposition::setLayerOrder(const vector <LayerID> & layerOrder){
this->layerOrder = layerOrder;
}
}