diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index d63ee30..0035548 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -255,14 +255,6 @@ void GPUFontAtlasLayerCombo::draw(int width, int height){ bb.p2.y = max_y; bb.p3.x = min_x; bb.p3.y = max_y; - - if(ofGetFrameNum() % 600 == 0){ - cout - << "n_wraps: " << ofToString(n_wraps) << endl - << "layer->getProps().width: " << ofToString(layer->getProps().width) << endl - ; - - } } glm::vec4 transformOrigin; getAndApplyTransformOrigin(transformOrigin, @@ -373,11 +365,33 @@ void GPUFontAtlasLayerCombo::draw(int width, int height){ min_y = min(min_y, min(mbb.p0.y, min(mbb.p1.y, min(mbb.p2.y, mbb.p3.y)))); max_y = max(max_y, max(mbb.p0.y, max(mbb.p1.y, max(mbb.p2.y, mbb.p3.y)))); } - float width = max_x - min_x; - float height = max_y - min_y; - layer->setBoundingBox(Layer::BoundingBox{min_x, min_y, width, height}); + float layerWidth = max_x - min_x; + float layerHeight = max_y - min_y; + layer->setBoundingBox(Layer::BoundingBox{min_x, min_y, layerWidth, layerHeight}); r = ofRectangle(layer->getProps().x, layer->getProps().y, layer->getProps().width, 800); + + // culling + deque removeMe; + for(int index : indices){ + const auto & v0 = vertices[index * 4]; + const auto & v1 = vertices[index * 4 + 1]; + const auto & v2 = vertices[index * 4 + 2]; + const auto & v3 = vertices[index * 4 + 3]; + if(!isInside(v0.x, v0.y, 0, 0, float(width), float(height)) + && !isInside(v1.x, v1.y, 0, 0, float(width), float(height)) + && !isInside(v2.x, v2.y, 0, 0, float(width), float(height)) + && !isInside(v3.x, v3.y, 0, 0, float(width), float(height))){ + removeMe.push_front(index); + } + } + for(int index : removeMe){ + indices.erase(indices.begin() + index); + vertices.erase(vertices.begin() + (index * 4)); + vertices.erase(vertices.begin() + (index * 4) + 1); + vertices.erase(vertices.begin() + (index * 4) + 2); + vertices.erase(vertices.begin() + (index * 4) + 3); + } } { @@ -425,16 +439,11 @@ void GPUFontAtlasLayerCombo::draw(int width, glm::mat4 view = transform.getViewMatrix(); glm::mat4 model = glm::mat4(1.0f); - //glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // background color - //glClear(GL_COLOR_BUFFER_BIT); // clear background with background color - // Uses premultiplied-alpha. ofDisableDepthTest(); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - //ofEnableAlphaBlending(); int currentProgram; glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); @@ -491,16 +500,13 @@ void GPUFontAtlasLayerCombo::draw(int width, true, layer->getProps().fontSize_px, layer->getProps().lineHeight); float lineHeight = font->getLineHeight(layer->getProps().fontSize_px) * layer->getProps().lineHeight; - if(layer->getProps().width > 0){ - int n_wraps = wrapBoundingBoxes(bbs, - layer->getVariationText(), - layer->getProps().width, - lineHeight); - // could be optimized by: - // - min_x = bbs[0].p0.x - // - max_x = min_x + layer->getProps().width - // - min_y = bbs[0].p0.y - // - max_y = lineHeight * (n_wraps + 1) + int n_wraps = wrapBoundingBoxes(bbs, + layer->getVariationText(), + layer->getProps().width, + lineHeight, + layer->getProps().textAlignment); + //if(layer->getProps().width > 0){ + { float min_x = FLT_MAX; float min_y = FLT_MAX; float max_x = -FLT_MAX; @@ -519,14 +525,6 @@ void GPUFontAtlasLayerCombo::draw(int width, bb.p2.y = max_y; bb.p3.x = min_x; bb.p3.y = max_y; - - if(ofGetFrameNum() % 600 == 0){ - cout - << "n_wraps: " << ofToString(n_wraps) << endl - << "layer->getProps().width: " << ofToString(layer->getProps().width) << endl - ; - - } } glm::vec4 transformOrigin; getAndApplyTransformOrigin(transformOrigin, @@ -637,13 +635,42 @@ void GPUFontAtlasLayerCombo::draw(int width, min_y = min(min_y, min(mbb.p0.y, min(mbb.p1.y, min(mbb.p2.y, mbb.p3.y)))); max_y = max(max_y, max(mbb.p0.y, max(mbb.p1.y, max(mbb.p2.y, mbb.p3.y)))); } - float width = max_x - min_x; - float height = max_y - min_y; - layer->setBoundingBox(Layer::BoundingBox{min_x, min_y, width, height}); + float layerWidth = max_x - min_x; + float layerHeight = max_y - min_y; + layer->setBoundingBox(Layer::BoundingBox{min_x, min_y, layerWidth, layerHeight}); r = ofRectangle(layer->getProps().x, layer->getProps().y, layer->getProps().width, 800); + + //cout << vertices.size() << " / " << indices.size() << endl; + // culling + //deque removeMe; + //for(int index = 0; index < vertices.size() / 4; index++){ + //const auto & v0 = vertices[index * 4]; + //const auto & v1 = vertices[index * 4 + 1]; + //const auto & v2 = vertices[index * 4 + 2]; + //const auto & v3 = vertices[index * 4 + 3]; + //if(!isInside(v0.x, v0.y, 0, 0, float(width), float(height)) + //&& !isInside(v1.x, v1.y, 0, 0, float(width), float(height)) + //&& !isInside(v2.x, v2.y, 0, 0, float(width), float(height)) + //&& !isInside(v3.x, v3.y, 0, 0, float(width), float(height))){ + //removeMe.push_front(index); + //} + //} + //for(int index : removeMe){ + //indices.erase(indices.begin() + (index * 6)); + //indices.erase(indices.begin() + (index * 6) + 1); + //indices.erase(indices.begin() + (index * 6) + 2); + //indices.erase(indices.begin() + (index * 6) + 3); + //indices.erase(indices.begin() + (index * 6) + 4); + //indices.erase(indices.begin() + (index * 6) + 5); + //vertices.erase(vertices.begin() + (index * 4)); + //vertices.erase(vertices.begin() + (index * 4) + 1); + //vertices.erase(vertices.begin() + (index * 4) + 2); + //vertices.erase(vertices.begin() + (index * 4) + 3); + //} } + { OFX_PROFILER_SCOPE("font->draw()"); font->draw(vertices, indices); @@ -717,7 +744,8 @@ void GPUFontAtlasLayerCombo::getAndApplyTransformOrigin(glm::vec4 & transformOri } case Layer::TransformOrigin::BOTTOM_LEFT: { - float moveY = ascender - advanceY; + //float moveY = ascender - advanceY; + float moveY = (bb.p0.y - bb.p2.y); node.setPosition(glm::vec3(0, moveY, 0)); @@ -728,7 +756,8 @@ void GPUFontAtlasLayerCombo::getAndApplyTransformOrigin(glm::vec4 & transformOri } case Layer::TransformOrigin::BOTTOM_RIGHT: { - float moveY = ascender - (advanceY); + //float moveY = ascender - (advanceY); + float moveY = (bb.p0.y - bb.p2.y); float moveX = (bb.p2.x - bb.p0.x); node.setPosition(glm::vec3(-moveX, moveY, @@ -746,21 +775,32 @@ void GPUFontAtlasLayerCombo::getAndApplyTransformOrigin(glm::vec4 & transformOri int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector & bbs, const std::vector & _variationText, int width, - float advanceY){ + float advanceY, + float textAlignment){ int i = 0; int vi = 0; int wrapIndex = -1; int n_wraps = 0; - bool firstToBreak = true; float collectedWrapWidth = 0; + std::vector lineBreaks; + std::vector goodCharacters; + int lastGoodCharacter = -1; + //textAlignment = ofMap(sin(ofGetElapsedTimef()), -1, 1, 0, 1); + float maxX = 0; for(ofxGPUFont::Font::BoundingBox & bb : bbs){ + // good character means it's a drawable character bool hasGoodCharacter = false; - while(!hasGoodCharacter && vi < variationText.size() - 1){ + while(!hasGoodCharacter && vi < variationText.size()){ if(variationText[vi].charcode == '\0' || variationText[vi].charcode == '\r' || variationText[vi].charcode == '\n'){ + if(variationText[vi].charcode == '\n'){ + if(lastGoodCharacter >= 0){ + lineBreaks.push_back(lastGoodCharacter); + } + } wrapIndex = -1; collectedWrapWidth = 0; vi++; @@ -769,70 +809,62 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector width){ + const float insideWidth = bb.p1.x - collectedWrapWidth; + bool overhang = (insideWidth / float(width)) > (n_wraps + 1); + + if(width > 0 && insideWidth > width){ if(wrapIndex >= 0){ - if(wrapIndex == i){ - float wrapWidth = bb.p0.x; - collectedWrapWidth = wrapWidth; - n_wraps++; - bb.p0.x -= wrapWidth; - bb.p1.x -= wrapWidth; - bb.p2.x -= wrapWidth; - bb.p3.x -= wrapWidth; - bb.p0.y += (n_wraps) * advanceY; - bb.p1.y += (n_wraps) * advanceY; - bb.p2.y += (n_wraps) * advanceY; - bb.p3.y += (n_wraps) * advanceY; - }else{ - if(firstToBreak){ - collectedWrapWidth = bbs[wrapIndex].p0.x; - n_wraps++; - for(int w = wrapIndex; w <= i; w++){ - bbs[w].p0.x -= collectedWrapWidth; - bbs[w].p1.x -= collectedWrapWidth; - bbs[w].p2.x -= collectedWrapWidth; - bbs[w].p3.x -= collectedWrapWidth; - bbs[w].p0.y += (n_wraps) * advanceY; - bbs[w].p1.y += (n_wraps) * advanceY; - bbs[w].p2.y += (n_wraps) * advanceY; - bbs[w].p3.y += (n_wraps) * advanceY; - } - }else{ - bb.p0.x -= collectedWrapWidth; - bb.p1.x -= collectedWrapWidth; - bb.p2.x -= collectedWrapWidth; - bb.p3.x -= collectedWrapWidth; - bb.p0.y += (n_wraps) * advanceY; - bb.p1.y += (n_wraps) * advanceY; - bb.p2.y += (n_wraps) * advanceY; - bb.p3.y += (n_wraps) * advanceY; - } + float wrapWidth = bbs[wrapIndex].p0.x; + for(int w = wrapIndex; w < bbs.size(); w++){ + bbs[w].p0.x -= wrapWidth; + bbs[w].p1.x -= wrapWidth; + bbs[w].p2.x -= wrapWidth; + bbs[w].p3.x -= wrapWidth; + bbs[w].p0.y += advanceY; + bbs[w].p1.y += advanceY; + bbs[w].p2.y += advanceY; + bbs[w].p3.y += advanceY; } - firstToBreak = false; + n_wraps++; + lineBreaks.push_back(wrapIndex - 1); + wrapIndex = -1; } - }else{ - bb.p0.x -= collectedWrapWidth; - bb.p1.x -= collectedWrapWidth; - bb.p2.x -= collectedWrapWidth; - bb.p3.x -= collectedWrapWidth; - bb.p0.y += (n_wraps) * advanceY; - bb.p1.y += (n_wraps) * advanceY; - bb.p2.y += (n_wraps) * advanceY; - bb.p3.y += (n_wraps) * advanceY; } + maxX = max(maxX, bbs[i].p1.x); + + if(hasGoodCharacter){ + lastGoodCharacter = i; + } vi++; i++; } + + if(textAlignment != 0){ + if(lineBreaks.size() > 0){ + lineBreaks.push_back(lastGoodCharacter); + } + float w = width; // > 0 ? width : maxX; + int startFromCharacter = 0; + for(int lineBreak : lineBreaks){ + ofxGPUFont::Font::BoundingBox & bbb = bbs[lineBreak]; + float shiftX = (w - bbb.p1.x) * textAlignment; + for(int i = startFromCharacter; i <= lineBreak; i++){ + auto & bb = bbs[i]; + bb.p0.x += shiftX; + bb.p1.x += shiftX; + bb.p2.x += shiftX; + bb.p3.x += shiftX; + } + startFromCharacter = lineBreak + 1; + } + } return n_wraps; } //void GPUFontAtlasLayerCombo::cullBoundingBoxes(std::vector & bbs, @@ -844,5 +876,4 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector & bbs, const std::vector & _variationText, int width, - float advanceY); + float advanceY, + float textAlignment = 0); //void cullBoundingBoxes(std::vector & bbs, //int width, int height); //bool isInside(const ofxGPUFont::Font::BoundingBox & bb, @@ -130,4 +131,5 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo { int totalCharacters = 0; }; + } diff --git a/src/Layer.h b/src/Layer.h index 8a95257..edb5ede 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -36,6 +36,7 @@ class Layer { float fontSize_px = 42; float letterSpacing = 0; float lineHeight = 1; + float textAlignment = 0; std::array color = {0, 0, 0, 1}; bool mirror_x = false; float mirror_x_distance = 0; diff --git a/src/LayerComposition.cpp b/src/LayerComposition.cpp index 6cb6340..cb4af93 100644 --- a/src/LayerComposition.cpp +++ b/src/LayerComposition.cpp @@ -181,12 +181,18 @@ shared_ptr LayerComposition::getLayer(const LayerID & 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)); + //layer->draw(glm::vec3(200, 200, 0)); }else{ auto combo = static_pointer_cast (atlasLayerCombos.at(layer->getMomsComboIdentifier())); @@ -209,6 +215,14 @@ void LayerComposition::draw(int width, int height) const { //} //} } +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; diff --git a/src/LayerComposition.h b/src/LayerComposition.h index 6b74cfb..117b154 100644 --- a/src/LayerComposition.h +++ b/src/LayerComposition.h @@ -15,6 +15,7 @@ class LayerComposition { void setup(); void update(); void draw(int width = 0, int height = 0) const; + void drawCamera(const ofCamera & camera) const; LayerID addLayer(const Layer::Props & props, LayerID layerID = ""); LayerID addLayer(const ComboIdentifier & identifier, diff --git a/src/MsdfAtlasLayerCombo.cpp b/src/MsdfAtlasLayerCombo.cpp index f46f286..d51bfa1 100644 --- a/src/MsdfAtlasLayerCombo.cpp +++ b/src/MsdfAtlasLayerCombo.cpp @@ -114,6 +114,16 @@ bool MsdfAtlasLayerCombo::hasChildren(){ return layers.size() > 0; } +// unique +void MsdfAtlasLayerCombo::draw(const ofCamera & camera){ + vertices.clear(); + parameters.clear(); + for(const auto & layer : layers){ + vertices.insert(vertices.end(), layer->vertices.begin(), layer->vertices.end()); + parameters.insert(parameters.end(), layer->parameters.begin(), layer->parameters.end()); + } +} + const ofImage & MsdfAtlasLayerCombo::getAtlasImage(){ return atlas->getAtlasImage(); } diff --git a/src/MsdfAtlasLayerCombo.h b/src/MsdfAtlasLayerCombo.h index c0a52ed..11afd8b 100644 --- a/src/MsdfAtlasLayerCombo.h +++ b/src/MsdfAtlasLayerCombo.h @@ -20,6 +20,7 @@ class MsdfAtlasLayerCombo : public AtlasLayerCombo { const ComboIdentifier & getIdentifier() const override; void setVFlip(VFlipState vFlipState) override; bool hasChildren() override; + void draw(const ofCamera & camera); const ofImage & getAtlasImage(); string getAtlasImagePath(); shared_ptr getLayer(); // TODO: is this used @@ -39,5 +40,7 @@ class MsdfAtlasLayerCombo : public AtlasLayerCombo { GLint uboIndex; void setupUbo(); bool uboIsSetup = false; + std::vector vertices; + std::vector parameters; }; } diff --git a/src/MsdfLayer.cpp b/src/MsdfLayer.cpp index e0b3d73..369c6f8 100644 --- a/src/MsdfLayer.cpp +++ b/src/MsdfLayer.cpp @@ -3,6 +3,7 @@ #include "Utils.h" #include "fwd.hpp" #include "ofGraphics.h" +#include "ofGraphicsConstants.h" #include "ofUtils.h" namespace ofxVariableLab { @@ -311,6 +312,122 @@ const Layer::BoundingBox & MsdfLayer::getBoundingBox(){ void MsdfLayer::setBoundingBox(const Layer::BoundingBox & boundingBox){ this->boundingBox = boundingBox; } +void MsdfLayer::collectCharacter(const char character, + const ofNode & node, + glm::vec4 color, + ofxVariableLab::FontVariation fontVariation){ + const ofImage & atlasImage = atlas->getAtlasImage(); + ofNode n = node; + n.setScale(n.getScale() * scaleFactor); + float pixelRange = 2; + int atlas_w = atlasImage.getWidth(); + int atlas_h = atlasImage.getHeight(); + glm::vec2 unitRange = glm::vec2(pixelRange) / glm::vec2(atlas_w, atlas_h); + + float mix = -1; + ofxMsdfgen::GlyphGeometry gg_a; + ofxMsdfgen::GlyphGeometry gg_b; + + ofxMsdfgen::FontVariation fv{ + fontVariation.name, + fontVariation.value + }; + + bool success = atlas->getGlyphGeometryPair(character, + fv, + gg_a, + gg_b, + mix); + if(!success){ + ofLogError("MsdfLayer::draw") << "could not get glyphGeometryPair" << endl; + } + int x_a, y_a, w_a, h_a; + int x_b, y_b, w_b, h_b; + gg_a.getBoxRect(x_a, y_a, w_a, h_a); + gg_b.getBoxRect(x_b, y_b, w_b, h_b); + if(y_a < 0 || y_b < 0){ + // FIXME: make sure this does not happen + ofLogError("MsdfLayer::draw") << "y smaller 0, this is not good" << endl; + } + double pl_a, pb_a, pr_a, pt_a; + double pl_b, pb_b, pr_b, pt_b; + gg_a.getQuadPlaneBounds(pl_a, pb_a, pr_a, pt_a); + gg_b.getQuadPlaneBounds(pl_b, pb_b, pr_b, pt_b); + + double advance_a = gg_a.getAdvance(); + double advance_b = gg_b.getAdvance(); + + float w = glm::mix(float(w_a), float(w_b), mix); + float h = glm::mix(float(h_a), float(h_b), mix); + float pl = glm::mix(float(pl_a), float(pl_b), mix); + float pt = glm::mix(float(pt_a), float(pt_b), mix); + double advance = glm::mix(advance_a, advance_b, mix); + + ofPushMatrix(); + float magic = atlas->settings.scale; + ofSetColor(ofFloatColor(1, 1, 1, 1)); + getVFlip(settings.vFlipBehaviour, + ofGetCurrentOrientationMatrix(), + vFlip); + if(vFlip == V_FLIP_OFF){ + n.move(pl * magic, (pt * magic) + (-1 * h), 0.0f); + }else{ + n.move(pl * magic, -1 * pt * magic, 0); + } + + glm::vec2 translation_a = glm::vec2(float(x_a) / float(atlas_w), + float(y_a) / float(atlas_h)); + glm::vec2 scale_a = glm::vec2(float(w_a) / float(atlas_w), + float(h_a) / float(atlas_h)); + glm::vec2 translation_b = glm::vec2(float(x_b) / float(atlas_w), + float(y_b) / float(atlas_h)); + glm::vec2 scale_b = glm::vec2(float(w_b) / float(atlas_w), + float(h_b) / float(atlas_h)); + + BufferVertex v[4]; + glm::vec4 p0 = n.getGlobalTransformMatrix() * glm::vec4(0, 0, 0, 1); + glm::vec4 p1 = n.getGlobalTransformMatrix() * glm::vec4(w, 0, 0, 1); + glm::vec4 p2 = n.getGlobalTransformMatrix() * glm::vec4(w, h, 0, 1); + glm::vec4 p3 = n.getGlobalTransformMatrix() * glm::vec4(0, h, 0, 1); + glm::vec2 uv0_a = glm::vec2(); + glm::vec2 uv0_b = glm::vec2(); + glm::vec2 uv1_a = glm::vec2(); + glm::vec2 uv1_b = glm::vec2(); + glm::vec2 uv2_a = glm::vec2(); + glm::vec2 uv2_b = glm::vec2(); + glm::vec2 uv3_a = glm::vec2(); + glm::vec2 uv3_b = glm::vec2(); + vertices.push_back(BufferVertex{ + {p0.x, p0.y, p0.z, p0.w}, + {uv0_a.x, uv0_a.y}, + {uv0_b.x, uv0_b.y} + }); + vertices.push_back(BufferVertex{ + {p1.x, p1.y, p1.z, p1.w}, + {uv1_a.x, uv1_a.y}, + {uv1_b.x, uv1_b.y} + }); + vertices.push_back(BufferVertex{ + {p2.x, p2.y, p2.z, p2.w}, + {uv2_a.x, uv2_a.y}, + {uv2_b.x, uv2_b.y} + }); + vertices.push_back(BufferVertex{ + {p3.x, p3.y, p3.z, p3.w}, + {uv3_a.x, uv3_a.y}, + {uv3_b.x, uv3_b.y} + }); + CharacterDrawParameters characterDrawParameters; + characterDrawParameters.unitRange = unitRange; + characterDrawParameters.fontColor = color; + characterDrawParameters.bgColor = uboParameters.bgColor; + characterDrawParameters.translation_a = translation_a; + characterDrawParameters.translation_b = translation_b; + characterDrawParameters.scale_a = scale_a; + characterDrawParameters.scale_b = scale_b; + characterDrawParameters.mix = mix; + parameters.push_back(characterDrawParameters); +} void MsdfLayer::setAtlas(shared_ptr _atlas){ atlas = _atlas; // TODO: this does not seem proper diff --git a/src/MsdfLayer.h b/src/MsdfLayer.h index 4e03125..a957933 100644 --- a/src/MsdfLayer.h +++ b/src/MsdfLayer.h @@ -21,6 +21,22 @@ class MsdfLayer : public Layer { glm::vec2 scale_b; float mix; }; + struct BufferVertex { + GLfloat position[4]; + GLfloat uv_a[2]; + GLfloat uv_b[2]; + }; + struct CharacterDrawParameters { + glm::vec2 dimensions; + glm::vec4 fontColor; + glm::vec4 bgColor; + glm::vec2 unitRange; + glm::vec2 translation_a; + glm::vec2 scale_a; + glm::vec2 translation_b; + glm::vec2 scale_b; + float mix; + }; void setup(const LayerSettings & settings = LayerSettings()) override; void update() override; void draw(glm::vec3 position = glm::vec3(0, 0, 0)) override; @@ -49,6 +65,10 @@ class MsdfLayer : public Layer { ofNode & getInnerNode() override; const Layer::BoundingBox & getBoundingBox() override; void setBoundingBox(const Layer::BoundingBox & boundingBox) override; + void collectCharacter(const char character, + const ofNode & node, + glm::vec4 color = glm::vec4(1, 1, 1, 1), + ofxVariableLab::FontVariation fontVariation = ofxVariableLab::FontVariation()); void setAtlas(shared_ptr _atlas); shared_ptr getAtlas() const; @@ -67,6 +87,9 @@ class MsdfLayer : public Layer { GLint uboIndex; UboParameters uboParameters; + std::vector vertices; + std::vector parameters; + private: Props lastProps; std::deque propsBuffer; diff --git a/src/Utils.cpp b/src/Utils.cpp index 37fc210..922cadf 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -41,5 +41,4 @@ void getVFlip(const VFlipBehaviour & vFlipBehaviour, ////ofTranslate(pl * magic, -1 * pt * magic, 0); //}else{ //ofTranslate(pl * magic, -1 * pt * magic, 0); -//} } diff --git a/src/Utils.h b/src/Utils.h index 0f29988..6c5a80e 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -159,4 +159,8 @@ static bool listFontVariationAxes(std::string fontPath, return success; } +static bool isInside(float px, float py, float x, float y, float w, float h){ + return px >= x && px <= x + w && py >= y && py <= y + h; +} + }