void gpuPictoString::draw(){ ofSetColor(255); ofNoFill(); { renderFBO.draw(0,0); //texadv.draw(); } if(testApp::getDebugDraw()){ if(false){ // FBO check float scale = getFontScale(); float lineHeightScaled = font.getLineHeight()*scale; GPICTO_STR_ITR itr = gpchars.begin(); int particleMax = textureRes*textureRes; ofSetColor(255); for(; itr!=gpchars.end(); itr++){ ofVec2f& pos = (*itr)->charPos; glPushMatrix(); glTranslatef(pos.x, pos.y, 0); (*itr)->drawFbo(); glPopMatrix(); } } } }
void gpuPictoString::drawPreview(){ ofPushStyle(); glPushAttrib(GL_ALL_ATTRIB_BITS); ofBackground(255); int w = testApp::getW(); int h = testApp::getH(); float screenScalex = 305.0/(float)w; float screenScaley = 183.0/(float)h; float scale = getFontScale(); float fh = font.getLineHeight(); // ???? glPushMatrix();{ glScalef(screenScalex, screenScaley, 1); for(int i=0; i<charPosList.size(); i++){ ofVec3f& xyc = charPosList[i]; char c = (char)xyc.z; int find = alphabet.find(c); if(find == -1 || c == '\302' || c == '\245'){ // cout << "skip " << c << endl; continue; }else{ // cout << "make " << c << endl; } glPushMatrix();{ glTranslatef(xyc.x, xyc.y, 0); ofNoFill(); ofSetColor(120); glScalef(scale, scale, 1); /* Here, Font y position (fh * 1.2) Sohuld use same value with gpuPictoChar::getFinalTarget DO NOT USE font.drawString() This will make app crash. I think due to Cocoa multiple GL view (and shaders). */ font.drawStringAsShapes(ofToString(c), 0, fh*1.2); // ofRect(10, 10, 100, 100); }glPopMatrix(); } ofSetColor(0, 0, 255); glBegin(GL_LINES); glVertex3f(w/2, 0, 0); glVertex3f(w/2, h, 0); glVertex3f(0, h/2, 0); glVertex3f(w, h/2, 0); glEnd(); }glPopMatrix(); glPopAttrib(); ofPopStyle(); }
vector<ofVec3f> gpuPictoString::calcCharPos(){ string s = prm.message; int w = testApp::getInstance()->getW(); int h = testApp::getInstance()->getH(); float fontScale = getFontScale(); // font のLineHeightに影響されない float height1 = font.getCharProps('1').height; font.setLetterSpacing(prm.letterSpacing); font.setLineHeight(prm.lineHeight*height1); vector<string> lines = ofSplitString(s, "\n"); vector<float> offsetXs; for (int i=0; i<lines.size(); i++) { float sw = font.stringWidth(lines[i]) * fontScale * 0.5; offsetXs.push_back(sw); } int lineNum = 0; int posx = w/2 - offsetXs[lineNum]; int posy = 0; float lineHeight = font.getLineHeight() * fontScale; float letterSpacing = font.getLetterSpacing(); float letterHeight = height1 * fontScale; vector<ofVec2f> ps1, ps2, ps3; vector<ofVec3f> charPosList; for(int i=0; i<s.size(); i++){ char c = s.at(i); float charw = 0; if(c!='\n') charw = font.getCharProps(c).setWidth * letterSpacing * fontScale; // if(posx > w - charw){ // lineNum++; // posx = w/2 - offsetXs[lineNum]; // posy += lineHeight; // } ofVec3f charPos(posx, posy, (int)c); charPosList.push_back(charPos); if(c == '\n'){ lineNum++; posx = w/2 - offsetXs[lineNum]; posy += lineHeight; continue; }else{ posx += charw; } } return charPosList; }
bool Renderer::requestRendering() { auto s = getSource(); if (!_enabled || _renderingInProgress || _surfaceSize.equals(cocos2d::Size::ZERO) || !s) { return false; } font::Source *fontSet = nullptr; Document *document = nullptr; if (s->isReady()) { fontSet = s->getSource(); document = s->getDocument(); } if (fontSet && document) { auto media = _media; media.fontScale = s->getFontScale(); media.pageMargin = _pageMargin; if (_isPageSplitted) { media.flags |= RenderFlag::SplitPages; } Builder * impl = new Builder(document, media, fontSet, _ids); impl->setHyphens(_hyphens); _renderingInProgress = true; if (_renderingCallback) { _renderingCallback(nullptr, true); } retain(); auto &thread = resource::thread(); thread.perform([impl] (cocos2d::Ref *) -> bool { // auto now = Time::now(); impl->render(); // TimeInterval all = (Time::now() - now); // log::format("Profiling", "Result rendering: %lu (%lu reader %lu other)", all.toMicroseconds(), // impl->getReaderTime().toMicroseconds(), (all - impl->getReaderTime()).toMicroseconds()); return true; }, [this, impl] (cocos2d::Ref *, bool) { auto result = impl->getResult(); //log::format("Result size:", "%lu %d %d %d", result->getSizeInMemory(), sizeof(font::CharSpec), sizeof(font::LineSpec), sizeof(font::RangeSpec)); if (result) { onResult(result); } release(); delete impl; }, this); _renderingDirty = false; } return false; }
void gpuPictoString::makeAnimation(){ bClear = false; bNeedUpdateCharPos = true; clearAll(); finalTargets.clear(); gpuPicto::totalPicto = 0; offset.set(ofRandom(0.0,1.0),ofRandom(0.1,0.9)); pastOffset = offset; offsetVel.set(ofRandom(-0.5,0.5),ofRandom(-0.5,0.5)); float w = testApp::getInstance()->getW(); float h = testApp::getInstance()->getH(); int time = 0; { // attractor ofVec2f randL = ofVec2f( ofRandom(0.2, 0.3), ofRandom(0.55, 0.70)); ofVec2f randR = ofVec2f( ofRandom(0.7, 0.8), ofRandom(0.55, 0.70)); attractor::addAttraction(time, randL); time += 1500; attractor::addAttraction(time, randR); // time += 1500; // attractor::addAttraction(time, randL); } // if(bNeedUpdateCharPos){ charPosList = calcCharPos(); bNeedUpdateCharPos = false; // } float fontScale = getFontScale(); float lineHeight = font.getLineHeight() * fontScale; float letterHeight = font.stringHeight("1") * fontScale; float res = lineHeight * (0.21-prm.iconDensity); float rand = lineHeight * prm.fontRandomness; if(res<=0)res=0.2; int index = 0; // cout << endl << "Start Make Pictograph " << endl; char c; char pastc = ' '; ofVec2f posMainPoint(ofRandom(0.0, 1.0), ofRandom(0.3, 0.9)); ofVec2f velMainDir(ofRandom(-0.2, 0.2), ofRandom(-0.3, 0.3)); int finalSpreadFrame = 0; for(int i=0; i<charPosList.size(); i++){ if(gpuPicto::totalPicto>=numParticles) break; ofVec3f xyc = charPosList[i]; c = (char)xyc.z; int find = alphabet.find(c); if(find == -1 || c == '\302' || c == '\245'){ // cout << "skip " << c << endl; continue; }else{ // cout << "make " << c << endl; } if(c != ' ' && c!='\n'){ gpuPictoChar * gpchar = new gpuPictoChar(c, xyc.x, xyc.y, this); gpchars.push_back(gpchar); // target gpchar->getFinalTarget(font, getFontScale(), res, rand, finalTargets); int n = gpchar->numPicto; for (int j=0; j<n; j++) { if(gpuPicto::totalPicto>=numParticles) break; gpuPicto::totalPicto++; // target finalTargetPosData[index*3 ] = (xyc.x + finalTargets[index*3 ]) / w; finalTargetPosData[index*3 + 1] = (xyc.y + finalTargets[index*3 + 1]) / h; finalTargetPosData[index*3 + 2] = 0; // pos float radian = ofRandom(0.0, 360.0)/360.0 * TWO_PI; float length = ofRandom(0.001, 0.1); if(length<0.5){length+=ofRandom(0.001, 0.04);} posData[index*3 ] = cos(radian) * length*1.33 + posMainPoint.x; posData[index*3 + 1] = sin(radian) * length + posMainPoint.y; posData[index*3 + 2] = ofRandom(0.1, 0.2); // alpha // vel velData[index*4 ] = velMainDir.x + ofRandom(-0.02, 0.02); velData[index*4 + 1] = velMainDir.y + ofRandom(-0.02, 0.02); velData[index*4 + 2] = 0; velData[index*4 + 3] = 0; // icon iconPrmData[index*4 + 0] = ofRandom(0,5) * 0.01; iconPrmData[index*4 + 1] = ofRandom(0,numIcon) * 0.01; // iconType 0-0.43 iconPrmData[index*4 + 2] = 0.0; iconPrmData[index*4 + 3] = 0.0; //spring springPrmData[index*4 + 3] = 1; // attractOn index++; } // attractor if(i<=1){ time += 3000; }else{ time += 300; } attractor::addAttraction(time, ofVec2f((xyc.x/w - 0.5)*1.2 + 0.5, (xyc.y+lineHeight-letterHeight*0.5)/h) ); int nowf = ofGetFrameNum(); gpchar->spreadFrame = nowf + (float)(time+200)/1000.0*60.0; //cout << "set spread frame: " << gpchar->spreadFrame << endl; finalSpreadFrame = gpchar->spreadFrame; } if(c =='\n'){ time += 800; }else if(pastc=='\n'){ time += 1500; } pastc = c; } int readable_ending_estimated_frame = 500; int holdFrame = (float)prm.holdTime/1000*60.0; clearFrame = finalSpreadFrame + holdFrame + readable_ending_estimated_frame; shouldStartNextFrame = clearFrame + 500; // shuffle // { // cout << "index = " << index << endl; // for(int i=0; i<index; i++){ // int rind = ofRandom(0,index); // float f1 = iconPrmData[i*4 +1]; // float f2 = iconPrmData[rind*4 +1]; // cout << "f1= " << f1 << ", f2= " << f2 << endl; // // iconPrmData[i*4 + 1] = f2; // iconPrmData[rind*4 +1] = f1; // } // // for(int i=0; i<index; i++){ // cout << iconPrmData[i*4 + 1] << endl; // } // } int total = gpuPicto::totalPicto; int pixTotal = textureRes * textureRes; finalTargetTex.loadData(finalTargetPosData, textureRes, textureRes, GL_RGB); iconPrmTex.loadData(iconPrmData, textureRes, textureRes, GL_RGBA); springPrmTex.loadData(springPrmData, textureRes, textureRes, GL_RGBA); posPingPong.src->getTextureReference().loadData(posData, textureRes, textureRes, GL_RGB); posPingPong.dst->getTextureReference().loadData(posData, textureRes, textureRes, GL_RGB); velPingPong.src->getTextureReference().loadData(velData, textureRes, textureRes, GL_RGBA); velPingPong.dst->getTextureReference().loadData(velData, textureRes, textureRes, GL_RGBA); }