Changeset 13041 for OpenSceneGraph/trunk/src/osg/Texture2DArray.cpp
- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
-
OpenSceneGraph/trunk/src/osg/Texture2DArray.cpp (modified) (39 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osg/Texture2DArray.cpp
r12993 r13041 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 5 * (at your option) any later version. The full license is in LICENSE file 6 6 * included with this distribution, and on the openscenegraph.org website. 7 * 7 * 8 8 * This library is distributed in the hope that it will be useful, 9 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 * OpenSceneGraph Public License for more details. 12 12 */ … … 60 60 if (noImages && _images[n].valid()) noImages = false; 61 61 if (noImages && rhs._images[n].valid()) noImages = false; 62 62 63 63 if (_images[n]!=rhs._images[n]) // smart pointer comparison. 64 64 { … … 72 72 else 73 73 { 74 return 1; // valid lhs._image is greater than null. 74 return 1; // valid lhs._image is greater than null. 75 75 } 76 76 } 77 else if (rhs._images[n].valid()) 78 { 79 return -1; // valid rhs._image is greater than null. 80 } 81 } 82 } 83 84 77 else if (rhs._images[n].valid()) 78 { 79 return -1; // valid rhs._image is greater than null. 80 } 81 } 82 } 83 84 85 85 if (noImages) 86 86 { … … 110 110 return; 111 111 } 112 112 113 113 if (_images[layer] == image) return; 114 114 … … 144 144 } 145 145 } 146 146 147 147 void Texture2DArray::setTextureSize(int width, int height, int depth) 148 148 { … … 154 154 155 155 void Texture2DArray::setTextureDepth(int depth) 156 { 156 { 157 157 // if we decrease the number of layers, then delete non-used 158 158 if (depth < _textureDepth) … … 161 161 _modifiedCount.resize(depth); 162 162 } 163 163 164 164 // if we increase the array, then add new empty elements 165 165 if (depth > _textureDepth) … … 168 168 _modifiedCount.resize(depth, ImageModifiedCount()); 169 169 } 170 170 171 171 // resize the texture array 172 172 _textureDepth = depth; … … 196 196 void Texture2DArray::computeInternalFormat() const 197 197 { 198 if (imagesValid()) computeInternalFormatWithImage(*_images[0]); 198 if (imagesValid()) computeInternalFormatWithImage(*_images[0]); 199 199 else computeInternalFormatType(); 200 200 } … … 203 203 void Texture2DArray::apply(State& state) const 204 204 { 205 // get the contextID (user defined ID of 0 upwards) for the 205 // get the contextID (user defined ID of 0 upwards) for the 206 206 // current OpenGL context. 207 207 const unsigned int contextID = state.getContextID(); … … 219 219 return; 220 220 } 221 221 222 222 // get the texture object for the current contextID. 223 223 TextureObject* textureObject = getTextureObject(contextID); … … 245 245 } 246 246 247 // if we already have an texture object, then 247 // if we already have an texture object, then 248 248 if (textureObject) 249 249 { … … 265 265 { 266 266 osg::Image* image = _images[n].get(); 267 267 268 268 // if image content is modified, then upload it to the GPU memory 269 269 if (image && getModifiedCount(n,contextID) != image->getModifiedCount()) … … 276 276 277 277 } 278 278 279 279 // there is no texture object, but exists a subload callback, so use it to upload images 280 280 else if (_subloadCallback.valid()) … … 286 286 _subloadCallback->load(*this,state); 287 287 } 288 288 289 289 // nothing before, but we have valid images, so do manual upload and create texture object manually 290 290 // TODO: we assume _images[0] is valid, however this may not be always the case … … 301 301 textureObject = generateTextureObject( 302 302 this, contextID,GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); 303 303 304 304 // bind texture 305 305 textureObject->bind(); … … 311 311 int sourceFormat = _sourceFormat ? _sourceFormat : _internalFormat; 312 312 313 if( isCompressedInternalFormat( sourceFormat ) && 313 if( isCompressedInternalFormat( sourceFormat ) && 314 314 sourceFormat == _internalFormat && 315 315 extensions->isCompressedTexImage3DSupported() ) … … 321 321 } 322 322 else 323 { 323 { 324 324 // Override compressed source format with safe GL_RGBA value which not generate error 325 325 // We can safely do this as source format is not important when source data is NULL … … 330 330 _textureWidth, _textureHeight, _textureDepth, _borderWidth, 331 331 sourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 332 0); 332 0); 333 333 } 334 334 335 335 // For certain we have to manually allocate memory for mipmaps if images are compressed 336 336 // if not allocated OpenGL will produce errors on mipmap upload. 337 // I have not tested if this is neccessary for plain texture formats but 337 // I have not tested if this is neccessary for plain texture formats but 338 338 // common sense suggests its required as well. 339 339 if( _min_filter != LINEAR && _min_filter != NEAREST && _images[0]->isMipmap() ) … … 354 354 355 355 const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true); 356 // source images have no mipmamps but we could generate them... 357 if( _min_filter != LINEAR && _min_filter != NEAREST && !_images[0]->isMipmap() && 356 // source images have no mipmamps but we could generate them... 357 if( _min_filter != LINEAR && _min_filter != NEAREST && !_images[0]->isMipmap() && 358 358 _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported() ) 359 359 { … … 363 363 364 364 textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); 365 365 366 366 // unref image data? 367 367 if (isSafeToUnrefImageData(state)) … … 369 369 Texture2DArray* non_const_this = const_cast<Texture2DArray*>(this); 370 370 for (int n=0; n<_textureDepth; n++) 371 { 371 { 372 372 if (_images[n].valid() && _images[n]->getDataVariance()==STATIC) 373 373 { … … 376 376 } 377 377 } 378 379 } 380 378 379 } 380 381 381 // No images present, but dimensions are set. So create empty texture 382 382 else if ( (_textureWidth > 0) && (_textureHeight > 0) && (_textureDepth > 0) && (_internalFormat!=0) ) 383 383 { 384 // generate texture 384 // generate texture 385 385 _textureObjectBuffer[contextID] = textureObject = generateTextureObject( 386 386 this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); 387 387 388 388 textureObject->bind(); 389 389 applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state); 390 390 391 391 extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat, 392 392 _textureWidth, _textureHeight, _textureDepth, … … 394 394 _sourceFormat ? _sourceFormat : _internalFormat, 395 395 _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 396 0); 397 398 } 399 396 0); 397 398 } 399 400 400 // nothing before, so just unbind the texture target 401 401 else … … 418 418 return; 419 419 420 // get the contextID (user defined ID of 0 upwards) for the 420 // get the contextID (user defined ID of 0 upwards) for the 421 421 // current OpenGL context. 422 422 const unsigned int contextID = state.getContextID(); 423 const Extensions* extensions = getExtensions(contextID,true); 423 const Extensions* extensions = getExtensions(contextID,true); 424 424 const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true); 425 425 GLenum target = GL_TEXTURE_2D_ARRAY_EXT; 426 426 427 427 // compute the internal texture format, this set the _internalFormat to an appropriate value. 428 428 computeInternalFormat(); … … 437 437 // we give a warning and do nothing 438 438 OSG_WARN<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) the given layer number exceeds the maximum number of supported layers."<<std::endl; 439 return; 439 return; 440 440 } 441 441 … … 447 447 448 448 // image size or format has changed, this is not allowed, hence return 449 if (image->s()!=inwidth || 450 image->t()!=inheight || 451 image->getInternalTextureFormat()!=inInternalFormat ) 449 if (image->s()!=inwidth || 450 image->t()!=inheight || 451 image->getInternalTextureFormat()!=inInternalFormat ) 452 452 { 453 453 OSG_WARN<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) given image do have wrong dimension or internal format."<<std::endl; 454 return; 455 } 456 454 return; 455 } 456 457 457 glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 458 458 #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) … … 460 460 #endif 461 461 462 bool useHardwareMipmapGeneration = 462 bool useHardwareMipmapGeneration = 463 463 !image->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported(); 464 464 … … 481 481 image->data() ); 482 482 } 483 483 484 484 // if we support compression and image is compressed, then 485 485 else if (extensions->isCompressedTexImage3DSupported()) … … 491 491 492 492 extensions->glCompressedTexSubImage3D(target, 0, 493 0, 0, indepth, 494 inwidth, inheight, 1, 493 0, 0, indepth, 494 inwidth, inheight, 1, 495 495 (GLenum)image->getPixelFormat(), 496 size, 496 size, 497 497 image->data()); 498 498 } … … 526 526 527 527 extensions->glTexSubImage3D( target, k, 0, 0, indepth, 528 width, height, 1, 528 width, height, 1, 529 529 (GLenum)image->getPixelFormat(), 530 530 (GLenum)image->getDataType(), … … 599 599 // get the texture object for the current contextID. 600 600 TextureObject* textureObject = getTextureObject(contextID); 601 601 602 602 if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0) 603 { 603 { 604 604 const Extensions* extensions = getExtensions(contextID,true); 605 605 … … 608 608 // Make sure source format does not contain compressed formats value (like DXT3) 609 609 // they are invalid when passed to glTexImage3D source format parameter 610 if( isCompressedInternalFormat( safeSourceFormat ) ) 610 if( isCompressedInternalFormat( safeSourceFormat ) ) 611 611 { 612 612 if( safeSourceFormat != _internalFormat || !extensions->isCompressedTexImage3DSupported() ) … … 625 625 width >>= 1; 626 626 height >>= 1; 627 627 628 628 for( GLsizei k = 1; k < numMipmapLevels && (width || height); k++) 629 629 { … … 633 633 height = 1; 634 634 635 if( isCompressedInternalFormat(safeSourceFormat) ) 635 if( isCompressedInternalFormat(safeSourceFormat) ) 636 636 { 637 637 int size = 0, blockSize = 0; … … 639 639 getCompressedSize( _internalFormat, width, height, _textureDepth, blockSize, size); 640 640 641 extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat, 641 extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat, 642 642 width, height, _textureDepth, _borderWidth, 643 643 size, … … 648 648 extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat, 649 649 width, height, _textureDepth, _borderWidth, 650 safeSourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 650 safeSourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 651 651 NULL); 652 652 } … … 655 655 height >>= 1; 656 656 } 657 657 658 658 // inform state that this texture is the current one bound. 659 state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); 659 state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); 660 660 } 661 661 } … … 685 685 _isTexture3DSupported = rhs._isTexture3DSupported; 686 686 _isTexture2DArraySupported = rhs._isTexture2DArraySupported; 687 687 688 688 _max2DSize = rhs._max2DSize; 689 689 _maxLayerCount = rhs._maxLayerCount; 690 690 691 691 _glTexImage3D = rhs._glTexImage3D; 692 692 _glTexSubImage3D = rhs._glTexSubImage3D;
