Added Texuture::SubloadCallback example into the osgprerender demo to illustrate
how to use it. Changed the ImpostorSprite to use LINEAR,LINEAR for min and mag filters for the impostor texture.
This commit is contained in:
@@ -105,12 +105,18 @@ class SG_EXPORT Image : public Object
|
||||
inline const unsigned char *data() const { return _data; }
|
||||
|
||||
|
||||
unsigned char* data(int column, int row=0,int image=0)
|
||||
inline unsigned char* data(int column, int row=0,int image=0)
|
||||
{
|
||||
if (!_data) return NULL;
|
||||
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
|
||||
}
|
||||
|
||||
inline const unsigned char* data(int column, int row=0,int image=0) const
|
||||
{
|
||||
if (!_data) return NULL;
|
||||
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
|
||||
}
|
||||
|
||||
/** Flip the image horizontally.*/
|
||||
void flipHorizontal(int image=0);
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
|
||||
/** 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 setSubloadTextureSize(const int width, const int height)
|
||||
inline void setSubloadTextureSize(const int width, const int height) const
|
||||
{
|
||||
_textureWidth = width;
|
||||
_textureHeight = height;
|
||||
@@ -288,6 +288,21 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
height = _subloadImageHeight;
|
||||
}
|
||||
|
||||
class SubloadCallback : public Referenced
|
||||
{
|
||||
public:
|
||||
virtual void load(GLenum target, const Texture& texture,State& state) const = 0;
|
||||
virtual void subload(GLenum target, const Texture& texture,State& state) const = 0;
|
||||
};
|
||||
|
||||
void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb; _subloadMode = cb ? USE_CALLBACK:OFF; }
|
||||
|
||||
SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); }
|
||||
|
||||
const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); }
|
||||
|
||||
|
||||
|
||||
/** Get the handle to the texture object for the current context.*/
|
||||
/** return the OpenGL texture object for specified context.*/
|
||||
inline GLuint& getTextureObject(const uint contextID) const
|
||||
@@ -321,26 +336,15 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
virtual void compile(State& state) const;
|
||||
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with,*/
|
||||
/** Set the number of mip map levels the the texture has been created with,
|
||||
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with.*/
|
||||
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
|
||||
|
||||
|
||||
|
||||
class SubloadCallback : public Referenced
|
||||
{
|
||||
public:
|
||||
virtual void load(GLenum target, const Texture& texture,State& state) const;
|
||||
virtual void subload(GLenum target, const Texture& texture,State& state) const;
|
||||
};
|
||||
|
||||
void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb; _subloadMode = cb ? USE_CALLBACK:OFF; }
|
||||
|
||||
SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); }
|
||||
|
||||
const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); }
|
||||
|
||||
|
||||
|
||||
/** use deleteTextureObject instead of glDeleteTextures to allow
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <osgGLUT/glut>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
|
||||
class MyAppCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
@@ -284,6 +283,119 @@ class MyGeometryCallback :
|
||||
|
||||
};
|
||||
|
||||
// Custom Texture subload callback, just acts the the standard subload modes in osg::Texture right now
|
||||
// but code be used to define your own style callbacks.
|
||||
class MyTextureSubloadCallback : public osg::Texture::SubloadCallback
|
||||
{
|
||||
public:
|
||||
virtual void load(GLenum target, const osg::Texture& texture,osg::State&) const
|
||||
{
|
||||
osg::notify(osg::INFO)<<"doing load"<<std::endl;
|
||||
|
||||
static bool s_SGIS_GenMipmap = osg::isGLExtensionSupported("GL_SGIS_generate_mipmap");
|
||||
|
||||
if (s_SGIS_GenMipmap && (texture.getFilter(osg::Texture::MIN_FILTER) != osg::Texture::LINEAR && texture.getFilter(osg::Texture::MIN_FILTER) != osg::Texture::NEAREST))
|
||||
{
|
||||
texture.setNumMipmapLevels(1); // will leave this at one, since the mipmap will be created internally by OpenGL.
|
||||
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture.setNumMipmapLevels(1);
|
||||
}
|
||||
|
||||
int subloadImageOffsetX;
|
||||
int subloadImageOffsetY;
|
||||
texture.getSubloadImageOffset(subloadImageOffsetX,subloadImageOffsetY);
|
||||
|
||||
int subloadImageWidth;
|
||||
int subloadImageHeight;
|
||||
texture.getSubloadImageSize(subloadImageWidth,subloadImageHeight);
|
||||
|
||||
GLsizei width = (subloadImageWidth>0)?subloadImageWidth:texture.getImage()->s();
|
||||
GLsizei height = (subloadImageHeight>0)?subloadImageHeight:texture.getImage()->t();
|
||||
|
||||
int subloadTextureOffsetX;
|
||||
int subloadTextureOffsetY;
|
||||
texture.getSubloadTextureOffset(subloadTextureOffsetX,subloadTextureOffsetY);
|
||||
|
||||
int textureWidth;
|
||||
int textureHeight;
|
||||
texture.getSubloadTextureSize(textureWidth, textureHeight);
|
||||
|
||||
bool sizeChanged = false;
|
||||
if (textureWidth==0)
|
||||
{
|
||||
// need to calculate texture dimension
|
||||
sizeChanged = true;
|
||||
textureWidth = 1;
|
||||
for (; textureWidth < (static_cast<GLsizei>(subloadTextureOffsetX) + width); textureWidth <<= 1) {}
|
||||
}
|
||||
|
||||
if (textureHeight==0)
|
||||
{
|
||||
// need to calculate texture dimension
|
||||
sizeChanged = true;
|
||||
textureHeight = 1;
|
||||
for (; textureHeight < (static_cast<GLsizei>(subloadTextureOffsetY) + height); textureHeight <<= 1) {}
|
||||
}
|
||||
|
||||
if (sizeChanged)
|
||||
{
|
||||
texture.setSubloadTextureSize(textureWidth, textureHeight);
|
||||
}
|
||||
|
||||
// reserve appropriate texture memory
|
||||
glTexImage2D(target, 0, texture.getInternalFormatValue(),
|
||||
textureWidth, textureHeight, 0,
|
||||
(GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(),
|
||||
NULL);
|
||||
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH,texture.getImage()->s());
|
||||
|
||||
|
||||
glTexSubImage2D(target, 0,
|
||||
subloadTextureOffsetX, subloadTextureOffsetY,
|
||||
width, height,
|
||||
(GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(),
|
||||
texture.getImage()->data(subloadImageOffsetX,subloadImageOffsetY));
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
|
||||
|
||||
}
|
||||
|
||||
virtual void subload(GLenum target, const osg::Texture& texture,osg::State&) const
|
||||
{
|
||||
osg::notify(osg::INFO)<<"doing subload"<<std::endl;
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH,texture.getImage()->s());
|
||||
|
||||
int subloadTextureOffsetX;
|
||||
int subloadTextureOffsetY;
|
||||
texture.getSubloadTextureOffset(subloadTextureOffsetX,subloadTextureOffsetY);
|
||||
|
||||
int subloadImageOffsetX;
|
||||
int subloadImageOffsetY;
|
||||
texture.getSubloadImageOffset(subloadImageOffsetX,subloadImageOffsetY);
|
||||
|
||||
int subloadImageWidth;
|
||||
int subloadImageHeight;
|
||||
texture.getSubloadImageSize(subloadImageWidth,subloadImageHeight);
|
||||
|
||||
glTexSubImage2D(target, 0,
|
||||
subloadTextureOffsetX, subloadTextureOffsetY,
|
||||
(subloadImageWidth>0)?subloadImageWidth:texture.getImage()->s(), (subloadImageHeight>0)?subloadImageHeight:texture.getImage()->t(),
|
||||
(GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(),
|
||||
texture.getImage()->data(subloadImageOffsetX,subloadImageOffsetY));
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
{
|
||||
@@ -348,28 +460,13 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
image->setInternalTextureFormat(GL_RGBA);
|
||||
|
||||
osg::Texture* texture = new osg::Texture;
|
||||
texture->setSubloadMode(osg::Texture::IF_DIRTY);
|
||||
//texture->setSubloadMode(osg::Texture::IF_DIRTY);
|
||||
texture->setSubloadCallback(new MyTextureSubloadCallback());
|
||||
texture->setImage(image);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
|
||||
stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
|
||||
|
||||
// {
|
||||
// // set up the second tex coord array for the an additional texture
|
||||
// // to add texture to the flag.
|
||||
// polyGeom->setTexCoordArray(1,texcoords);
|
||||
//
|
||||
// osg::Image* overlay_image = osgDB::readImageFile("tank.rgb");
|
||||
// osg::Texture* overlay_texture = new osg::Texture;
|
||||
// overlay_texture->setImage(overlay_image);
|
||||
// stateset->setTextureAttributeAndModes(1, overlay_texture,osg::StateAttribute::ON);
|
||||
//
|
||||
// osg::TexEnv* overlay_texenv = new osg::TexEnv;
|
||||
// overlay_texenv->setMode(osg::TexEnv::BLEND);
|
||||
// overlay_texenv->setColor(osg::Vec4(0.3f,0.3f,0.3f,1.0f));
|
||||
// stateset->setTextureAttribute(1, overlay_texenv);
|
||||
// }
|
||||
|
||||
polyGeom->setStateSet(stateset);
|
||||
|
||||
polyGeom->setAppCallback(new MyGeometryCallback(origin,xAxis,yAxis,zAxis,1.0,1.0/width,0.2f));
|
||||
@@ -381,10 +478,8 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
|
||||
parent->setAppCallback(new MyAppCallback(subgraph));
|
||||
|
||||
// parent->setCullCallback(new MyCullCallback(subgraph,texture));
|
||||
parent->setCullCallback(new MyCullCallback(subgraph,image));
|
||||
|
||||
// parent->addChild(billboard);
|
||||
parent->addChild(geode);
|
||||
|
||||
return parent;
|
||||
|
||||
@@ -254,6 +254,8 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i
|
||||
stateset->setAttributeAndModes( _alphafunc.get(), StateAttribute::ON );
|
||||
|
||||
Texture* texture = osgNew Texture;
|
||||
texture->setFilter(Texture::MIN_FILTER,Texture::LINEAR);
|
||||
texture->setFilter(Texture::MAG_FILTER,Texture::LINEAR);
|
||||
|
||||
stateset->setTextureAttributeAndModes(0,texture,StateAttribute::ON);
|
||||
stateset->setTextureAttribute(0,_texenv.get());
|
||||
|
||||
Reference in New Issue
Block a user