#pragma once #include "Utils.h" #include "ofMain.h" #include "AtlasLayerCombo.h" #include "GPUFontLayer.h" #include "ofxProfiler.h" #ifdef TARGET_EMSCRIPTEN #include #include #endif namespace ofxVariableLab { struct GPUFontAtlasLayerComboSettings : public AtlasLayerComboSettings { int gpuTextureOffset = 0; }; class GPUFontAtlasLayerCombo : public AtlasLayerCombo { struct Transform { enum Origin { CENTERED, TOP_LEFT }; float fovy = glm::radians(60.0f); float distance = 0.42f; glm::mat3 rotation = glm::mat3(1.0f); glm::vec3 position = glm::vec3(0.0f); glm::mat4 getProjectionMatrix(float aspect){ return glm::perspective( /* fovy = */ glm::radians(60.0f), aspect, 0.002f, 12.000f); } glm::mat4 getOrthoProjectionMatrix(float w, float h, Origin origin = Origin::CENTERED){ switch(origin){ default: case Origin::CENTERED: return glm::ortho(-(w * 0.5f), (w * 0.5f), -(h * 0.5f), (h * 0.5f), 0.002f, 12.000f); break; case Origin::TOP_LEFT: return glm::ortho(0.0f, w, 0.0f, h, 0.002f, 12.000f); break; } } glm::mat4 getViewMatrix(){ auto translation = glm::translate(position); return glm::lookAt(glm::vec3(0, 0, distance), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)) * glm::mat4(rotation) * translation; } }; void getAndApplyTransformOrigin(glm::vec4 & transformOrigin, ofNode & momNode, ofNode & node, const ofxGPUFont::Font::BoundingBox & bb, const float ascender, const float advanceY, const Layer::Props & props); public: void setup(const ComboIdentifier & identifier, AtlasLayerComboSettings settings = GPUFontAtlasLayerComboSettings()) override; void update() override; void careForChild(shared_ptr layer) override; void abandonChild(shared_ptr layer) override; const ComboIdentifier & getIdentifier() const override; void setVFlip(VFlipState vFlipState) override; bool hasChildren() override; const vector > & getLayers(); void draw(); shared_ptr font; string mainText = ""; std::vector variationText; bool isDirty = false; private: GPUFontAtlasLayerComboSettings settings; FT_Library library; vector > layers; ComboIdentifier identifier; // Empty VAO used when the vertex shader has no input and only uses gl_VertexID, // because OpenGL still requires a non-zero VAO to be bound for the draw call. GLuint emptyVAO; std::unique_ptr shaderCatalog; //std::shared_ptr backgroundShader; std::shared_ptr fontShader; Transform transform; // Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays. // 0 - no anti-aliasing // 1 - normal anti-aliasing // >=2 - exaggerated effect int antiAliasingWindowSize = 1; // Enable a second ray along the y-axis to achieve 2-dimensional anti-aliasing. bool enableSuperSamplingAntiAliasing = true; // Draw control points for debugging (green - on curve, magenta - off curve). bool enableControlPointsVisualization = false; GLuint fontShaderProgram; std::vector fontVariationAxesParameters; std::vector fontVariationAxes; VFlipState vFlip; int totalCharacters = 0; }; }