diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index b919693da..b93eabfe5 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -508,6 +508,7 @@ osg::Node* createCube(float size,float alpha, unsigned int numSlices, float slic } osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptr& normalmap_3d, + osg::Texture::InternalFormatMode internalFormatMode, float xSize, float ySize, float zSize, float xMultiplier, float yMultiplier, float zMultiplier, unsigned int numSlices=500, float sliceEnd=1.0f, float alphaFuncValue=0.02f) @@ -606,6 +607,8 @@ osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptrsetWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP); bump_texture3D->setImage(normalmap_3d.get()); + bump_texture3D->setInternalFormatMode(internalFormatMode); + stateset->setTextureAttributeAndModes(0,bump_texture3D,osg::StateAttribute::ON); osg::TexEnvCombine* tec = new osg::TexEnvCombine; @@ -643,6 +646,10 @@ osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptrsetInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); texture3D->setInternalFormat(GL_INTENSITY); } + else + { + texture3D->setInternalFormatMode(internalFormatMode); + } texture3D->setImage(image_3d.get()); stateset->setTextureAttributeAndModes(1,texture3D,osg::StateAttribute::ON); @@ -665,6 +672,8 @@ osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptrsetWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP); bump_texture3D->setImage(normalmap_3d.get()); + bump_texture3D->setInternalFormatMode(internalFormatMode); + stateset->setTextureAttributeAndModes(0,bump_texture3D,osg::StateAttribute::ON); osg::TexEnvCombine* tec = new osg::TexEnvCombine; @@ -709,6 +718,11 @@ osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptrsetInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); texture3D->setInternalFormat(GL_INTENSITY); } + else + { + texture3D->setInternalFormatMode(internalFormatMode); + } + texture3D->setImage(image_3d.get()); stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); @@ -747,6 +761,11 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->addCommandLineOption("--s_maxTextureSize","Set the texture maximum resolution in the s (x) dimension."); arguments.getApplicationUsage()->addCommandLineOption("--t_maxTextureSize","Set the texture maximum resolution in the t (y) dimension."); arguments.getApplicationUsage()->addCommandLineOption("--r_maxTextureSize","Set the texture maximum resolution in the r (z) dimension."); + arguments.getApplicationUsage()->addCommandLineOption("--compressed","Enable the usage of compressed textures"); + arguments.getApplicationUsage()->addCommandLineOption("--compressed-arb","Enable the usage of OpenGL ARB compressed textures"); + arguments.getApplicationUsage()->addCommandLineOption("--compressed-dxt1","Enable the usage of S3TC DXT1 compressed textures"); + arguments.getApplicationUsage()->addCommandLineOption("--compressed-dxt3","Enable the usage of S3TC DXT3 compressed textures"); + arguments.getApplicationUsage()->addCommandLineOption("--compressed-dxt5","Enable the usage of S3TC DXT5 compressed textures"); // construct the viewer. osgProducer::Viewer viewer(arguments); @@ -806,6 +825,12 @@ int main( int argc, char **argv ) while(arguments.read("--t_maxTextureSize",t_maximumTextureSize)) {} while(arguments.read("--r_maxTextureSize",r_maximumTextureSize)) {} + osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT; + while(arguments.read("--compressed") || arguments.read("--compressed-arb")) { internalFormatMode = osg::Texture::USE_ARB_COMPRESSION; } + + while(arguments.read("--compressed-dxt1")) { internalFormatMode = osg::Texture::USE_S3TC_DXT1_COMPRESSION; } + while(arguments.read("--compressed-dxt3")) { internalFormatMode = osg::Texture::USE_S3TC_DXT3_COMPRESSION; } + while(arguments.read("--compressed-dxt5")) { internalFormatMode = osg::Texture::USE_S3TC_DXT5_COMPRESSION; } osg::ref_ptr image_3d; @@ -853,8 +878,11 @@ int main( int argc, char **argv ) osg::ref_ptr normalmap_3d = createNormalMap ? createNormalMapTexture(image_3d.get()) : 0; + + // create a model from the images. osg::Node* rootNode = createModel(image_3d, normalmap_3d, + internalFormatMode, xSize, ySize, zSize, xMultiplier, yMultiplier, zMultiplier, numSlices, sliceEnd, alphaFunc); diff --git a/include/osg/Texture3D b/include/osg/Texture3D index 2e1836a61..e7e7c134f 100644 --- a/include/osg/Texture3D +++ b/include/osg/Texture3D @@ -138,7 +138,7 @@ class SG_EXPORT Texture3D : public Texture Extensions(const Extensions& rhs); void lowestCommonDenominator(const Extensions& rhs); - + void setupGLExtenions(); void setTexture3DSupported(bool flag) { _isTexture3DSupported=flag; } @@ -159,6 +159,14 @@ class SG_EXPORT Texture3D : public Texture void setCopyTexSubImage3DProc(void* ptr) { _glCopyTexSubImage3D = ptr; } void glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) const; + bool isCompressedTexImage3DSupported() const { return _glCompressedTexImage3D!=0; } + void setCompressedTexImage3DProc(void* ptr) { _glCompressedTexImage3D = ptr; } + void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const; + + bool isCompressedTexSubImage3DSupported() const { return _glCompressedTexSubImage3D!=0; } + void setCompressedTexSubImage3DProc(void* ptr) { _glCompressedTexSubImage3D = ptr; } + void glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ) const; + void setBuild3DMipmapsProc(void* ptr) { _gluBuild3DMipmaps = ptr; } void gluBuild3DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) const; @@ -172,6 +180,8 @@ class SG_EXPORT Texture3D : public Texture void* _glTexImage3D; void* _glTexSubImage3D; + void* _glCompressedTexImage3D; + void* _glCompressedTexSubImage3D; void* _glCopyTexSubImage3D; void* _gluBuild3DMipmaps; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 4c757f214..2c5043d65 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "dxtctool.h" @@ -404,20 +405,31 @@ void Image::readPixels(int x,int y,int width,int height, void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable) { const osg::Texture::Extensions* extensions = osg::Texture::getExtensions(contextID,true); + const osg::Texture3D::Extensions* extensions3D = osg::Texture3D::getExtensions(contextID,true); + + + GLboolean binding1D, binding2D, binding3D; + glGetBooleanv(GL_TEXTURE_BINDING_1D, &binding1D); + glGetBooleanv(GL_TEXTURE_BINDING_2D, &binding2D); + glGetBooleanv(GL_TEXTURE_BINDING_3D, &binding3D); + + GLenum textureMode = binding1D ? GL_TEXTURE_1D : binding2D ? GL_TEXTURE_2D : binding3D ? GL_TEXTURE_3D : 0; + + if (textureMode==0) return; GLint internalformat; GLint width; GLint height; GLint depth; - + GLint numMipMaps = 0; if (copyMipMapsIfAvailable) { for(;numMipMaps<20;++numMipMaps) { - glGetTexLevelParameteriv(GL_TEXTURE_2D, numMipMaps, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, numMipMaps, GL_TEXTURE_HEIGHT, &height); - glGetTexLevelParameteriv(GL_TEXTURE_2D, numMipMaps, GL_TEXTURE_DEPTH, &depth); + glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_HEIGHT, &height); + glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_DEPTH, &depth); if (width==0 || height==0 || depth==0) break; } } @@ -429,11 +441,23 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps GLint compressed = 0; - if (extensions->isCompressedTexImage2DSupported()) + if (textureMode==GL_TEXTURE_2D) { - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB,&compressed); + if (extensions->isCompressedTexImage2DSupported()) + { + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB,&compressed); + } + } + else if (textureMode==GL_TEXTURE_2D) + { + if (extensions3D->isCompressedTexImage3DSupported()) + { + glGetTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED_ARB,&compressed); + } } + + /* if the compression has been successful */ if (compressed == GL_TRUE) { @@ -447,7 +471,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps if (i>0) mipMapData.push_back(total_size); GLint compressed_size; - glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed_size); + glGetTexLevelParameteriv(textureMode, i, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed_size); total_size += compressed_size; } @@ -462,10 +486,10 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps deallocateData(); // and sets it to NULL. - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_HEIGHT, &height); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_DEPTH, &depth); _data = data; _s = width; @@ -480,7 +504,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps for(i=0;iglGetCompressedTexImage(GL_TEXTURE_2D, i, getMipmapData(i)); + extensions->glGetCompressedTexImage(textureMode, i, getMipmapData(i)); } ++_modifiedTag; @@ -496,9 +520,9 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps { if (i>0) mipMapData.push_back(total_size); - glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &height); - glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_DEPTH, &depth); + glGetTexLevelParameteriv(textureMode, i, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(textureMode, i, GL_TEXTURE_HEIGHT, &height); + glGetTexLevelParameteriv(textureMode, i, GL_TEXTURE_DEPTH, &depth); unsigned int level_size = computeRowWidthInBytes(width,_pixelFormat,GL_UNSIGNED_BYTE,_packing)*height*depth; @@ -515,10 +539,10 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps deallocateData(); // and sets it to NULL. - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_HEIGHT, &height); + glGetTexLevelParameteriv(textureMode, 0, GL_TEXTURE_DEPTH, &depth); _data = data; _s = width; @@ -533,7 +557,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps for(i=0;i #include -typedef void (APIENTRY * MyCompressedTexImage2DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); - using namespace osg; Texture2D::Texture2D(): diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index c18bb55bc..54c3e2f0c 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -205,8 +205,8 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz bool compressed = isCompressedInternalFormat(_internalFormat); if (compressed) { - notify(WARN)<<"Warning::cannot currently use compressed format with 3D textures."<ensureValidSizeForTexturing(extensions->maxTexture3DSize()); @@ -345,6 +345,8 @@ void Texture3D::Extensions::lowestCommonDenominator(const Extensions& rhs) if (!rhs._glTexImage3D) _glTexImage3D = 0; if (!rhs._glTexSubImage3D) _glTexSubImage3D = 0; + if (!rhs._glCompressedTexImage3D) _glTexImage3D = 0; + if (!rhs._glCompressedTexSubImage3D) _glTexSubImage3D = 0; if (!rhs._glCopyTexSubImage3D) _glCopyTexSubImage3D = 0; if (!rhs._gluBuild3DMipmaps) _gluBuild3DMipmaps = 0; } @@ -358,10 +360,12 @@ void Texture3D::Extensions::setupGLExtenions() glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &_maxTexture3DSize); - _glTexImage3D = getGLExtensionFuncPtr("glTexImage3D","glTexImage3DEXT");; - _glTexSubImage3D = getGLExtensionFuncPtr("glTexSubImage3D","glTexSubImage3DEXT"); - _glCopyTexSubImage3D = getGLExtensionFuncPtr("glCopyTexSubImage3D","glCopyTexSubImage3DEXT"); - _gluBuild3DMipmaps = getGLExtensionFuncPtr("gluBuild3DMipmaps"); + _glTexImage3D = getGLExtensionFuncPtr("glTexImage3D","glTexImage3DEXT"); + _glTexSubImage3D = getGLExtensionFuncPtr("glTexSubImage3D","glTexSubImage3DEXT"); + _glCompressedTexImage3D = getGLExtensionFuncPtr("glCompressedTexImage3D","glCompressedTexImage3DARB"); + _glCompressedTexSubImage3D = getGLExtensionFuncPtr("glCompressedTexSubImage3D","glCompressedTexSubImage3DARB"); + _glCopyTexSubImage3D = getGLExtensionFuncPtr("glCopyTexSubImage3D","glCopyTexSubImage3DEXT"); + _gluBuild3DMipmaps = getGLExtensionFuncPtr("gluBuild3DMipmaps"); } @@ -393,6 +397,32 @@ void Texture3D::Extensions::glTexSubImage3D( GLenum target, GLint level, GLint x } } +void Texture3D::Extensions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const +{ + if (_glCompressedTexImage3D) + { + typedef void (APIENTRY * CompressedTexImage3DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); + ((CompressedTexImage3DArbProc)_glCompressedTexImage3D)(target, level, internalformat, width, height, depth, border, imageSize, data); + } + else + { + notify(WARN)<<"Error: glCompressedTexImage3D not supported by OpenGL driver"<