//---------------------------------------------------------- void ofTexture::bind(int textureLocation){ //we could check if it has been allocated - but we don't do that in draw() if(texData.alphaMask){ ofGetGLRenderer()->setAlphaMaskTex(*texData.alphaMask); } enableTextureTarget(textureLocation); if(ofGetUsingNormalizedTexCoords()) { ofSetMatrixMode(OF_MATRIX_TEXTURE); ofPushMatrix(); ofMatrix4x4 m; #ifndef TARGET_OPENGLES if(texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB) m.makeScaleMatrix(texData.width, texData.height, 1.0f); else #endif m.makeScaleMatrix(texData.width / texData.tex_w, texData.height / texData.tex_h, 1.0f); ofLoadMatrix(m); ofSetMatrixMode(OF_MATRIX_MODELVIEW); } if(texData.useTextureMatrix){ ofSetMatrixMode(OF_MATRIX_TEXTURE); if(!ofGetUsingNormalizedTexCoords()) ofPushMatrix(); ofMultMatrix(texData.textureMatrix); ofSetMatrixMode(OF_MATRIX_MODELVIEW); } texData.isBound = true; }
void ofTexture::setSwizzle(GLenum srcSwizzle, GLenum dstChannel){ #ifndef TARGET_OPENGLES enableTextureTarget(0); //glBindTexture(texData.textureTarget, (GLuint)texData.textureID); glTexParameteri(texData.textureTarget, srcSwizzle, dstChannel); disableTextureTarget(0); #endif }
void ofTexture::setRGToRGBASwizzles(bool rToRGBSwizzles){ #ifndef TARGET_OPENGLES enableTextureTarget(0); //glBindTexture(texData.textureTarget, (GLuint)texData.textureID); if(rToRGBSwizzles){ if(texData.glTypeInternal==GL_R8 || texData.glTypeInternal==GL_R16 || texData.glTypeInternal==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.glTypeInternal==GL_RG8 || texData.glTypeInternal==GL_RG16 || texData.glTypeInternal==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.glTypeInternal==GL_R8 || texData.glTypeInternal==GL_R16 || texData.glTypeInternal==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.glTypeInternal==GL_RG8 || texData.glTypeInternal==GL_RG16 || texData.glTypeInternal==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); disableTextureTarget(0); #endif }
//---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ int screenHeight = ofGetViewportHeight(); // this call fails if we are in a different viewport or FBO: ofGetHeight(); y = screenHeight - y; y -= h; // top, bottom issues texData.bFlipTexture = true; if ( w > texData.tex_w || h > texData.tex_h) { ofLogError("ofTexture") << "loadScreenData(): " << w << "x" << h << " image data too big for " << texData.tex_w << "x " << texData.tex_h << " allocated texture, not uploading"; return; } //update our size with the new dimensions - this should be the same size or smaller than the allocated texture size texData.width = w; texData.height = h; //texData.glType = GL_RGB; // this was probably a bug, because you might be resetting the glType to something other than what the texture was created for //compute new tex co-ords based on the ratio of data's w, h to texture w,h; #ifndef TARGET_OPENGLES // DAMIAN if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ texData.tex_t = (float)(w); texData.tex_u = (float)(h); } else #endif { texData.tex_t = (float)(w) / (float)texData.tex_w; texData.tex_u = (float)(h) / (float)texData.tex_h; } enableTextureTarget(0); glBindTexture(texData.textureTarget, (GLuint)texData.textureID); glCopyTexSubImage2D(texData.textureTarget, 0,0,0,x,y,w,h); disableTextureTarget(0); if (bWantsMipmap) { generateMipmap(); } }
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; }
//---------------------------------------------------------- void ofTexture::loadData(const void * data, int w, int h, int glFormat, int glType){ if(w > texData.tex_w || h > texData.tex_h) { allocate(w, h, glFormat, glFormat, glType); } // compute new tex co-ords based on the ratio of data's w, h to texture w,h; #ifndef TARGET_OPENGLES if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ texData.tex_t = w; texData.tex_u = h; } else #endif { texData.tex_t = (float)(w) / (float)texData.tex_w; texData.tex_u = (float)(h) / (float)texData.tex_h; } // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //Sosolimited: texture compression if (texData.compressionType == OF_COMPRESS_NONE) { //STANDARD openFrameworks: no compression //update the texture image: enableTextureTarget(); glBindTexture(texData.textureTarget, (GLuint) texData.textureID); //glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)w, (GLint)h, 0, glFormat, glType, data); glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, glFormat, glType, data); disableTextureTarget(); } else { //SOSOLIMITED: setup mipmaps and use compression //TODO: activate at least mimaps for OPENGL_ES //need proper tex_u and tex_t positions, with mipmaps they are the nearest power of 2 #ifndef TARGET_OPENGLES if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ //need to find closest powers of two int last_h = ofNextPow2(texData.height)>>1; int next_h = ofNextPow2(texData.height); if ((texData.height - last_h) < (next_h - texData.height)) texData.tex_u = last_h; else texData.tex_u = next_h; int last_w = ofNextPow2(texData.width)>>1; int next_w = ofNextPow2(texData.width); if ((texData.width - last_w) < (next_w - texData.width)) texData.tex_t = last_w; else texData.tex_t = next_w; } #endif enableTextureTarget(); glBindTexture(texData.textureTarget, (GLuint)texData.textureID); glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); if(!ofGetGLProgrammableRenderer()){ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } #ifndef TARGET_OPENGLES glTexParameteri(texData.textureTarget, GL_GENERATE_MIPMAP_SGIS, true); #endif glTexParameteri( texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri( texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri( texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri( texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2); #ifndef TARGET_OPENGLES //using sRGB compression if (texData.compressionType == OF_COMPRESS_SRGB) { if(texData.glTypeInternal == GL_RGBA) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_SRGB_ALPHA, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_RGB) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_SRGB_ALPHA, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_LUMINANCE_ALPHA) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_SRGB_ALPHA, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_LUMINANCE) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_SRGB_ALPHA, w, h, glFormat, glType, data); } //using ARB compression: default else { if(texData.glTypeInternal == GL_RGBA) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_RGBA_ARB, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_RGB) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_RGB_ARB, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_LUMINANCE_ALPHA) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_LUMINANCE_ALPHA_ARB, w, h, glFormat, glType, data); else if(texData.glTypeInternal == GL_LUMINANCE) gluBuild2DMipmaps(texData.textureTarget, GL_COMPRESSED_LUMINANCE_ARB, w, h, glFormat, glType, data); } #endif disableTextureTarget(); }