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:
parent
02bb66a572
commit
6b59f66d80
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user