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 <[email protected]> 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_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
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to