void maDrawString(MAHandle font, const char* str, int x, int y) { MAFont* f = &fonts[font]; //int charsPerLine = f->charsetWidth/f->charWidth; //5 MARect srcRect = {0, 0, f->charWidth, f->charHeight}; MAPoint2d destPoint = {x,y}; while(*str) { calcCharPos(f, *str, &srcRect.left, &srcRect.top); maDrawImageRegion(f->handle, &srcRect, &destPoint, 0); destPoint.x += f->charWidth; str++; } }
void maDrawChar(MAHandle font, char c, int x, int y) { MAFont* f = &fonts[font]; MARect srcRect; MAPoint2d destPoint = {x,y}; int fx,fy; calcCharPos(f, c, &fx, &fy); srcRect.left = fx; srcRect.top = fy; srcRect.width = f->charWidth; srcRect.height = f->charHeight; maDrawImageRegion(f->handle, &srcRect, &destPoint, 0); }
void gpuPictoString::update(){ float w = testApp::getInstance()->getW(); float h = testApp::getInstance()->getH(); if(bNeedUpdateCharPos){ charPosList = calcCharPos(); bNeedUpdateCharPos = false; } int total = gpuPicto::totalPicto; int totalPix = textureRes*textureRes; // manual mipmap // *** should check icon size resizeIcon(h); int iconSize = prm.iconSize * h; iconSize*=0.5; if(iconSize<1){ iconSize=1; } // // nomad // bool bNomad = true; if(bNomad){ if(total>0 && ofRandom(1.0)>0.95){ if(gpchars.size()>2){ int charIndexA = (int)ofRandom(2, gpchars.size()-2); int charIndexB = charIndexA + (int)ofRandom(-2, 2); if(charIndexA!=charIndexB){ int numPictoA = gpchars[charIndexA]->numPicto; int numPictoB = gpchars[charIndexB]->numPicto; int firstIdA = gpchars[charIndexA]->firstIndex; int firstIdB = gpchars[charIndexB]->firstIndex; int indexA = ofRandom(firstIdA, numPictoA-1); int indexB = ofRandom(firstIdB, numPictoB-1); float attractOnA = springPrmData[indexA*4+3]; float attractOnB = springPrmData[indexB*4+3]; if(attractOnA<0 && attractOnB<0){ float Ax = finalTargetPosData[indexA*3 + 0]; float Ay = finalTargetPosData[indexA*3 + 1]; finalTargetPosData[indexA*3 + 0] = finalTargetPosData[indexB*3 + 0]; finalTargetPosData[indexA*3 + 1] = finalTargetPosData[indexB*3 + 1]; finalTargetPosData[indexB*3 + 0] = Ax; finalTargetPosData[indexB*3 + 1] = Ay; finalTargetTex.loadData(finalTargetPosData, textureRes, textureRes, GL_RGB); } } } } } { // offset = attractor::getPos(); const ofVec2f& attr = attractor::getPos(); float K = 20; float maxSpeed = 0.05; ofVec2f dir = attr - offset; ofVec2f acc = K * 0.000167 * dir; offsetVel += acc; offsetVel.limit(maxSpeed); offset += offsetVel; ofVec2f dirf = attr - offset; if(dirf.length() > 0.1){ offset += dirf - dirf.normalized() * 0.1; } } // // check pictoChar // bool shouldUpdateSpringTexture = false; GPICTO_STR_ITR itr = gpchars.begin(); int particleMax = textureRes*textureRes; for(; itr!=gpchars.end(); itr++){ if((*itr)->update()){ shouldUpdateSpringTexture = true; int index = (*itr)->firstIndex; int numPicto = (*itr)->numPicto; if(index<=particleMax){ for(int i=0; i<numPicto; i++){ springPrmData[index*4 + 3] = -1; // attractOn index++; if(index>particleMax){ index = 0; } } } } } if(clearCheck()){ clearAll(); bNeedUpdateCharPos = true; } if(testApp::gprm.bAutoPlay) shouldStartNextCheck(); if(shouldUpdateSpringTexture){ springPrmTex.loadData(springPrmData, textureRes, textureRes, GL_RGBA); } // // make random tex // // if(ofGetFrameNum()%3 == 0){ for(int index=0; index<total; index++){ randomData[index*3 + 0] = ofRandom(1.0); randomData[index*3 + 1] = ofRandom(1.0); randomData[index*3 + 2] = ofRandom(1.0); // randomData[index*4 + 3] = ofRandom(1.0); } randomTex.loadData(randomData, textureRes, textureRes, GL_RGB); // } // // 1. calc vel // velPingPong.dst->begin();{ ofClear(0); updateVel.begin();{ updateVel.setUniformTexture("backbuffer", velPingPong.src->getTextureReference(), 0); updateVel.setUniformTexture("posData", posPingPong.src->getTextureReference(), 1); updateVel.setUniformTexture("springData", springPrmTex, 2); updateVel.setUniformTexture("randomData", randomTex, 3); updateVel.setUniformTexture("targetData", finalTargetTex, 4); updateVel.setUniform1i("resolution", (int)textureRes); updateVel.setUniform2f("screen", (float)width, (float)height); updateVel.setUniform2f("offset", (float)offset.x, (float)offset.y); updateVel.setUniform2f("pastOffset", (float)pastOffset.x, (float)pastOffset.y); updateVel.setUniform1f("timestep", (float)timeStep); updateVel.setUniform1f("ACCEL",(float) prm.accel ); updateVel.setUniform1f("SPEED",(float) prm.speed); updateVel.setUniform1f("VIBRATION",(float) prm.vibration ); // draw the source velocity texture to be updated velPingPong.src->draw(0, 0); }updateVel.end(); }velPingPong.dst->end(); velPingPong.swap(); // // 2. calc pos // posPingPong.dst->begin();{ ofClear(0); updatePos.begin();{ updatePos.setUniformTexture("prevPosData", posPingPong.src->getTextureReference(), 0); // Previus position updatePos.setUniformTexture("velData", velPingPong.src->getTextureReference(), 1); // Velocity updatePos.setUniformTexture("springData", springPrmTex, 2); updatePos.setUniform1f("timestep",(float) timeStep ); // updatePos.setUniform2f("offset", (float)offset.x, (float)offset.y); // updatePos.setUniform2f("pastOffset", (float)pastOffset.x, (float)pastOffset.y); posPingPong.src->draw(0, 0); }updatePos.end(); }posPingPong.dst->end(); posPingPong.swap(); // // 3. render // renderFBO.begin();{ ofClear(testApp::getBackgroundColor()); // ofClear(0); //ofClear(0, 0, 0, 0); updateRender.begin();{ updateRender.setUniformTexture("posTex", posPingPong.dst->getTextureReference(), 0); updateRender.setUniformTexture("sparkTex", img->getTextureReference() , 1); updateRender.setUniformTexture("iconPrmTex", iconPrmTex, 2); updateRender.setUniformTexture("springData", springPrmTex, 3); updateRender.setUniform1i("resolution", (float)textureRes); updateRender.setUniform2f("screen", (float)testApp::getInstance()->getW(), (float)testApp::getInstance()->getH()); updateRender.setUniform1i("size", (int)iconSize); updateRender.setUniform1f("imgWidth", imgSize); updateRender.setUniform1f("imgHeight", imgSize); // updateRender.setUniform2f("offset", (float)offset.x, (float)offset.y); ofPushStyle(); //ofEnableBlendMode( OF_BLENDMODE_ADD ); ofEnableBlendMode( OF_BLENDMODE_ALPHA); ofEnableAlphaBlending(); ofEnableSmoothing(); ofSetColor(255); ofFill(); glBegin( GL_POINTS );{ int count = 0; for(int y = 0; y < textureRes; y++){ for(int x = 0; x < textureRes; x++){ if(count >= total) break; count++; glVertex2d(x,y); glTexCoord2i(x, y); } if(count >= total) break; } }glEnd(); ofPopStyle(); }updateRender.end(); if(testApp::getDebugDraw()){ { // Attractor const ofVec2f& attr = attractor::getPos(); ofFill(); ofSetColor(255, 55, 0); ofRect(attr.x*w, attr.y*h, 10, 10); ofFill(); ofSetColor(5, 255, 0); ofRect(pastOffset.x*w, pastOffset.y*h, 10, 10); ofFill(); ofSetColor(0, 5, 220); ofRect(offset.x*w, offset.y*h, 10, 10); } { // + line if(testApp::gprm.bWallMapMouseAdjust){ ofSetColor(0, 255, 0); }else{ ofSetColor(255, 0, 0); } glBegin(GL_LINES); glVertex3f(w/2, 0, 0); glVertex3f(w/2, h, 0); glVertex3f(0, h/2, 0); glVertex3f(w, h/2, 0); glVertex3f(1, 1, 0); glVertex3f(w-1, 1, 0); glVertex3f(1, h-1, 0); glVertex3f(w-1, h-1, 0); glVertex3f(1, 1, 0); glVertex3f(1, h-1, 0); glVertex3f(w-1, 1, 0); glVertex3f(w-1, h-1, 0); glVertex3f(1, 1, 0); glVertex3f(w-1, h-1, 0); glVertex3f(w-1, 1, 0); glVertex3f(1, h-1, 0); glEnd(); } } if(testApp::gprm.bShowInfo){ ofPushMatrix();{ ofTranslate(0,0); ofSetColor(ofColor(255,255,255)-testApp::gprm.bg); ofFill(); ofRect(0, 0, w, 30); ofSetColor(testApp::gprm.bg); int y = 23; ofDrawBitmapString("fps: " + ofToString(ofGetFrameRate()),20,y); ofDrawBitmapString("picto num: " + ofToString(gpuPicto::totalPicto), 200, y); ofDrawBitmapString("Frame num: " + ofToString(ofGetFrameNum()), 400, y); }ofPopMatrix(); } }renderFBO.end(); pastOffset = offset; }
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); }