// 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)); }
//---------------------------------------------------------- GLuint ofFbo::createAndAttachRenderbuffer(GLenum internalFormat, GLenum attachmentPoint) { GLuint buffer; glGenRenderbuffers(1, &buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer); #ifndef TARGET_OPENGLES if (settings.numSamples==0) { glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, settings.width, settings.height); } else { glRenderbufferStorageMultisample(GL_RENDERBUFFER, settings.numSamples, internalFormat, settings.width, settings.height); } #else if(ofGLSupportsNPOTTextures()){ glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, settings.width, settings.height); }else{ glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, ofNextPow2(settings.width), ofNextPow2(settings.height)); } #endif glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER, buffer); return buffer; }
// 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(); }
//------------------------------------ ofMesh ofTexture::getMeshForSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh, bool vflipped, ofRectMode rectMode) 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 == vflipped){ swap(py0,py1); } // for rect mode center, let's do this: if (rectMode == 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; }
void ofTexture::allocate(const ofTextureData & textureData, int glFormat, int pixelType){ #ifndef TARGET_OPENGLES if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ #else if(texData.textureTarget == GL_TEXTURE_2D){ #endif if( textureData.width <= 0.0 || textureData.height <= 0.0 ){ ofLogError("ofTexture") << "allocate(): ofTextureData has 0 width and/or height: " << textureData.width << "x" << textureData.height; return; } } texData = textureData; //our graphics card might not support arb so we have to see if it is supported. #ifndef TARGET_OPENGLES if( texData.textureTarget==GL_TEXTURE_RECTANGLE_ARB && ofGLSupportsNPOTTextures() ){ texData.tex_w = texData.width; texData.tex_h = texData.height; texData.tex_t = texData.width; texData.tex_u = texData.height; }else if(texData.textureTarget == GL_TEXTURE_2D) #endif { if(ofGLSupportsNPOTTextures()){ texData.tex_w = texData.width; texData.tex_h = texData.height; }else{ //otherwise we need to calculate the next power of 2 for the requested dimensions //ie (320x240) becomes (512x256) texData.tex_w = ofNextPow2(texData.width); texData.tex_h = ofNextPow2(texData.height); } texData.tex_t = texData.width / texData.tex_w; texData.tex_u = texData.height / texData.tex_h; } // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)&texData.textureID); // could be more then one, but for now, just one retain(texData.textureID); #ifndef TARGET_OPENGLES if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ #else if(texData.textureTarget == GL_TEXTURE_2D){ #endif glBindTexture(texData.textureTarget,texData.textureID); glTexImage2D(texData.textureTarget, 0, texData.glInternalFormat, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, glFormat, pixelType, 0); // init to black... glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, texData.magFilter); glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, texData.minFilter); glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, texData.wrapModeHorizontal); glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, texData.wrapModeVertical); #ifndef TARGET_PROGRAMMABLE_GL if (!ofIsGLProgrammableRenderer()){ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } #endif glBindTexture(texData.textureTarget,0); } texData.bAllocated = true; #ifdef TARGET_ANDROID registerTexture(this); #endif } void ofTexture::setRGToRGBASwizzles(bool rToRGBSwizzles){ #ifndef TARGET_OPENGLES glBindTexture(texData.textureTarget,texData.textureID); if(rToRGBSwizzles){ if(texData.glInternalFormat==GL_R8 || texData.glInternalFormat==GL_R16 || texData.glInternalFormat==GL_R32F){ glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); }else if(texData.glInternalFormat==GL_RG8 || texData.glInternalFormat==GL_RG16 || texData.glInternalFormat==GL_RG32F){ glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN); } }else{ if(texData.glInternalFormat==GL_R8 || texData.glInternalFormat==GL_R16 || texData.glInternalFormat==GL_R32F){ glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE); }else if(texData.glInternalFormat==GL_RG8 || texData.glInternalFormat==GL_RG16 || texData.glInternalFormat==GL_RG32F){ glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE); glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); } } glBindTexture(texData.textureTarget,0); #endif } void ofTexture::setSwizzle(GLenum srcSwizzle, GLenum dstChannel){ #ifndef TARGET_OPENGLES glBindTexture(texData.textureTarget,texData.textureID); glTexParameteri(texData.textureTarget, srcSwizzle, dstChannel); glBindTexture(texData.textureTarget,0); #endif }
//---------------------------------------------------------- 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); }
void ofTexture::allocate(const ofTextureData & textureData, int glFormat, int pixelType){ if( textureData.width <= 0.0 || textureData.height <= 0.0 ){ ofLogError("ofTexture") << "allocate(): ofTextureData has 0 width and/or height: " << textureData.width << "x" << textureData.height; return; } texData = textureData; //our graphics card might not support arb so we have to see if it is supported. #ifndef TARGET_OPENGLES if( texData.textureTarget==GL_TEXTURE_RECTANGLE_ARB && ofGLSupportsNPOTTextures() ){ texData.tex_w = texData.width; texData.tex_h = texData.height; texData.tex_t = texData.width; texData.tex_u = texData.height; }else #endif { if(ofGLSupportsNPOTTextures()){ texData.tex_w = texData.width; texData.tex_h = texData.height; }else{ //otherwise we need to calculate the next power of 2 for the requested dimensions //ie (320x240) becomes (512x256) texData.tex_w = ofNextPow2(texData.width); texData.tex_h = ofNextPow2(texData.height); } texData.tex_t = texData.width / texData.tex_w; texData.tex_u = texData.height / texData.tex_h; #ifndef TARGET_OPENGLES if( texData.textureTarget==GL_TEXTURE_RECTANGLE_ARB ) texData.textureTarget = GL_TEXTURE_2D; #endif } // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)&texData.textureID); // could be more then one, but for now, just one retain(texData.textureID); enableTextureTarget(0); glBindTexture(texData.textureTarget, (GLuint)texData.textureID); glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, glFormat, pixelType, 0); // init to black... glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, texData.magFilter); glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, texData.minFilter); glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, texData.wrapModeHorizontal); glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, texData.wrapModeVertical); #ifndef TARGET_PROGRAMMABLE_GL if (!ofIsGLProgrammableRenderer()){ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } #endif disableTextureTarget(0); texData.bAllocated = true; }