#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 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, 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 (); GPUFontAtlasLayerComboSettings settings; combo->setup(idealMom, settings); combo->careForChild(layer); atlasLayerCombos[idealMom] = std::move(combo); break; } default: case LayerType::MSDFGEN: { auto combo = make_shared (); combo->setup(idealMom); std::vector 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 & 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 & variations, AtlasLayerComboSettings & s, LayerID layerID){ switch(identifier.type){ case LayerType::GPUFONT: { shared_ptr combo; auto comboIterator = atlasLayerCombos.find(identifier); if(comboIterator == atlasLayerCombos.end()){ // we don't have one yet // so let's create it combo = make_shared (); GPUFontAtlasLayerComboSettings & settings = static_cast (s); combo->setup(identifier, settings); atlasLayerCombos[identifier] = combo; }else{ // use existing combo combo = dynamic_pointer_cast (comboIterator->second); } auto layer = make_shared (); 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 (); MsdfAtlasLayerComboSettings settings = static_cast (s); cout << "LayerComposition::addLayer scale " << settings.scale << endl; combo->setup(identifier, settings); // TODO: add here text and variations auto layer = make_shared (); layer->vFlip = vFlipState; layer->setProps(props); layer->setup(); if(layerID == ""){ layerID = layer->getId(); }else{ layer->setId(layerID); } std::vector 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 > & LayerComposition::getLayers(){ return layers; } shared_ptr 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 (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 (atlasLayerCombos.at(layer->getMomsComboIdentifier())); auto gpulayer = static_pointer_cast (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 (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 (layerCombo); combo->draw(camera); } } } const unordered_map > & 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 & layerOrder){ this->layerOrder = layerOrder; } }