From cce00c475b5c87368e886d088a1b4f511a0ca289 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 5 Jul 2004 21:09:30 +0000 Subject: [PATCH] Added suppor for copying mipmaps of compressed textures --- include/osg/Image | 2 +- src/osg/Image.cpp | 134 ++++++++++++++++++++++++++++++------- src/osgTerrain/DataSet.cpp | 32 +++++++-- 3 files changed, 137 insertions(+), 31 deletions(-) diff --git a/include/osg/Image b/include/osg/Image index c2b859bdb..f1e14bd7e 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -106,7 +106,7 @@ class SG_EXPORT Image : public Object /** read the contents of the current bound texture, handling compressed pixelFormats if present. * Create memory for storage if required, reuse existing pixel coords if possible.*/ - void readImageFromCurrentTexture(unsigned int contextID=0); + void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable); /** Scale image to specified size. */ diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 4fdc736bd..bd3f246f5 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -403,50 +403,136 @@ void Image::readPixels(int x,int y,int width,int height, } -void Image::readImageFromCurrentTexture(unsigned int contextID) +void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable) { const osg::Texture::Extensions* extensions = osg::Texture::getExtensions(contextID,true); 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); + if (width==0 || height==0 || depth==0) break; + } + } + else + { + numMipMaps = 1; + } + + + GLint compressed = 0; if (extensions->isCompressedTexImage2DSupported()) { - GLint compressed; - GLint compressed_size; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB,&compressed); + } + + /* if the compression has been successful */ + if (compressed == GL_TRUE) + { - /* if the compression has been successful */ - if (compressed == GL_TRUE) + MipmapDataType mipMapData; + + unsigned int total_size = 0; + GLint i; + for(i=0;i0) mipMapData.push_back(total_size); - extensions->glGetCompressedTexImage(GL_TEXTURE_2D, 0, _data); + GLint compressed_size; + glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed_size); - _internalTextureFormat = internalformat; - - return; + total_size += compressed_size; } + + osg::notify(osg::WARN)<<"********** reading from compressed texture -------------------."<glGetCompressedTexImage(GL_TEXTURE_2D, i, getMipmapData(i)); + } + } + else + { + MipmapDataType mipMapData; - // non compressed texture implemention. - 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); + unsigned int total_size = 0; + GLint i; + for(i=0;i0) 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); + + unsigned int level_size = computeRowWidthInBytes(width,_pixelFormat,GL_UNSIGNED_BYTE,_packing)*height*depth; - allocateImage(width,height,1,internalformat,GL_UNSIGNED_BYTE); + total_size += level_size; + } + + + unsigned char* data = new unsigned char[total_size]; + if (!data) + { + osg::notify(osg::WARN)<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<setMaxAnisotropy(_dataSet->getMaxAnisotropy()); stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); bool inlineImageFile = _dataSet->getDestinationTileExtension()==".ive"; + bool compressedImageSupported = inlineImageFile; + bool mipmapImageSupported = inlineImageFile; std::cout<<"__________________image->getPixelFormat()="<getPixelFormat()<getTextureType()==COMPRESSED_TEXTURE && (image->getPixelFormat()==GL_RGB || image->getPixelFormat()==GL_RGBA)) { texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION); osg::ref_ptr state = new osg::State; + + // force the mip mapping off temporay if we intend the graphics hardware to do the mipmapping. + if (_dataSet->getMipMappingMode()==DataSet::MIP_MAPPING_HARDWARE) + texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); + + // get OpenGL driver to create texture from image. texture->apply(*state); - image->readImageFromCurrentTexture(); + image->readImageFromCurrentTexture(0,true); + + // restore the mip mapping mode. + if (_dataSet->getMipMappingMode()==DataSet::MIP_MAPPING_HARDWARE) + texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); std::cout<<">>>>>>>>>>>>>>>compress image.<<<<<<<<<<<<<<"<getTextureType()==RGB_16_BIT && - image->getPixelFormat()==GL_RGB) + } + else { - image->scaleImage(image->s(),image->t(),image->r(),GL_UNSIGNED_SHORT_5_6_5); + if (_dataSet->getTextureType()==RGB_16_BIT && image->getPixelFormat()==GL_RGB) + { + image->scaleImage(image->s(),image->t(),image->r(),GL_UNSIGNED_SHORT_5_6_5); + } + + if (mipmapImageSupported && _dataSet->getMipMappingMode()==DataSet::MIP_MAPPING_IMAGERY) + { + image->computeMipMaps(); + } } if (!inlineImageFile)