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_width>extensions->maxTextureSize()) tex_width =
extensions->maxTextureSize();
if (tex_height>extensions->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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org