From 012987c11ba2ecf24250a5f33e989972974a07b4 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sun, 14 May 2023 08:33:23 +0200 Subject: [PATCH] introduce layerOrder --- src/GPUFontAtlasLayerCombo.cpp | 278 ++++++++++++++++++++++++++++++--- src/GPUFontAtlasLayerCombo.h | 3 + src/Layer.h | 1 + src/LayerComposition.cpp | 47 ++++-- src/LayerComposition.h | 3 + 5 files changed, 298 insertions(+), 34 deletions(-) diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index b3dbe3c..d2c02a2 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -39,19 +39,18 @@ void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier, this->settings.gpuTextureOffset); font->listFontVariationAxes(fontVariationAxesParameters, library); - cout << this->identifier.fontPath << " : 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) - << "\tmax: " << std::to_string(axis.maxValue) - << "\tdefault: " << std::to_string(axis.defaultValue) << endl; + //cout << std::fixed << std::setprecision(10) << axis.name << " :\n" + //<< "\tmin: " << std::to_string(axis.minValue) + //<< "\tmax: " << std::to_string(axis.maxValue) + //<< "\tdefault: " << std::to_string(axis.defaultValue) << endl; fontVariationAxes.push_back({axis.name, axis.defaultValue}); } transform = Transform(); auto & r = ofGetCurrentRenderer(); - cout << "Render type " << r->getType() << endl; } void GPUFontAtlasLayerCombo::update(){ OFX_PROFILER_FUNCTION(); @@ -228,12 +227,12 @@ void GPUFontAtlasLayerCombo::draw(int width, int height){ layer->getVariationText(), layer->getProps().width, lineHeight); - if(ofGetFrameNum() % 600 == 0){ - cout - << "n_wraps: " << ofToString(n_wraps) << endl - << "layer->getProps().width: " << ofToString(layer->getProps().width) << endl - ; - } + //if(ofGetFrameNum() % 600 == 0){ + //cout + //<< "n_wraps: " << ofToString(n_wraps) << endl + //<< "layer->getProps().width: " << ofToString(layer->getProps().width) << endl + //; + //bb.p2.y += n_wraps * lineHeight; //bb.p3.y += n_wraps * lineHeight; glm::vec4 transformOrigin; @@ -358,11 +357,250 @@ void GPUFontAtlasLayerCombo::draw(int width, int height){ } glUseProgram(currentProgram); - ofPushStyle(); - ofSetColor(ofColor::green); - ofNoFill(); - ofDrawRectangle(r); - ofPopStyle(); + //ofPushStyle(); + //ofSetColor(ofColor::green); + //ofNoFill(); + //ofDrawRectangle(r); + //ofPopStyle(); + //ofPushStyle(); + //ofSetColor(ofColor::white); + //for(const auto & b : outerBoundingBoxes){ + //int i = 0; + //for(const auto & v : b.getVertices()){ + //ofSetColor(b.getColors()[i]); + //ofDrawCircle(v, 2); + //ofDrawBitmapString(ofToString(i), 0, 0); + //i++; + //} + //b.drawVertices(); + //} + //ofFill(); + //ofPopStyle(); + } + + glDisable(GL_BLEND); +} +void GPUFontAtlasLayerCombo::draw(int width, + int height, + const shared_ptr & layer){ + OFX_PROFILER_FUNCTION(); + GLuint location; + + glm::vec2 mouse = glm::vec2(ofGetMouseX(), ofGetMouseY()); + + //glm::mat4 projection = transform.getProjectionMatrix((float)width / height); + glm::mat4 projection = transform.getOrthoProjectionMatrix(width, + height, + Transform::TOP_LEFT); + //Transform::CENTERED); + 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); + + //antiAliasingWindowSize = ofMap(ofGetMouseX(), 0, ofGetWidth(), 1, 3); + //enableSuperSamplingAntiAliasing = ofGetMouseY() > ofGetHeight() / 2; + if(font){ + OFX_PROFILER_SCOPE("draw font"); + fontShaderProgram = fontShader->program; + glUseProgram(fontShaderProgram); + + font->program = fontShaderProgram; + font->drawSetup(); + + location = glGetUniformLocation(fontShaderProgram, "projection"); + glUniformMatrix4fv(location, 1, false, glm::value_ptr(projection)); + + location = glGetUniformLocation(fontShaderProgram, "view"); + glUniformMatrix4fv(location, 1, false, glm::value_ptr(view)); + location = glGetUniformLocation(fontShaderProgram, "model"); + glUniformMatrix4fv(location, 1, false, glm::value_ptr(model)); + float z = 0; + location = glGetUniformLocation(fontShaderProgram, "z"); + glUniform1f(location, z); + + + location = glGetUniformLocation(fontShaderProgram, "antiAliasingWindowSize"); + glUniform1f(location, (float)antiAliasingWindowSize); + location = glGetUniformLocation(fontShaderProgram, "enableSuperSamplingAntiAliasing"); + glUniform1i(location, enableSuperSamplingAntiAliasing); + location = glGetUniformLocation(fontShaderProgram, "enableControlPointsVisualization"); + glUniform1i(location, enableControlPointsVisualization); + + std::vector vertices; + std::vector indices; + + vertices.resize(totalCharacters * 4); + indices.resize(totalCharacters * 6); + + std::vector outerBoundingBoxes; + ofRectangle r; + + //for(const auto & layer : layers) + { + OFX_PROFILER_SCOPE("draw layer"); + float ascender = font->getAscender(layer->getProps().fontSize_px); + ofxGPUFont::Font::BoundingBox bb; + std::vector bbs; + std::vector mirror_bbs; + float advanceY = 0; + font->collectBoundingBoxes(layer->getVariationText(), + layer->getVariationTextAppearance(), + bb, bbs, advanceY, + true, layer->getProps().fontSize_px, + layer->getProps().lineHeight); + float lineHeight = font->getLineHeight(layer->getProps().fontSize_px) * layer->getProps().lineHeight; + int n_wraps = wrapBoundingBoxes(bbs, + layer->getVariationText(), + layer->getProps().width, + lineHeight); + //if(ofGetFrameNum() % 600 == 0){ + //cout + //<< "n_wraps: " << ofToString(n_wraps) << endl + //<< "layer->getProps().width: " << ofToString(layer->getProps().width) << endl + //; + //} + //bb.p2.y += n_wraps * lineHeight; + //bb.p3.y += n_wraps * lineHeight; + glm::vec4 transformOrigin; + getAndApplyTransformOrigin(transformOrigin, + layer->getOuterNode(), + layer->getInnerNode(), + bb, + ascender, + advanceY, + layer->getProps()); + + auto bb_mirror_none = bb; + bb_mirror_none.multiply(layer->getInnerNode().getGlobalTransformMatrix()); + + mirror_bbs.push_back(std::move(bb_mirror_none)); + //layer->setBoundingBox(bb); + ofVboMesh mesh; + mesh.addVertices({bb_mirror_none.p0, + bb_mirror_none.p1, + bb_mirror_none.p2, + bb_mirror_none.p3, + glm::vec4(layer->getProps().x, layer->getProps().y, 0, 1), + transformOrigin + }); + mesh.addColors({ + ofColor::red, + ofColor::red, + ofColor::red, + ofColor::red, + ofColor::white, + ofColor::green, + }); + outerBoundingBoxes.push_back(mesh); + + if(layer->getProps().mirror_x){ + auto bbs_mirror_x = bbs; + ofNode mirrorOuterNode = layer->getOuterNode(); + ofNode mirrorInnerNode = layer->getInnerNode(); + mirrorInnerNode.setParent(mirrorOuterNode); + mirrorOuterNode.setOrientation(glm::quat(1, 0, 0, 0)); + mirrorOuterNode.rotateDeg(layer->getProps().rotation * -1, glm::vec3(0, 0, 1)); + mirrorOuterNode.setPosition(transformOrigin); + mirrorOuterNode.move(layer->getProps().mirror_x_distance * -1, 0, 0); + mirrorOuterNode.setScale(-1, 1, 1); + + auto bb_mirror_x = bb; + bb_mirror_x.multiply(mirrorInnerNode.getGlobalTransformMatrix()); + mirror_bbs.push_back(std::move(bb_mirror_x)); + font->collectVerticesAndIndices(mirrorInnerNode, + layer->getVariationTextAppearance(), + bbs_mirror_x, + vertices, + indices); + } + if(layer->getProps().mirror_y){ + auto bbs_mirror_y = bbs; + ofNode mirrorOuterNode = layer->getOuterNode(); + ofNode mirrorInnerNode = layer->getInnerNode(); + mirrorInnerNode.setParent(mirrorOuterNode); + mirrorOuterNode.setOrientation(glm::quat(1, 0, 0, 0)); + mirrorOuterNode.rotateDeg(layer->getProps().rotation * -1, glm::vec3(0, 0, 1)); + mirrorOuterNode.setPosition(transformOrigin); + mirrorOuterNode.move(0, layer->getProps().mirror_y_distance * -1, 0); + mirrorOuterNode.setScale(1, -1, 1); + + auto bb_mirror_y = bb; + bb_mirror_y.multiply(mirrorInnerNode.getGlobalTransformMatrix()); + mirror_bbs.push_back(std::move(bb_mirror_y)); + font->collectVerticesAndIndices(mirrorInnerNode, + layer->getVariationTextAppearance(), + bbs_mirror_y, + vertices, + indices); + } + if(layer->getProps().mirror_xy){ + auto bbs_mirror_xy = bbs; + ofNode mirrorOuterNode = layer->getOuterNode(); + ofNode mirrorInnerNode = layer->getInnerNode(); + mirrorInnerNode.setParent(mirrorOuterNode); + mirrorOuterNode.setOrientation(glm::quat(1, 0, 0, 0)); + mirrorOuterNode.rotateDeg(layer->getProps().rotation * 1, glm::vec3(0, 0, 1)); + mirrorOuterNode.setPosition(transformOrigin); + mirrorOuterNode.move(layer->getProps().mirror_x_distance * -1, + layer->getProps().mirror_y_distance * -1, 0); + mirrorOuterNode.setScale(-1, -1, 1); + + auto bb_mirror_xy = bb; + bb_mirror_xy.multiply(mirrorInnerNode.getGlobalTransformMatrix()); + mirror_bbs.push_back(std::move(bb_mirror_xy)); + font->collectVerticesAndIndices(mirrorInnerNode, + layer->getVariationTextAppearance(), + bbs_mirror_xy, + vertices, + indices); + } + font->collectVerticesAndIndices(layer->getInnerNode(), + layer->getVariationTextAppearance(), + bbs, + vertices, + indices); + + float min_x = FLT_MAX; + float max_x = -FLT_MAX; + float min_y = FLT_MAX; + float max_y = -FLT_MAX; + for(const auto & mbb : mirror_bbs){ + min_x = min(min_x, min(mbb.p0.x, min(mbb.p1.x, min(mbb.p2.x, mbb.p3.x)))); + max_x = max(max_x, max(mbb.p0.x, max(mbb.p1.x, max(mbb.p2.x, mbb.p3.x)))); + 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}); + + r = ofRectangle(layer->getProps().x, layer->getProps().y, layer->getProps().width, 800); + } + + { + OFX_PROFILER_SCOPE("font->draw()"); + font->draw(vertices, indices); + } + + glUseProgram(currentProgram); + //ofPushStyle(); + //ofSetColor(ofColor::green); + //ofNoFill(); + //ofDrawRectangle(r); + //ofPopStyle(); //ofPushStyle(); //ofSetColor(ofColor::white); //for(const auto & b : outerBoundingBoxes){ @@ -483,9 +721,9 @@ int GPUFontAtlasLayerCombo::wrapBoundingBoxes(std::vector width){ if(wrapIndex >= 0){ if(wrapIndex == i){ diff --git a/src/GPUFontAtlasLayerCombo.h b/src/GPUFontAtlasLayerCombo.h index 9624ce8..e4207f2 100644 --- a/src/GPUFontAtlasLayerCombo.h +++ b/src/GPUFontAtlasLayerCombo.h @@ -6,6 +6,7 @@ #include "AtlasLayerCombo.h" #include "GPUFontLayer.h" #include "ofxProfiler.h" +#include #ifdef TARGET_EMSCRIPTEN #include #include @@ -77,6 +78,8 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo { const vector > & getLayers(); void draw(int width, int height); + void draw(int width, int height, + const shared_ptr & layer); shared_ptr font; string mainText = ""; diff --git a/src/Layer.h b/src/Layer.h index 3d5c618..ce9d838 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -45,6 +45,7 @@ class Layer { float letterDelay = 0; int transformOrigin = TransformOrigin::TOP_LEFT; std::vector fontVariations; + std::map letterDelays; string text = "abc"; string fontPath = "data/celines-fonts/Version-2-var.ttf"; //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Props, diff --git a/src/LayerComposition.cpp b/src/LayerComposition.cpp index 2c66a5d..7e466df 100644 --- a/src/LayerComposition.cpp +++ b/src/LayerComposition.cpp @@ -1,6 +1,7 @@ #include "LayerComposition.h" #include "Atlas.h" #include "GPUFontAtlasLayerCombo.h" +#include "GPUFontLayer.h" #include "MsdfLayer.h" #include "Utils.h" #include "ofUtils.h" @@ -23,9 +24,9 @@ void LayerComposition::update(){ l.second->getProps().fontPath, momIdentifier.type }; - cout << "ideal mom looks like this: " << l.second->getProps().fontPath - << (momIdentifier.type == LayerType::GPUFONT ? " gpufont" : " msdfgen") - << endl; + //cout << "ideal mom looks like this: " << l.second->getProps().fontPath + //<< (momIdentifier.type == LayerType::GPUFONT ? " gpufont" : " msdfgen") + //<< endl; findOrCreateNewMomForLayer(l.second, idealMom); } } @@ -119,7 +120,6 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, layer->setup(); if(layerID == ""){ layerID = layer->getId(); - cout << "yess layerID is now " << layerID << "!" << endl; }else{ layer->setId(layerID); } @@ -176,18 +176,33 @@ shared_ptr LayerComposition::getLayer(const LayerID & layerID){ } void LayerComposition::draw(int width, int height) const { - 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); + 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); + //} + //} } const unordered_map > & LayerComposition::getAtlasLayerCombos() const { @@ -204,4 +219,8 @@ void LayerComposition::setVFlip(bool vFlip){ } } +void LayerComposition::setLayerOrder(const vector & layerOrder){ + this->layerOrder = layerOrder; +} + } diff --git a/src/LayerComposition.h b/src/LayerComposition.h index fa405dd..2b955ad 100644 --- a/src/LayerComposition.h +++ b/src/LayerComposition.h @@ -33,10 +33,13 @@ class LayerComposition { const unordered_map > & getAtlasLayerCombos() const; void setVFlip(bool vFlip); + void setLayerOrder(const vector & layerOrder); private: VFlipState vFlipState = V_FLIP_UNKNOWN; unordered_map > layers; + unordered_map > layerIDcombos; unordered_map > atlasLayerCombos; + vector layerOrder; /** * @brief lastGpuTextureOffset GL_TEXTURE0 + offset