From 7af174fadbe6e3570c9387266f8fa93320e52549 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 7 Apr 2003 13:20:53 +0000 Subject: [PATCH] From Ulrich Hertlien, new osg::TextureRectangle class. --- AUTHORS.txt | 1 + NEWS.txt | 10 +- VisualStudio/osg/osg.dsp | 8 ++ include/osg/Texture2D | 2 - include/osg/TextureRectangle | 116 ++++++++++++++++++++++ src/osg/GNUmakefile | 1 + src/osg/Texture2D.cpp | 5 +- src/osg/TextureRectangle.cpp | 182 +++++++++++++++++++++++++++++++++++ 8 files changed, 319 insertions(+), 6 deletions(-) create mode 100644 include/osg/TextureRectangle create mode 100644 src/osg/TextureRectangle.cpp diff --git a/AUTHORS.txt b/AUTHORS.txt index 076056870..702c59b1c 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -62,6 +62,7 @@ Ulrich Hertlein - osg::Sequence support. - improvements to the pfb loader. - .lwo, .obj and .x (DirectX model) plugins. + - osg::TextureRectangle. Axel Volley - support for OBJECT_LINEAR and EYE_LINEAR TexGen modes. diff --git a/NEWS.txt b/NEWS.txt index 8b491f0ef..428f1a63b 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -19,7 +19,7 @@ OSG News (most significant items from ChangeLog) configuration of threading and multiple camera views can all be done via ASCII configuration files, no need to recompile. - Improvemnts to the Makefle system. + Improvements to the Makefle system. Added support for early abort of rendering, useful for interactive applications which occasional have rendering that takes that long @@ -42,8 +42,14 @@ OSG News (most significant items from ChangeLog) the rest of the core libraries, virtual of this osgText now compiles by default on platforms. - Automatic subloading of textures when images are updated. + New osg::TextureRectangle texture class which encapsulates the + NV_texture_rectangle and EXT_texture_rectange extensions. + + Added automatic subloading of textures when images are updated. + Added the option of automatic unref'ing of texture image data once the data has + been download to OpenGL to active graphics contexts. + New database cache in the osgDB library. Clean up of memory management in the OpenFlight loader. diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index dd3ab527b..52fdbc775 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -417,6 +417,10 @@ SOURCE=..\..\src\osg\TextureCubeMap.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\TextureRectangle.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\Timer.cpp # End Source File # Begin Source File @@ -833,6 +837,10 @@ SOURCE=..\..\Include\Osg\TextureCubeMap # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\TextureRectangle +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\Timer # End Source File # Begin Source File diff --git a/include/osg/Texture2D b/include/osg/Texture2D index d8f4fa4ed..905e0d759 100644 --- a/include/osg/Texture2D +++ b/include/osg/Texture2D @@ -11,8 +11,6 @@ * OpenSceneGraph Public License for more details. */ -// -*-c++-*- - #ifndef OSG_TEXTURE2D #define OSG_TEXTURE2D 1 diff --git a/include/osg/TextureRectangle b/include/osg/TextureRectangle new file mode 100644 index 000000000..c10ef76af --- /dev/null +++ b/include/osg/TextureRectangle @@ -0,0 +1,116 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_TEXTURERECTANGLE +#define OSG_TEXTURERECTANGLE 1 + +#include + +#ifndef GL_TEXTURE_RECTANGLE_NV +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#endif + +namespace osg { + +/** Texture state class which encapsulates OpenGL texture functionality.*/ +class SG_EXPORT TextureRectangle : public Texture +{ + + public : + + TextureRectangle(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + TextureRectangle(const TextureRectangle& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, TextureRectangle, TEXTURE); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& rhs) const; + + virtual void getAssociatedModes(std::vector& modes) const + { + modes.push_back(GL_TEXTURE_RECTANGLE_NV); + } + + /** Set the texture image. */ + void setImage(Image* image); + + /** Get the texture image. */ + Image* getImage() { return _image.get(); } + + /** Get the const texture image. */ + inline const Image* getImage() const { return _image.get(); } + + inline unsigned int& getModifiedTag(unsigned int contextID) const + { + // get the modified tag for the current contextID. + return _modifiedTag[contextID]; + } + + /** Set the texture width and height. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setTextureSize(int width, int height) const + { + _textureWidth = width; + _textureHeight = height; + } + + /** Get the texture subload width. */ + inline void getTextureSize(int& width, int& height) const + { + width = _textureWidth; + height = _textureHeight; + } + + class SubloadCallback : public Referenced + { + public: + virtual void load(const TextureRectangle&, State&) const = 0; + virtual void subload(const TextureRectangle&, State&) const = 0; + }; + + void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; } + SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } + const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + + /** On first apply (unless already compiled), create the minmapped + * texture and bind it, subsequent apply will simple bind to texture.*/ + virtual void apply(State& state) const; + + protected : + + virtual ~TextureRectangle(); + + virtual void computeInternalFormat() const; + + void applyTexImageRectangle(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight) const; + + // not ideal that _image is mutable, but its required since + // Image::ensureDimensionsArePowerOfTwo() can only be called + // in a valid OpenGL context, a therefore within an Texture::apply + // which is const... + mutable ref_ptr _image; + + // subloaded images can have different texture and image sizes. + mutable GLsizei _textureWidth, _textureHeight; + + ref_ptr _subloadCallback; + + typedef buffered_value ImageModifiedTag; + mutable ImageModifiedTag _modifiedTag; +}; + +} + +#endif diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index dc2567654..63e80cc38 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -84,6 +84,7 @@ CXXFILES =\ Texture2D.cpp\ Texture3D.cpp\ TextureCubeMap.cpp\ + TextureRectangle.cpp\ Timer.cpp\ Transform.cpp\ UnitTestFramework.cpp\ diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index ecfbb5b72..8f2516a18 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -10,6 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ + #include #include #include @@ -151,8 +152,8 @@ void Texture2D::apply(State& state) const if (_unrefImageDataAfterApply) { // only unref image once all the graphics contexts has been set up. - int numLeftToBind=0; - for(int i=0;igetMaxNumberOfGraphicsContexts();++i) + unsigned int numLeftToBind=0; + for(unsigned int i=0;igetMaxNumberOfGraphicsContexts();++i) { if (_handleList[i]==0) ++numLeftToBind; } diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp new file mode 100644 index 000000000..f44b8560b --- /dev/null +++ b/src/osg/TextureRectangle.cpp @@ -0,0 +1,182 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include +#include +#include + +using namespace osg; + +TextureRectangle::TextureRectangle(): + _textureWidth(0), + _textureHeight(0) +{ +} + +TextureRectangle::TextureRectangle(const TextureRectangle& text,const CopyOp& copyop): + Texture(text,copyop), + _image(copyop(text._image.get())), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _subloadCallback(text._subloadCallback) +{ +} + +TextureRectangle::~TextureRectangle() +{ +} + +int TextureRectangle::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(TextureRectangle,sa) + + if (_image!=rhs._image) // smart pointer comparison. + { + if (_image.valid()) + { + if (rhs._image.valid()) + { + int result = _image->compare(*rhs._image); + if (result!=0) return result; + } + else + { + return 1; // valid lhs._image is greater than null. + } + } + else if (rhs._image.valid()) + { + return -1; // valid rhs._image is greater than null. + } + } + + int result = compareTexture(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_textureWidth) + COMPARE_StateAttribute_Parameter(_textureHeight) + COMPARE_StateAttribute_Parameter(_subloadCallback) + + return 0; // passed all the above comparison macro's, must be equal. +} + +void TextureRectangle::setImage(Image* image) +{ + // delete old texture objects. + dirtyTextureObject(); + + _image = image; +} + + +void TextureRectangle::apply(State& state) const +{ + static bool s_rectangleSupported = isGLExtensionSupported("GL_EXT_texture_rectangle") || isGLExtensionSupported("GL_NV_texture_rectangle"); + + if (!s_rectangleSupported) + { + notify(WARN)<<"Warning: TextureRectangle::apply(..) failed, texture rectangle is not support by your OpenGL drivers."<subload(*this, state); + } + else if (_subloadCallback.valid()) + { + glGenTextures(1L, (GLuint *)&handle); + glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle); + + applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state); + + _subloadCallback->load(*this, state); + + // in theory the following line is redundant, but in practice + // have found that the first frame drawn doesn't apply the textures + // unless a second bind is called?!! + // perhaps it is the first glBind which is not required... + glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle); + } + else if (_image.valid() && _image->data()) + { + glGenTextures(1L, (GLuint *)&handle); + glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle); + + applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state); + + applyTexImageRectangle(GL_TEXTURE_RECTANGLE_NV, _image.get(), state, _textureWidth, _textureHeight); + + // in theory the following line is redundant, but in practice + // have found that the first frame drawn doesn't apply the textures + // unless a second bind is called?!! + // perhaps it is the first glBind which is not required... + glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle); + } + else + { + glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0); + } +} + +void TextureRectangle::applyTexImageRectangle(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight) const +{ + // if we don't have a valid image we can't create a texture! + if (!image || !image->data()) + return; + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const unsigned int contextID = state.getContextID(); + + // update the modified tag to show that it is upto date. + getModifiedTag(contextID) = image->getModifiedTag(); + + // compute the internal texture format, sets _internalFormat. + computeInternalFormat(); + + glPixelStorei(GL_UNPACK_ALIGNMENT, image->getPacking()); + + // UH: ignoring compressed for now. + glTexImage2D(target, 0, _internalFormat, + image->s(), image->t(), 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->data()); + + inwidth = image->s(); + inheight = image->t(); +} + +void TextureRectangle::computeInternalFormat() const +{ + if (_image.valid()) + computeInternalFormatWithImage(*_image); +}