Re: [osg-users] Texture2D::copyTexImage2D
Hi Guy, I can confirm that this is not a correct solution - as copying a different size portion of screen certainly isn't what the Texture2D::copyTexImage2D() is asking to do. If not texture object is allocated and NPOT is not supported then probably the right thing to do is recreate a texture object which is the power of two then use glCopySubImage of the correct size. However, even this really isn't ideal as the texture coords will be the wrong size. Perhaps one simple can't solve the problem using osg::Texture2D as which ever way you solve it the tex coords will be wrong. What about attaching an osg::TextureRectangle? Or ensuring the size is a valid power of two prior to calling? Robert. On Thu, Dec 3, 2009 at 6:59 PM, Guy Volckaert guy.volcka...@meggitt.com wrote: Hi, I was having problems with a resizable window that required a render target implementation (like FRAME_BUFFER). The problem only occurred on hardware that did not support NPOT textures (what can I say - I have an old graphic card!). The problem was isolated in Texture2D::copyTexImage2D() which I corrected below (enclosed between MTSI labels). Can anyone confirm that this is the correct solution? Code: inline int ComputeUpperPowerOfTwo( int s ) { static double ks_dLog2 = log10( 2.0 ); return ( 1 ( int ) ceil( log10( ( double ) s ) / ks_dLog2 ) ); } void Texture2D::copyTexImage2D(State state, int x, int y, int width, int height ) { const unsigned int contextID = state.getContextID(); if (_internalFormat==0) _internalFormat=GL_RGBA; // get the globj for the current contextID. TextureObject* textureObject = getTextureObject(contextID); if (textureObject) { if (width==(int)_textureWidth height==(int)_textureHeight) { // we have a valid texture object which is the right size // so lets play clever and use copyTexSubImage2D instead. // this allows use to reuse the texture object and avoid // expensive memory allocations. copyTexSubImage2D(state,0 ,0, x, y, width, height); return; } // the relevent texture object is not of the right size so // needs to been deleted // remove previously bound textures. dirtyTextureObject(); // note, dirtyTextureObject() dirties all the texture objects for // this texture, is this right? Perhaps we should dirty just the // one for this context. Note sure yet will leave till later. // RO July 2001. } // remove any previously assigned images as these are nolonger valid. _image = NULL; // switch off mip-mapping. // _textureObjectBuffer[contextID] = textureObject = generateTextureObject(contextID,GL_TEXTURE_2D); textureObject-bind(); applyTexParameters(GL_TEXTURE_2D,state); bool needHardwareMipMap = (_min_filter != LINEAR _min_filter != NEAREST); bool hardwareMipMapOn = false; if (needHardwareMipMap) { hardwareMipMapOn = isHardwareMipmapGenerationEnabled(state); if (!hardwareMipMapOn) { // have to switch off mip mapping notify(NOTICE)Warning: Texture2D::copyTexImage2D() switch off mip mapping as hardware support not available.std::endl; _min_filter = LINEAR; } } GenerateMipmapMode mipmapResult = mipmapBeforeTexImage(state, hardwareMipMapOn); // MTSI [20091203 guyv] // Fixed an an issue with hardware that does not support non-power-of-two textures. int tex_width = width; int tex_height = height; const Extensions* extensions = getExtensions(contextID,true); if( _resizeNonPowerOfTwoHint || !extensions-isNonPowerOfTwoTextureSupported(_min_filter) ) { tex_width = ComputeUpperPowerOfTwo(width-2*_borderWidth)+2*_borderWidth; tex_height = ComputeUpperPowerOfTwo(height-2*_borderWidth)+2*_borderWidth; } // cap the size to what the graphics hardware can handle. if (tex_widthextensions-maxTextureSize()) tex_width = extensions-maxTextureSize(); if (tex_heightextensions-maxTextureSize()) tex_height = extensions-maxTextureSize(); glCopyTexImage2D( GL_TEXTURE_2D, 0, _internalFormat, x, y, tex_width, tex_height, 0 ); mipmapAfterTexImage(state, mipmapResult); _textureWidth = tex_width; _textureHeight = tex_height; _numMipmapLevels = 1; // ~MTSI [20091203 guyv] textureObject-setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0); // inform state that this texture is the current one bound. state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); } Cheers, Guy -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20833#20833 ___ osg-users mailing list osg-users@lists.openscenegraph.org
Re: [osg-users] Texture2D::copyTexImage2D
Unfortunately, my graphic crad does not support NPOT texture which is why I can't use osg::TextureRectangle. I also tried ensuring that my Texture2D is always a POT when I change the windows size (see code below). Code: int32 nWitdh = viewport-width(); int32 nHeight = viewport-height(); int32 nPOTWidth = ComputeUpperPowerOfTwo( nWidth ); int32 nPOTHeight = ComputeUpperPowerOfTwo( nHeight ); if( nPOTWidth != pTex2D-getTextureWidth( ) || nPOTHeight != pTex2D-getTextureHeight( ) ) { pTex2D-dirtyTextureObject( ); pTex2D-setTextureSize( nPOTWidth, nPOTHeight ); } else { bDirtyTexture = false; } u = double( nWidth ) / nPOTWidth; v = double( nHeight ) / nPOTHeight; However that does not work. The Texture2D::copyTexImage2D() eventually gets called, but fails to call copyTexSubImage2D() since the width/height passes as paramater do not equal the texture width/height. Code: if (width==(int)_textureWidth height==(int)_textureHeight) { // we have a valid texture object which is the right size // so lets play clever and use copyTexSubImage2D instead. // this allows use to reuse the texture object and avoid // expensive memory allocations. copyTexSubImage2D(state,0 ,0, x, y, width, height); return; } Near the end of the Texture2D::copyTexImage2D() function, it simply copies the viewport size (width/height) into the texture _textureWidth/_textureHeight and thus it becomes a NPOT texture - hense the problem I am experiencing. Guy -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20896#20896 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Texture2D::copyTexImage2D
Hi Guy, The GL_TEXTURE_RECTANGLE extension is independent of the NPOT support in standard GL_TEXTURE_2D that is found in OpenGL 2.0 onwards, so just because your hardware lacks support for the later, it doesn't mean that texture rectangle extension is not supported. Robert. On Fri, Dec 4, 2009 at 2:37 PM, Guy Volckaert guy.volcka...@meggitt.com wrote: Unfortunately, my graphic crad does not support NPOT texture which is why I can't use osg::TextureRectangle. I also tried ensuring that my Texture2D is always a POT when I change the windows size (see code below). Code: int32 nWitdh = viewport-width(); int32 nHeight = viewport-height(); int32 nPOTWidth = ComputeUpperPowerOfTwo( nWidth ); int32 nPOTHeight = ComputeUpperPowerOfTwo( nHeight ); if( nPOTWidth != pTex2D-getTextureWidth( ) || nPOTHeight != pTex2D-getTextureHeight( ) ) { pTex2D-dirtyTextureObject( ); pTex2D-setTextureSize( nPOTWidth, nPOTHeight ); } else { bDirtyTexture = false; } u = double( nWidth ) / nPOTWidth; v = double( nHeight ) / nPOTHeight; However that does not work. The Texture2D::copyTexImage2D() eventually gets called, but fails to call copyTexSubImage2D() since the width/height passes as paramater do not equal the texture width/height. Code: if (width==(int)_textureWidth height==(int)_textureHeight) { // we have a valid texture object which is the right size // so lets play clever and use copyTexSubImage2D instead. // this allows use to reuse the texture object and avoid // expensive memory allocations. copyTexSubImage2D(state,0 ,0, x, y, width, height); return; } Near the end of the Texture2D::copyTexImage2D() function, it simply copies the viewport size (width/height) into the texture _textureWidth/_textureHeight and thus it becomes a NPOT texture - hense the problem I am experiencing. Guy -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20896#20896 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Texture2D::copyTexImage2D
Ahhh.. I was not aware of that small detail. Thanks for the info - I will try it immediately. Guy -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20898#20898 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Texture2D::copyTexImage2D
Dude you the greatest. Using osg::TextureRectangle worked! Thanks for your great help. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20926#20926 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] Texture2D::copyTexImage2D
Hi, I was having problems with a resizable window that required a render target implementation (like FRAME_BUFFER). The problem only occurred on hardware that did not support NPOT textures (what can I say - I have an old graphic card!). The problem was isolated in Texture2D::copyTexImage2D() which I corrected below (enclosed between MTSI labels). Can anyone confirm that this is the correct solution? Code: inline int ComputeUpperPowerOfTwo( int s ) { static double ks_dLog2 = log10( 2.0 ); return ( 1 ( int ) ceil( log10( ( double ) s ) / ks_dLog2 ) ); } void Texture2D::copyTexImage2D(State state, int x, int y, int width, int height ) { const unsigned int contextID = state.getContextID(); if (_internalFormat==0) _internalFormat=GL_RGBA; // get the globj for the current contextID. TextureObject* textureObject = getTextureObject(contextID); if (textureObject) { if (width==(int)_textureWidth height==(int)_textureHeight) { // we have a valid texture object which is the right size // so lets play clever and use copyTexSubImage2D instead. // this allows use to reuse the texture object and avoid // expensive memory allocations. copyTexSubImage2D(state,0 ,0, x, y, width, height); return; } // the relevent texture object is not of the right size so // needs to been deleted // remove previously bound textures. dirtyTextureObject(); // note, dirtyTextureObject() dirties all the texture objects for // this texture, is this right? Perhaps we should dirty just the // one for this context. Note sure yet will leave till later. // RO July 2001. } // remove any previously assigned images as these are nolonger valid. _image = NULL; // switch off mip-mapping. // _textureObjectBuffer[contextID] = textureObject = generateTextureObject(contextID,GL_TEXTURE_2D); textureObject-bind(); applyTexParameters(GL_TEXTURE_2D,state); bool needHardwareMipMap = (_min_filter != LINEAR _min_filter != NEAREST); bool hardwareMipMapOn = false; if (needHardwareMipMap) { hardwareMipMapOn = isHardwareMipmapGenerationEnabled(state); if (!hardwareMipMapOn) { // have to switch off mip mapping notify(NOTICE)Warning: Texture2D::copyTexImage2D() switch off mip mapping as hardware support not available.std::endl; _min_filter = LINEAR; } } GenerateMipmapMode mipmapResult = mipmapBeforeTexImage(state, hardwareMipMapOn); // MTSI [20091203 guyv] // Fixed an an issue with hardware that does not support non-power-of-two textures. int tex_width = width; int tex_height = height; const Extensions* extensions = getExtensions(contextID,true); if( _resizeNonPowerOfTwoHint || !extensions-isNonPowerOfTwoTextureSupported(_min_filter) ) { tex_width = ComputeUpperPowerOfTwo(width-2*_borderWidth)+2*_borderWidth; tex_height = ComputeUpperPowerOfTwo(height-2*_borderWidth)+2*_borderWidth; } // cap the size to what the graphics hardware can handle. if (tex_widthextensions-maxTextureSize()) tex_width = extensions-maxTextureSize(); if (tex_heightextensions-maxTextureSize()) tex_height = extensions-maxTextureSize(); glCopyTexImage2D( GL_TEXTURE_2D, 0, _internalFormat, x, y, tex_width, tex_height, 0 ); mipmapAfterTexImage(state, mipmapResult); _textureWidth = tex_width; _textureHeight = tex_height; _numMipmapLevels = 1; // ~MTSI [20091203 guyv] textureObject-setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0); // inform state that this texture is the current one bound. state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); } Cheers, Guy -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20833#20833 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Texture2D::copyTexImage2D
Forgot to mentioned that I was using OSG 2.8.2. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20834#20834 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org