Checked in new methods for setting up texture subloading, these allow the

user to control which parts on an image are subloaded from, and how big
the initial texture is.
This commit is contained in:
Robert Osfield 2002-07-28 23:28:27 +00:00
parent 02bb66a572
commit 6b59f66d80
3 changed files with 145 additions and 69 deletions

View File

@ -77,30 +77,8 @@ class SG_EXPORT Texture : public StateAttribute
Texture();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
StateAttribute(text,copyop),
_handleList(),
_modifiedTag(),
_image(copyop(text._image.get())),
_unrefImageAfterApply(text._unrefImageAfterApply),
_target(text._target),
_wrap_s(text._wrap_s),
_wrap_t(text._wrap_t),
_wrap_r(text._wrap_r),
_min_filter(text._min_filter),
_mag_filter(text._mag_filter),
_texParamtersDirty(false),
_internalFormatMode(text._internalFormatMode),
_internalFormatValue(text._internalFormatValue),
_borderColor(text._borderColor),
_textureWidth(text._textureWidth),
_textureHeight(text._textureHeight),
_subloadMode(text._subloadMode),
_subloadOffsX(text._subloadOffsX),
_subloadOffsY(text._subloadOffsY),
_subloadWidth(text._subloadWidth),
_subloadHeight(text._subloadHeight) {}
Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, Texture,TEXTURE);
virtual bool isTextureAttribute() const { return true; }
@ -121,9 +99,16 @@ class SG_EXPORT Texture : public StateAttribute
/** Get the const texture image. */
inline const Image* getImage() const { return _image.get(); }
/** Set the unreference image after apply flag, default value is false.
* If set to true the attached image is unreferenced via a _image = 0;
* if the image has no other references to it, it will be automatically
* deleted. Note, this should only by used in case where only a single
* graphics context is being used, otherwise only the first context will
* be set, with the rest left with no image to apply.*/
void setUnrefImageAfterApply(bool unrefImage) { _unrefImageAfterApply = unrefImage; }
/** Get the unreference image after apply flag.*/
bool getUnrefImageAfterApply() const { return _unrefImageAfterApply; }
/** Copy pixels into a 2D texture image.As per glCopyTexImage2D.
@ -238,29 +223,63 @@ class SG_EXPORT Texture : public StateAttribute
/** Get the texture subload mode. */
inline const SubloadMode getSubloadMode() const { return _subloadMode; }
/** Set the texture subload offsets. */
inline void setSubloadOffset(const int x, const int y) {
_subloadOffsX = x;
_subloadOffsY = y;
/** Set the texture subload texture offsets. */
inline void setSubloadTextureOffset(const int x, const int y)
{
_subloadTextureOffsetX = x;
_subloadTextureOffsetY = y;
}
/** Get the texture subload offsets. */
inline void getSubloadOffset(int& x, int& y) const {
x = _subloadOffsX;
y = _subloadOffsY;
/** Get the texture subload texture offsets. */
inline void getSubloadTextureOffset(int& x, int& y) const
{
x = _subloadTextureOffsetX;
y = _subloadTextureOffsetY;
}
/** Set the texture subload width. If width or height are zero then
* the repsective size value is calculated from the source image sizes. */
inline void setSubloadSize(const int width, const int height) {
_subloadWidth = width;
_subloadHeight = height;
inline void setSubloadTextureSize(const int width, const int height)
{
_textureWidth = width;
_textureHeight = height;
}
/** Get the texture subload width. */
inline void getSubloadSize(int& width, int& height) const {
width = _subloadWidth;
height = _subloadHeight;
inline void getSubloadTextureSize(int& width, int& height) const
{
width = _textureWidth;
height = _textureHeight;
}
/** Set the subload image offsets. */
inline void setSubloadImageOffset(const int x, const int y)
{
_subloadImageOffsetX = x;
_subloadImageOffsetY = y;
}
/** Get the subload image offsets. */
inline void getSubloadImageOffset(int& x, int& y) const
{
x = _subloadImageOffsetX;
y = _subloadImageOffsetY;
}
/** Set the image subload width. If width or height are zero then
* the repsective size value is calculated from the source image sizes. */
inline void setSubloadImageSize(const int width, const int height)
{
_subloadImageWidth = width;
_subloadImageHeight = height;
}
/** Get the image subload width. */
inline void getSubloadImageSize(int& width, int& height) const
{
width = _subloadImageWidth;
height = _subloadImageHeight;
}
/** Get the handle to the texture object for the current context.*/
@ -358,8 +377,9 @@ class SG_EXPORT Texture : public StateAttribute
mutable GLsizei _textureWidth, _textureHeight;
SubloadMode _subloadMode;
GLint _subloadOffsX, _subloadOffsY;
GLsizei _subloadWidth, _subloadHeight;
GLint _subloadTextureOffsetX, _subloadTextureOffsetY;
GLint _subloadImageOffsetX, _subloadImageOffsetY;
GLsizei _subloadImageWidth, _subloadImageHeight;
// static cache of deleted display lists which can only
// by completely deleted once the appropriate OpenGL context

View File

@ -19,8 +19,8 @@ using namespace osg;
Texture::DeletedTextureObjectCache Texture::s_deletedTextureObjectCache;
Texture::Texture():
_unrefImageAfterApply(false),
_target(GL_TEXTURE_2D),
_unrefImageAfterApply(true),
_wrap_s(CLAMP),
_wrap_t(CLAMP),
_wrap_r(CLAMP),
@ -33,16 +33,44 @@ Texture::Texture():
_textureWidth(0),
_textureHeight(0),
_subloadMode(OFF),
_subloadOffsX(0),
_subloadOffsY(0),
_subloadWidth(0),
_subloadHeight(0)
_subloadTextureOffsetX(0),
_subloadTextureOffsetY(0),
_subloadImageOffsetX(0),
_subloadImageOffsetY(0),
_subloadImageWidth(0),
_subloadImageHeight(0)
{
_handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0);
_modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0);
}
Texture::Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
StateAttribute(text,copyop),
_handleList(),
_modifiedTag(),
_image(copyop(text._image.get())),
_unrefImageAfterApply(text._unrefImageAfterApply),
_target(text._target),
_wrap_s(text._wrap_s),
_wrap_t(text._wrap_t),
_wrap_r(text._wrap_r),
_min_filter(text._min_filter),
_mag_filter(text._mag_filter),
_texParamtersDirty(false),
_internalFormatMode(text._internalFormatMode),
_internalFormatValue(text._internalFormatValue),
_borderColor(text._borderColor),
_textureWidth(text._textureWidth),
_textureHeight(text._textureHeight),
_subloadMode(text._subloadMode),
_subloadTextureOffsetX(text._subloadTextureOffsetX),
_subloadTextureOffsetY(text._subloadTextureOffsetY),
_subloadImageOffsetX(text._subloadImageOffsetX),
_subloadImageOffsetY(text._subloadImageOffsetY),
_subloadImageWidth(text._subloadImageWidth),
_subloadImageHeight(text._subloadImageHeight)
{}
Texture::~Texture()
{
@ -87,10 +115,12 @@ int Texture::compare(const StateAttribute& sa) const
COMPARE_StateAttribute_Parameter(_textureWidth)
COMPARE_StateAttribute_Parameter(_textureHeight)
COMPARE_StateAttribute_Parameter(_subloadMode)
COMPARE_StateAttribute_Parameter(_subloadOffsX)
COMPARE_StateAttribute_Parameter(_subloadOffsY)
COMPARE_StateAttribute_Parameter(_subloadWidth)
COMPARE_StateAttribute_Parameter(_subloadHeight)
COMPARE_StateAttribute_Parameter(_subloadTextureOffsetX)
COMPARE_StateAttribute_Parameter(_subloadTextureOffsetY)
COMPARE_StateAttribute_Parameter(_subloadImageOffsetX)
COMPARE_StateAttribute_Parameter(_subloadImageOffsetY)
COMPARE_StateAttribute_Parameter(_subloadImageWidth)
COMPARE_StateAttribute_Parameter(_subloadImageHeight)
return 0; // passed all the above comparison macro's, must be equal.
}
@ -200,11 +230,16 @@ void Texture::apply(State& state) const
if (_subloadMode == AUTO ||
(_subloadMode == IF_DIRTY && modifiedTag != _image->getModifiedTag()))
{
glPixelStorei(GL_UNPACK_ROW_LENGTH,_image->getRowSizeInBytes());
glTexSubImage2D(_target, 0,
_subloadOffsX, _subloadOffsY,
(_subloadWidth>0)?_subloadWidth:_image->s(), (_subloadHeight>0)?_subloadHeight:_image->t(),
_subloadTextureOffsetX, _subloadTextureOffsetY,
(_subloadImageWidth>0)?_subloadImageWidth:_image->s(), (_subloadImageHeight>0)?_subloadImageHeight:_image->t(),
(GLenum) _image->getPixelFormat(), (GLenum) _image->getDataType(),
_image->data());
_image->data(_subloadImageOffsetX,_subloadImageOffsetY));
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
// update the modified flag to show that the image has been loaded.
modifiedTag = _image->getModifiedTag();
}
@ -517,29 +552,39 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
}
GLsizei width = (_subloadWidth>0)?_subloadWidth:image->s();
GLsizei height = (_subloadHeight>0)?_subloadHeight:image->t();
GLsizei width = (_subloadImageWidth>0)?_subloadImageWidth:image->s();
GLsizei height = (_subloadImageHeight>0)?_subloadImageHeight:image->t();
if (_textureWidth==0)
{
// need to calculate texture dimension
_textureWidth = 1;
for (; _textureWidth < (static_cast<GLsizei>(_subloadTextureOffsetX) + width); _textureWidth <<= 1) {}
}
if (_textureHeight==0)
{
// need to calculate texture dimension
_textureHeight = 1;
for (; _textureHeight < (static_cast<GLsizei>(_subloadTextureOffsetY) + height); _textureHeight <<= 1) {}
}
// calculate texture dimension
_textureWidth = 1;
for (; _textureWidth < (static_cast<GLsizei>(_subloadOffsX) + width); _textureWidth <<= 1)
;
_textureHeight = 1;
for (; _textureHeight < (static_cast<GLsizei>(_subloadOffsY) + height); _textureHeight <<= 1)
;
// reserve appropriate texture memory
glTexImage2D(target, 0, internalFormat,
_textureWidth, _textureHeight, 0,
(GLenum) image->getPixelFormat(), (GLenum) image->getDataType(),
NULL);
glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowSizeInBytes());
glTexSubImage2D(target, 0,
_subloadOffsX, _subloadOffsY,
_subloadTextureOffsetX, _subloadTextureOffsetY,
width, height,
(GLenum) image->getPixelFormat(), (GLenum) image->getDataType(),
image->data());
image->data(_subloadImageOffsetX,_subloadImageOffsetY));
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
}
}

View File

@ -195,20 +195,31 @@ void TextureCubeMap::apply(State& state) const
modifiedTag = 0;
glBindTexture( _target, handle );
if (_texParamtersDirty) applyTexParameters(_target,state);
unsigned int rowwidth = 0;
for (int n=0; n<6; n++)
{
if ((_subloadMode == AUTO) ||
(_subloadMode == IF_DIRTY && modifiedTag != _images[n]->getModifiedTag()))
{
if (rowwidth != _images[n]->getRowSizeInBytes())
{
rowwidth = _images[n]->getRowSizeInBytes();
glPixelStorei(GL_UNPACK_ROW_LENGTH,rowwidth);
}
glTexSubImage2D(faceTarget[n], 0,
_subloadOffsX, _subloadOffsY,
(_subloadWidth>0)?_subloadWidth:_images[n]->s(), (_subloadHeight>0)?_subloadHeight:_images[n]->t(),
_subloadTextureOffsetX, _subloadTextureOffsetX,
(_subloadImageWidth>0)?_subloadImageWidth:_images[n]->s(), (_subloadImageHeight>0)?_subloadImageHeight:_images[n]->t(),
(GLenum) _images[n]->getPixelFormat(), (GLenum) _images[n]->getDataType(),
_images[n]->data());
_images[n]->data(_subloadImageOffsetX,_subloadImageOffsetY));
// update the modified flag to show that the image has been loaded.
modifiedTag += _images[n]->getModifiedTag();
}
}
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
}
}
else if (imagesValid())