diff --git a/include/osg/TextureRectangle b/include/osg/TextureRectangle index 07d6bd4ae..b25b3df9b 100644 --- a/include/osg/TextureRectangle +++ b/include/osg/TextureRectangle @@ -106,6 +106,21 @@ class OSG_EXPORT TextureRectangle : public Texture SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + /** Copies pixels into a 2D texture image, as per glCopyTexImage2D. + * Creates an OpenGL texture object from the current OpenGL background + * framebuffer contents at position \a x, \a y with width \a width and + * height \a height. \a width and \a height must be a power of two. */ + void copyTexImage2D(State& state, int x, int y, int width, int height ); + + /** Copies a two-dimensional texture subimage, as per + * glCopyTexSubImage2D. Updates a portion of an existing OpenGL + * texture object from the current OpenGL background framebuffer + * contents at position \a x, \a y with width \a width and height + * \a height. Loads framebuffer data into the texture using offsets + * \a xoffset and \a yoffset. \a width and \a height must be powers + * of two. */ + void copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height ); + /** On first apply (unless already compiled), create and bind the * texture, subsequent apply will simply bind to texture. */ diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 6d42e000c..736cb3245 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -356,3 +356,133 @@ void TextureRectangle::computeInternalFormat() const if (_image.valid()) computeInternalFormatWithImage(*_image); } + +void TextureRectangle::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_RECTANGLE); + + textureObject->bind(); + + applyTexParameters(GL_TEXTURE_RECTANGLE,state); + + +/* bool needHardwareMipMap = (_min_filter != LINEAR && _min_filter != NEAREST); + bool hardwareMipMapOn = false; + if (needHardwareMipMap) + { + const Extensions* extensions = getExtensions(contextID,true); + bool generateMipMapSupported = extensions->isGenerateMipMapSupported(); + + hardwareMipMapOn = _useHardwareMipMapGeneration && generateMipMapSupported; + + if (!hardwareMipMapOn) + { + // have to swtich off mip mapping + notify(NOTICE)<<"Warning: Texture2D::copyTexImage2D(,,,,) switch of mip mapping as hardware support not available."<setAllocated(1,_internalFormat,_textureWidth,_textureHeight,1,0); + + + // inform state that this texture is the current one bound. + state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); +} + +void TextureRectangle::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height ) +{ + const unsigned int contextID = state.getContextID(); + + if (_internalFormat==0) _internalFormat=GL_RGBA; + + // get the texture object for the current contextID. + TextureObject* textureObject = getTextureObject(contextID); + + if (textureObject) + { + // we have a valid image + textureObject->bind(); + + applyTexParameters(GL_TEXTURE_RECTANGLE,state); + +/* bool needHardwareMipMap = (_min_filter != LINEAR && _min_filter != NEAREST); + bool hardwareMipMapOn = false; + if (needHardwareMipMap) + { + const Extensions* extensions = getExtensions(contextID,true); + bool generateMipMapSupported = extensions->isGenerateMipMapSupported(); + + hardwareMipMapOn = _useHardwareMipMapGeneration && generateMipMapSupported; + + if (!hardwareMipMapOn) + { + // have to swtich off mip mapping + notify(NOTICE)<<"Warning: Texture2D::copyTexImage2D(,,,,) switch of mip mapping as hardware support not available."<