From Ulrich Hertlien, new osg::TextureRectangle class.

This commit is contained in:
Robert Osfield
2003-04-07 13:20:53 +00:00
parent 9f0fa75484
commit 7af174fadb
8 changed files with 319 additions and 6 deletions

View File

@@ -62,6 +62,7 @@ Ulrich Hertlein <u.hertlein@bit-side.com>
- osg::Sequence support.
- improvements to the pfb loader.
- .lwo, .obj and .x (DirectX model) plugins.
- osg::TextureRectangle.
Axel Volley <volley@acm.org>
- support for OBJECT_LINEAR and EYE_LINEAR TexGen modes.

View File

@@ -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.

View File

@@ -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

View File

@@ -11,8 +11,6 @@
* OpenSceneGraph Public License for more details.
*/
// -*-c++-*-
#ifndef OSG_TEXTURE2D
#define OSG_TEXTURE2D 1

View File

@@ -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 <osg/Texture>
#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<GLMode>& 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> _image;
// subloaded images can have different texture and image sizes.
mutable GLsizei _textureWidth, _textureHeight;
ref_ptr<SubloadCallback> _subloadCallback;
typedef buffered_value<unsigned int> ImageModifiedTag;
mutable ImageModifiedTag _modifiedTag;
};
}
#endif

View File

@@ -84,6 +84,7 @@ CXXFILES =\
Texture2D.cpp\
Texture3D.cpp\
TextureCubeMap.cpp\
TextureRectangle.cpp\
Timer.cpp\
Transform.cpp\
UnitTestFramework.cpp\

View File

@@ -10,6 +10,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osg/GLExtensions>
#include <osg/Texture2D>
#include <osg/State>
@@ -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;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}

View File

@@ -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 <osg/GLExtensions>
#include <osg/TextureRectangle>
#include <osg/State>
#include <osg/GLU>
#include <osg/Notify>
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."<<std::endl;
return;
}
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
if (handle != 0)
{
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
if (getTextureParameterDirty(state.getContextID()))
applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state);
if (_subloadCallback.valid())
_subloadCallback->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);
}