ofxVariableLab/src/Layer.cpp

174 lines
6.2 KiB
C++
Raw Normal View History

2023-03-19 12:04:47 +01:00
#include "Layer.h"
2023-03-26 21:19:37 +02:00
#include "conversion.h"
2023-03-25 13:51:04 +01:00
#include "ofAppRunner.h"
#include "ofGraphics.h"
2023-03-26 21:19:37 +02:00
#include "ofUtils.h"
2023-03-25 13:51:04 +01:00
namespace ofxVariableLab {
Layer::Layer(){
}
Layer::~Layer(){
}
MsdfLayer::MsdfLayer(){
}
MsdfLayer::~MsdfLayer(){
}
void Layer::update(){
2023-03-26 21:19:37 +02:00
if(isDirty){
2023-03-25 13:51:04 +01:00
2023-03-26 21:19:37 +02:00
isDirty = false;
}
2023-03-25 13:51:04 +01:00
}
2023-03-26 21:19:37 +02:00
void MsdfLayer::draw(glm::vec3 position) const {
const ofImage & atlasImage = atlas->getAtlasImage();
2023-03-25 13:51:04 +01:00
ofDisableAlphaBlending();
ofEnableDepthTest();
float pixelRange = 2;
2023-03-26 21:19:37 +02:00
int atlas_w = atlasImage.getWidth();
int atlas_h = atlasImage.getHeight();
2023-03-25 13:51:04 +01:00
int atlas_x = 0;
int atlas_y = 0;
glm::vec2 unitRange = glm::vec2(pixelRange) / glm::vec2(atlas_w, atlas_h);
2023-03-30 16:22:35 +02:00
shader->begin();
shader->setUniformTexture("msdf", atlasImage.getTexture(), 0);
shader->setUniform4f("fontColor", ofFloatColor::white);
2023-03-25 13:51:04 +01:00
shader->setUniform2f("unitRange", unitRange);
shader->end();
2023-03-26 21:19:37 +02:00
ofPushMatrix();
ofTranslate(position);
ofPushStyle();
ofSetColor(ofColor::pink);
ofDrawLine(glm::vec2(0, 0), glm::vec2(ofGetWidth(), 0));
ofPopStyle();
2023-03-28 19:18:45 +02:00
char previous_c;
bool firstLetter = true;
2023-03-30 16:22:35 +02:00
// set variation axis
const float swing_sin = sin(ofGetElapsedTimef() * 1);
const float swing_01 = ofMap(swing_sin, -1, 1, 0, 1);
const vector <ofxMsdfgen::FontVariationAxis> & variationAxisAvailable = atlas->getVariationAxesAvailable();
const string var_name = variationAxisAvailable[0].name;
const float var_value = ofMap(swing_01, 0, 1,
variationAxisAvailable[0].minValue,
variationAxisAvailable[0].maxValue);
int i = 0;
2023-03-26 21:19:37 +02:00
for(const char c : propsBuffer[0].text){
2023-03-30 16:22:35 +02:00
float mix = -1;
ofxMsdfgen::GlyphGeometry gg_a;
ofxMsdfgen::GlyphGeometry gg_b;
bool success = atlas->getGlyphGeometryPair(c,
{var_name, var_value},
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){
2023-03-26 21:19:37 +02:00
// FIXME: make sure this does not happen
ofLogError("MsdfLayer::draw") << "y smaller 0, this is not good" << endl;
}
ofPushStyle();
2023-03-30 16:22:35 +02:00
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);
2023-03-26 21:19:37 +02:00
2023-03-30 16:22:35 +02:00
double advance_a = gg_a.getAdvance();
double advance_b = gg_b.getAdvance();
2023-03-26 21:19:37 +02:00
2023-03-30 16:22:35 +02:00
float x = glm::mix(float(x_a), float(x_b), mix);
float y = glm::mix(float(y_a), float(y_b), mix);
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 pb = glm::mix(float(pb_a), float(pb_b), mix);
//float pr = glm::mix(float(pr_a), float(pr_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;
2023-03-26 21:19:37 +02:00
ofSetColor(ofFloatColor(1, 1, 1, 1));
2023-03-28 17:48:18 +02:00
ofTranslate(pl * magic, 0, 0);
ofTranslate(0, -1 * pt * magic, 0);
2023-03-30 16:22:35 +02:00
//msdf_atlas::unicode_t a = static_cast <msdf_atlas::unicode_t>(previous_c);
//msdf_atlas::unicode_t b = static_cast <msdf_atlas::unicode_t>(c);
2023-03-28 19:18:45 +02:00
if(!firstLetter){
//cout << "this is being printed" << endl;
auto & fontGeometry = atlas->getFontGeometry();
const std::map <std::pair <int, int>, double> kerning = fontGeometry.getKerning();
ofxMsdfgen::GlyphGeometry gg_previous = atlas->getGlyphGeometry(c);
2023-03-30 16:22:35 +02:00
std::map <std::pair <int, int>, double>::const_iterator it = kerning.find(std::make_pair <int, int>(gg_previous.getIndex(), gg_a.getIndex()));
2023-03-28 19:18:45 +02:00
if(it != kerning.end()){
2023-03-29 20:46:54 +02:00
advance += it->second;
ofDrawBitmapStringHighlight(ofToString(it->second), 0, 200, ofColor::black, ofColor::pink);
2023-03-28 19:18:45 +02:00
}
}
2023-03-30 16:22:35 +02:00
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));
//if(firstLetter){
//cout << "translation_a: " << ofToString(translation_a) << endl;
//cout << "scale_a: " << ofToString(scale_a) << endl;
//}
shader->begin();
shader->setUniform4f("fontColor", ofFloatColor::yellow);
shader->setUniform2f("translation_a", translation_a);
shader->setUniform2f("scale_a", scale_a);
shader->setUniform2f("translation_b", translation_b);
shader->setUniform2f("scale_b", scale_b);
shader->setUniform1f("msdf_mix", mix);
atlasImage.draw(0, 0, w, h);
2023-03-26 21:19:37 +02:00
shader->end();
ofPopMatrix();
ofPopStyle();
2023-03-28 19:18:45 +02:00
ofTranslate(advance * magic, 0, 0);
ofTranslate(-1 * pl * magic, 0, 0);
previous_c = c;
2023-03-30 16:22:35 +02:00
if(firstLetter){
firstLetter = false;
}
i++;
2023-03-26 21:19:37 +02:00
}
ofPopMatrix();
2023-03-25 13:51:04 +01:00
ofDisableDepthTest();
ofEnableAlphaBlending();
}
void Layer::setProps(const Props & props){
while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){
propsBuffer.pop_back();
}
propsBuffer.push_front(props);
}
2023-03-29 20:46:54 +02:00
const Layer::Props & Layer::getProps() const {
return propsBuffer[0];
}
2023-03-25 13:51:04 +01:00
void Layer::clearPropsBuffer(){
propsBuffer.clear();
}
void Layer::setId(const string & id){
this->id = id;
}
const string & Layer::getId(){
return id;
}
}