[osg-users] Need help using glTexSubImage2D

Thomas Hogarth thomas.hogarth at googlemail.com
Tue Mar 24 11:41:20 PDT 2009


>
> "Thanks Robert. A couple more questions. How do I guarantee that only the
> changed pixels are uploaded? The source image I'm using is 640x480. To
> maximize compatibility, I need to make texture sizes a power of 2 and square
> right?  That sets the next available size at 1024x1024. That's alot of extra
> data to copy.
>
> If I accessing the Image via the data()  method then there's no way to
> specify the dimensions of the dirty rectangle. I see that copySubImage takes
> a rectangle but the source for copy is an Image object so I'd have to copy
> the image data twice (camera -> tempImage ->texture). Is there something I'm
> missing? Perhapse I should call glTexSubImage2D directly? [/quote]"


Hi Luis (I know I'm not robert)

I've done this before, what you need to do is use a SubloadCallback and
attach it to your texture. In the contructor for this you need to find the
power of two up and set the actual texture size to that. Then is the
subsequent subload call you just copy the actual res image that is attached
to the  Texture something like below.

class CVideoTex2DCallBack :    public osg::Texture2D::SubloadCallback
{
public:
    CVideoTex2DCallBack(osg::Texture2D* texture)
    {
        const osg::Image* _image = texture->getImage();

        //work out next power of two
        m_powerOf2Width = xyz;
        m_powerOf2Height= xyz;

        //set the texture to beleive it is of power of two size
        texture->setTextureSize(m_powerOf2Width, m_powerOf2Width,);

        //set to linear to disable mipmap generation
        texture->setFilter(osg::Texture2D::MIN_FILTER,
osg::Texture2D::LINEAR);
        texture->setFilter(osg::Texture2D::MAG_FILTER,
osg::Texture2D::LINEAR);
    }

    //
    //load the full res
    //
    void load(const osg::Texture2D& texture, osg::State&) const
    {
        const osg::Image* _image = texture.getImage();

        //create texture space to include the power of two size up
        //this way writes to the video memory will be quicker
        glTexImage2D(GL_TEXTURE_2D, 0,

osg::Image::computeNumComponents(_image->getInternalTextureFormat()),
            (int)m_powerOf2Width,
            (int)m_powerOf2Width ,
            0, _image->getPixelFormat(),
            _image->getDataType(), 0);
    }

    //
    Subload the actual res image
    //
    void subload(const osg::Texture2D& texture, osg::State&) const
    {
        const osg::Image* _image = texture.getImage();

        //copy the actual res image into the sized up buffer
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                        _image->s(), _image->t(), _image->getPixelFormat(),
                        _image->getDataType(), _image->data());
    }

protected:

   int m_powerOf2Width;
    int m_powerOf2Height;

};


That should do the trick

Tom
PS sorry for the double post (damn web mail and the tab key :) )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20090324/5847181f/attachment-0003.htm>


More information about the osg-users mailing list