// see drawSubsection void mui::TextureAtlas::addSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh){ GLfloat px0 = x; // up to you to get the aspect ratio right GLfloat py0 = y; GLfloat px1 = w+x; GLfloat py1 = h+y; if (tex.texData.bFlipTexture == ofIsVFlipped()){ swap(py0,py1); } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 -= w/2; py0 -= h/2; px1 -= w/2; py1 -= h/2; } // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. GLfloat offsetw = 0.0f; GLfloat offseth = 0.0f; if (!ofGLSupportsNPOTTextures() && ofIsTextureEdgeHackEnabled()) { offsetw = 1.0f / (tex.texData.tex_w); offseth = 1.0f / (tex.texData.tex_h); } // ------------------------------------------------- ofPoint topLeft = tex.getCoordFromPoint(sx, sy); ofPoint bottomRight = tex.getCoordFromPoint(sx + sw, sy + sh); GLfloat tx0 = topLeft.x + offsetw; GLfloat ty0 = topLeft.y + offseth; GLfloat tx1 = bottomRight.x - offsetw; GLfloat ty1 = bottomRight.y - offseth; add.addVertex(ofVec3f(px0,py0,z)); add.addVertex(ofVec3f(px1,py0,z)); add.addVertex(ofVec3f(px1,py1,z)); add.addVertex(ofVec3f(px0,py0,z)); add.addVertex(ofVec3f(px1,py1,z)); add.addVertex(ofVec3f(px0,py1,z)); add.addTexCoord(ofVec3f(tx0,ty0)); add.addTexCoord(ofVec3f(tx1,ty0)); add.addTexCoord(ofVec3f(tx1,ty1)); add.addTexCoord(ofVec3f(tx0,ty0)); add.addTexCoord(ofVec3f(tx1,ty1)); add.addTexCoord(ofVec3f(tx0,ty1)); }
void ofTrueTypeFont::createStringMesh(string c, float x, float y){ GLint index = 0; GLfloat X = x; GLfloat Y = y; int newLineDirection = 1; if(!ofIsVFlipped()){ // this would align multiline texts to the last line when vflip is disabled //int lines = ofStringTimesInString(c,"\n"); //Y = lines*lineHeight; newLineDirection = -1; } int len = (int)c.length(); while(index < len){ int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { Y += lineHeight*newLineDirection; X = x ; //reset X Pos back to zero }else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; X += cps[cy].setWidth * letterSpacing * spaceSize; } else if(cy > -1){ drawChar(cy, X, Y); X += cps[cy].setWidth * letterSpacing; } } index++; } }
//===================================================================== void ofTrueTypeFont::drawStringAsShapes(string c, float x, float y) { if (!bLoadedOk){ ofLogError("ofTrueTypeFont") << "drawStringAsShapes(): font not allocated: line " << __LINE__ << " in " << __FILE__; return; }; //----------------------- error checking if (!bMakeContours){ ofLogError("ofTrueTypeFont") << "drawStringAsShapes(): contours not created for this font, call loadFont() with makeContours set to true"; return; } if(bFullCharacterSet && encoding==OF_ENCODING_UTF8){ string o; Poco::TextConverter(Poco::UTF8Encoding(),Poco::Latin9Encoding()).convert(c,o); c=o; } GLint index = 0; GLfloat X = x; GLfloat Y = y; int newLineDirection = 1; if(!ofIsVFlipped()){ // this would align multiline texts to the last line when vflip is disabled //int lines = ofStringTimesInString(c,"\n"); //Y = lines*lineHeight; newLineDirection = -1; } int len = (int)c.length(); while(index < len){ int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { Y += lineHeight*newLineDirection; X = x ; //reset X Pos back to zero }else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; X += cps[cy].setWidth * letterSpacing * spaceSize; //glTranslated(cps[cy].width, 0, 0); } else if(cy > -1){ drawCharAsShape((unsigned char)c[index], X, Y); X += cps[cy].setWidth * letterSpacing; //glTranslated(cps[cy].setWidth, 0, 0); } } index++; } }
//----------------------------------------------------------- void ofTrueTypeFont::drawStringAsShapes(const std::string& str, float x, float y) const{ if (!bLoadedOk){ ofLogError("ofTrueTypeFont") << "drawStringAsShapes(): font not allocated: line " << __LINE__ << " in " << __FILE__; return; }; //----------------------- error checking if (!settings.contours){ ofLogError("ofTrueTypeFont") << "drawStringAsShapes(): contours not created for this font, call loadFont() with makeContours set to true"; return; } iterateString(str,x,y,true,[&](uint32_t c, ofVec2f pos){ drawCharAsShape(c, pos.x, pos.y, ofIsVFlipped(), ofGetStyle().bFill); }); }
//----------------------------------------------------------- void ofTrueTypeFont::drawChar(int c, float x, float y) { if (c >= nCharacters){ //ofLogError("ofTrueTypeFont") << "drawChar(): char " << c + NUM_CHARACTER_TO_START << " not allocated: line " << __LINE__ << " in " << __FILE__; return; } int xmin, ymin, xmax, ymax; float t1, v1, t2, v2; t2 = cps[c].t2; v2 = cps[c].v2; t1 = cps[c].t1; v1 = cps[c].v1; xmin = cps[c].xmin+x; ymin = cps[c].ymin; xmax = cps[c].xmax+x; ymax = cps[c].ymax; if(!ofIsVFlipped()){ ymin *= -1; ymax *= -1; } ymin += y; ymax += y; int firstIndex = stringQuads.getVertices().size(); stringQuads.addVertex(ofVec3f(xmin,ymin)); stringQuads.addVertex(ofVec3f(xmax,ymin)); stringQuads.addVertex(ofVec3f(xmax,ymax)); stringQuads.addVertex(ofVec3f(xmin,ymax)); stringQuads.addTexCoord(ofVec2f(t1,v1)); stringQuads.addTexCoord(ofVec2f(t2,v1)); stringQuads.addTexCoord(ofVec2f(t2,v2)); stringQuads.addTexCoord(ofVec2f(t1,v2)); stringQuads.addIndex(firstIndex); stringQuads.addIndex(firstIndex+1); stringQuads.addIndex(firstIndex+2); stringQuads.addIndex(firstIndex+2); stringQuads.addIndex(firstIndex+3); stringQuads.addIndex(firstIndex); }
//----------------------------------------------------------- void ofTrueTypeFont::drawCharAsShape(int c, float x, float y) { if (c - NUM_CHARACTER_TO_START >= nCharacters || c < NUM_CHARACTER_TO_START){ //ofLogError("ofTrueTypeFont") << "drawCharAsShape(): char " << << c + NUM_CHARACTER_TO_START << " not allocated: line " << __LINE__ << " in " << __FILE__; return; } //----------------------- if(ofIsVFlipped()){ ofTTFCharacter & charRef = charOutlines[c - NUM_CHARACTER_TO_START]; charRef.setFilled(ofGetStyle().bFill); charRef.draw(x,y); }else{ ofTTFCharacter & charRef = charOutlinesNonVFlipped[c - NUM_CHARACTER_TO_START]; charRef.setFilled(ofGetStyle().bFill); charRef.draw(x,y); } }
//----------------------------------------------------------- void ofTrueTypeFont::drawChar(int c, float x, float y) { if (c >= nCharacters){ //ofLogError("ofTrueTypeFont") << "drawChar(): char " << c + NUM_CHARACTER_TO_START << " not allocated: line " << __LINE__ << " in " << __FILE__; return; } GLfloat x1, y1, x2, y2; GLfloat t1, v1, t2, v2; t2 = cps[c].t2; v2 = cps[c].v2; t1 = cps[c].t1; v1 = cps[c].v1; x1 = cps[c].x1+x; y1 = cps[c].y1; x2 = cps[c].x2+x; y2 = cps[c].y2; int firstIndex = stringQuads.getVertices().size(); if(!ofIsVFlipped()){ y1 *= -1; y2 *= -1; } y1 += y; y2 += y; stringQuads.addVertex(ofVec3f(x1,y1)); stringQuads.addVertex(ofVec3f(x2,y1)); stringQuads.addVertex(ofVec3f(x2,y2)); stringQuads.addVertex(ofVec3f(x1,y2)); stringQuads.addTexCoord(ofVec2f(t1,v1)); stringQuads.addTexCoord(ofVec2f(t2,v1)); stringQuads.addTexCoord(ofVec2f(t2,v2)); stringQuads.addTexCoord(ofVec2f(t1,v2)); stringQuads.addIndex(firstIndex); stringQuads.addIndex(firstIndex+1); stringQuads.addIndex(firstIndex+2); stringQuads.addIndex(firstIndex+2); stringQuads.addIndex(firstIndex+3); stringQuads.addIndex(firstIndex); }
//--------------------------------------------------------------------- void ofDrawBitmapCharacter(int character, int x , int y){ if(!bBitmapTexturePrepared){ prepareBitmapTexture(); } if (character < 128) { float posTexW = (float)(character % 16)/16.0f; float posTexH = ((int)(character / 16.0f))/16.0f; float texY1 = posTexH; float texY2 = posTexH+heightTex; //TODO: look into a better fix. //old ofDrawBitmapString was 3 pixels higher, so this version renders text in a different position. //3 pixel adjustment corrects that when y is flpped 5 when it's not. int yOffset = 14; if(!ofIsVFlipped()){ y += 5; y += yOffset; yOffset *= -1; }else{ y -= 3; } charMesh.getTexCoords()[vC].set(posTexW,texY1); charMesh.getTexCoords()[vC+1].set(posTexW + widthTex,texY1); charMesh.getTexCoords()[vC+2].set(posTexW+widthTex,texY2); charMesh.getTexCoords()[vC+3].set(posTexW + widthTex,texY2); charMesh.getTexCoords()[vC+4].set(posTexW,texY2); charMesh.getTexCoords()[vC+5].set(posTexW,texY1); charMesh.getVertices()[vC].set(x,y); charMesh.getVertices()[vC+1].set(x+8,y); charMesh.getVertices()[vC+2].set(x+8,y+yOffset); charMesh.getVertices()[vC+3].set(x+8,y+yOffset); charMesh.getVertices()[vC+4].set(x,y+yOffset); charMesh.getVertices()[vC+5].set(x,y); vC += 6; } }
void ofImage_<PixelType>::grabScreen(int _x, int _y, int _w, int _h){ allocate(_w, _h, OF_IMAGE_COLOR); int sh = ofGetViewportHeight(); // if we are in a FBO or other viewport, this fails: ofGetHeight(); #ifndef TARGET_OPENGLES if(ofIsVFlipped()){ _y = sh - _y; _y -= _h; // top, bottom issues } glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); // be nice to anyone else who might use pixelStore glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(_x, _y, _w, _h, ofGetGlFormat(pixels), GL_UNSIGNED_BYTE, pixels.getPixels()); // read the memory.... glPopClientAttrib(); int sizeOfOneLineOfPixels = pixels.getWidth() * pixels.getBytesPerPixel(); PixelType * tempLineOfPix = new PixelType[sizeOfOneLineOfPixels]; PixelType * linea; PixelType * lineb; for (int i = 0; i < pixels.getHeight()/2; i++){ linea = pixels.getPixels() + i * sizeOfOneLineOfPixels; lineb = pixels.getPixels() + (pixels.getHeight()-i-1) * sizeOfOneLineOfPixels; memcpy(tempLineOfPix, linea, sizeOfOneLineOfPixels); memcpy(linea, lineb, sizeOfOneLineOfPixels); memcpy(lineb, tempLineOfPix, sizeOfOneLineOfPixels); } delete [] tempLineOfPix; #else int sw = ofGetViewportWidth(); int numPixels = width*height; if( numPixels == 0 ){ ofLogError("ofImage") << "grabScreen(): unable to grab screen, image width and/or height are 0: " << width << "x" << height; return; } int numRGBA = numPixels*4; GLubyte *bufferRGBA = (GLubyte *) malloc(numRGBA); if(ofGetOrientation() == OF_ORIENTATION_DEFAULT || ofDoesHWOrientation()) { if(ofIsVFlipped()){ _y = sh - _y; // screen is flipped vertically. _y -= _h; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(_x, _y, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, bufferRGBA); for(int y = 0; y < _h; y++){ for(int x = 0; x < _w; x++){ int i = y * _w * 3 + x * 3; int j = (_h-1-y) * _w * 4 + x * 4; // rotate 90. pixels.getPixels()[i] = bufferRGBA[j]; pixels.getPixels()[i+1] = bufferRGBA[j+1]; pixels.getPixels()[i+2] = bufferRGBA[j+2]; } } } else if(ofGetOrientation() == OF_ORIENTATION_180) { if(ofIsVFlipped()){ _x = sw - _x; // screen is flipped horizontally. _x -= _w; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(_x, _y, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, bufferRGBA); for(int y = 0; y < _h; y++){ for(int x = 0; x < _w; x++){ int i = y * _w * 3 + x * 3; int j = y * _w * 4 + (_w-1-x) * 4; // rotate 90. pixels.getPixels()[i] = bufferRGBA[j]; pixels.getPixels()[i+1] = bufferRGBA[j+1]; pixels.getPixels()[i+2] = bufferRGBA[j+2]; } } } else if(ofGetOrientation() == OF_ORIENTATION_90_RIGHT) { swap(_w,_h); swap(_x,_y); if(!ofIsVFlipped()){ _x = sw - _x; // screen is flipped horizontally. _x -= _w; _y = sh - _y; // screen is flipped vertically. _y -= _h; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(_x, _y, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, bufferRGBA); for(int y = 0; y < _h; y++){ for(int x = 0; x < _w; x++){ int i = x * _h * 3 + y * 3; int j = y * _w * 4 + x * 4; pixels.getPixels()[i] = bufferRGBA[j]; pixels.getPixels()[i+1] = bufferRGBA[j+1]; pixels.getPixels()[i+2] = bufferRGBA[j+2]; } } } else if(ofGetOrientation() == OF_ORIENTATION_90_LEFT) { swap(_w, _h); swap(_x, _y); if(ofIsVFlipped()){ _x = sw - _x; // screen is flipped horizontally. _x -= _w; _y = sh - _y; // screen is flipped vertically. _y -= _h; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(_x, _y, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, bufferRGBA); for(int y = 0; y < _h; y++){ for(int x = 0; x < _w; x++){ int i = x * _h * 3 + y * 3; int j = (_h-1-y) * _w * 4 + (_w-1-x) * 4; pixels.getPixels()[i] = bufferRGBA[j]; pixels.getPixels()[i+1] = bufferRGBA[j+1]; pixels.getPixels()[i+2] = bufferRGBA[j+2]; } } } free(bufferRGBA); #endif update(); }
// copied almost directly from ofTexture.cpp // changes: // - no anchor point support (doesn't make sense) // - removed bind/unbind/activetex //---------------------------------------------------------- void mui::TextureAtlas::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) { GLfloat px0 = x; // up to you to get the aspect ratio right GLfloat py0 = y; GLfloat px1 = w+x; GLfloat py1 = h+y; if (tex.texData.bFlipTexture == ofIsVFlipped()){ swap(py0,py1); } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 -= w/2; py0 -= h/2; px1 -= w/2; py1 -= h/2; } //we translate our drawing points by our anchor point. //we still respect ofRectMode so if you have rect mode set to //OF_RECTMODE_CENTER your anchor will be relative to that. GLfloat anchorX; GLfloat anchorY; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. GLfloat offsetw = 0.0f; GLfloat offseth = 0.0f; if (!ofGLSupportsNPOTTextures() && ofIsTextureEdgeHackEnabled()) { offsetw = 1.0f / (tex.texData.tex_w); offseth = 1.0f / (tex.texData.tex_h); } // ------------------------------------------------- ofPoint topLeft = tex.getCoordFromPoint(sx, sy); ofPoint bottomRight = tex.getCoordFromPoint(sx + sw, sy + sh); GLfloat tx0 = topLeft.x + offsetw; GLfloat ty0 = topLeft.y + offseth; GLfloat tx1 = bottomRight.x - offsetw; GLfloat ty1 = bottomRight.y - offseth; /*if(z>0 || z<0){ ofPushMatrix(); ofTranslate(0,0,z); }*/ quad.getVertices()[0].set(px0,py0,z); quad.getVertices()[1].set(px1,py0,z); quad.getVertices()[2].set(px1,py1,z); quad.getVertices()[3].set(px0,py1,z); quad.getTexCoords()[0].set(tx0,ty0); quad.getTexCoords()[1].set(tx1,ty0); quad.getTexCoords()[2].set(tx1,ty1); quad.getTexCoords()[3].set(tx0,ty1); quad.draw(); }
//---------------------------------------------------------- void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) { if(!texData.bAllocated){ return; } GLfloat px0 = x; // up to you to get the aspect ratio right GLfloat py0 = y; GLfloat px1 = w+x; GLfloat py1 = h+y; if (texData.bFlipTexture == ofIsVFlipped()){ swap(py0,py1); } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 -= w/2; py0 -= h/2; px1 -= w/2; py1 -= h/2; } //we translate our drawing points by our anchor point. //we still respect ofRectMode so if you have rect mode set to //OF_RECTMODE_CENTER your anchor will be relative to that. GLfloat anchorX; GLfloat anchorY; if(bAnchorIsPct){ anchorX = anchor.x * w; anchorY = anchor.y * h; }else{ anchorX = anchor.x; anchorY = anchor.y; } px0 -= anchorX; py0 -= anchorY; px1 -= anchorX; py1 -= anchorY; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. GLfloat offsetw = 0.0f; GLfloat offseth = 0.0f; if (!ofGLSupportsNPOTTextures() && bTexHackEnabled) { offsetw = 1.0f / (texData.tex_w); offseth = 1.0f / (texData.tex_h); } // ------------------------------------------------- ofPoint topLeft = getCoordFromPoint(sx, sy); ofPoint bottomRight = getCoordFromPoint(sx + sw, sy + sh); GLfloat tx0 = topLeft.x + offsetw; GLfloat ty0 = topLeft.y + offseth; GLfloat tx1 = bottomRight.x - offsetw; GLfloat ty1 = bottomRight.y - offseth; quad.getVertices()[0].set(px0,py0,z); quad.getVertices()[1].set(px1,py0,z); quad.getVertices()[2].set(px1,py1,z); quad.getVertices()[3].set(px0,py1,z); quad.getTexCoords()[0].set(tx0,ty0); quad.getTexCoords()[1].set(tx1,ty0); quad.getTexCoords()[2].set(tx1,ty1); quad.getTexCoords()[3].set(tx0,ty1); // make sure we are on unit 0 - we may change this when setting shader samplers // before glEnable or else the shader gets confused /// ps: maybe if bUsingArbTex is enabled we should use glActiveTextureARB? //glActiveTexture(GL_TEXTURE0); bool wasBound = texData.isBound; if(!wasBound) bind(0); quad.draw(); if(!wasBound) unbind(0); }
//------------------------------------ ofMesh ofTexture::getMeshForSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) const{ ofMesh quad; if(!texData.bAllocated){ return quad; } GLfloat px0 = x; // up to you to get the aspect ratio right GLfloat py0 = y; GLfloat px1 = w+x; GLfloat py1 = h+y; if (texData.bFlipTexture == ofIsVFlipped()){ swap(py0,py1); } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 -= w/2; py0 -= h/2; px1 -= w/2; py1 -= h/2; } //we translate our drawing points by our anchor point. //we still respect ofRectMode so if you have rect mode set to //OF_RECTMODE_CENTER your anchor will be relative to that. GLfloat anchorX; GLfloat anchorY; if(bAnchorIsPct){ anchorX = anchor.x * w; anchorY = anchor.y * h; }else{ anchorX = anchor.x; anchorY = anchor.y; } px0 -= anchorX; py0 -= anchorY; px1 -= anchorX; py1 -= anchorY; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. GLfloat offsetw = 0.0f; GLfloat offseth = 0.0f; if (!ofGLSupportsNPOTTextures() && bTexHackEnabled) { offsetw = 1.0f / (texData.tex_w); offseth = 1.0f / (texData.tex_h); } // ------------------------------------------------- ofPoint topLeft = getCoordFromPoint(sx, sy); ofPoint bottomRight = getCoordFromPoint(sx + sw, sy + sh); GLfloat tx0 = topLeft.x + offsetw; GLfloat ty0 = topLeft.y + offseth; GLfloat tx1 = bottomRight.x - offsetw; GLfloat ty1 = bottomRight.y - offseth; quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN); quad.getVertices().resize(4); quad.getTexCoords().resize(4); quad.getVertices()[0].set(px0,py0,z); quad.getVertices()[1].set(px1,py0,z); quad.getVertices()[2].set(px1,py1,z); quad.getVertices()[3].set(px0,py1,z); quad.getTexCoords()[0].set(tx0,ty0); quad.getTexCoords()[1].set(tx1,ty0); quad.getTexCoords()[2].set(tx1,ty1); quad.getTexCoords()[3].set(tx0,ty1); return quad; }