00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include <boost/bind.hpp>
00047
00048 #include "OSGConfig.h"
00049
00050 #include <OSGGL.h>
00051 #include <OSGGLU.h>
00052 #include <OSGGLEXT.h>
00053 #include <OSGImage.h>
00054
00055 #include <OSGRenderTraversalActionBase.h>
00056 #include <OSGDrawActionBase.h>
00057 #include <OSGDrawEnv.h>
00058
00059 #include <OSGTextureObjChunk.h>
00060
00061
00062
00063 OSG_USING_NAMESPACE
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 typedef OSG::Window Win;
00075
00076 UInt32 TextureObjChunk::_extTex3D = Win::invalidExtensionID;
00077 UInt32 TextureObjChunk::_arbCubeTex = Win::invalidExtensionID;
00078 UInt32 TextureObjChunk::_sgisGenerateMipmap = Win::invalidExtensionID;
00079 UInt32 TextureObjChunk::_arbTextureCompression = Win::invalidExtensionID;
00080 UInt32 TextureObjChunk::_arbTextureRectangle = Win::invalidExtensionID;
00081 UInt32 TextureObjChunk::_arbTextureNonPowerOfTwo = Win::invalidExtensionID;
00082 UInt32 TextureObjChunk::_extTextureFilterAnisotropic = Win::invalidExtensionID;
00083 UInt32 TextureObjChunk::_extShadow = Win::invalidExtensionID;
00084 UInt32 TextureObjChunk::_extDepthTexture = Win::invalidExtensionID;
00085
00086 UInt32 TextureObjChunk::_funcTexImage3D = Win::invalidFunctionID;
00087 UInt32 TextureObjChunk::_funcTexSubImage3D = Win::invalidFunctionID;
00088 UInt32 TextureObjChunk::_funcCompressedTexImage1D = Win::invalidFunctionID;
00089 UInt32 TextureObjChunk::_funcCompressedTexSubImage1D = Win::invalidFunctionID;
00090 UInt32 TextureObjChunk::_funcCompressedTexImage2D = Win::invalidFunctionID;
00091 UInt32 TextureObjChunk::_funcCompressedTexSubImage2D = Win::invalidFunctionID;
00092 UInt32 TextureObjChunk::_funcCompressedTexImage3D = Win::invalidFunctionID;
00093 UInt32 TextureObjChunk::_funcCompressedTexSubImage3D = Win::invalidFunctionID;
00094
00095
00096 #ifndef GL_VERSION_1_2
00097 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3DEXT"
00098 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3DEXT"
00099 #else
00100 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3D"
00101 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3D"
00102 #endif
00103
00104
00105 StatElemDesc<StatIntOnceElem> TextureObjChunk::statNTextures(
00106 "NTextures",
00107 "number of texture changes");
00108
00109 StatElemDesc<StatIntOnceElem> TextureObjChunk::statNTexBytes(
00110 "NTexBytes",
00111 "sum of all used textures' sizes (approx., in bytes)");
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void TextureObjChunk::initMethod(InitPhase ePhase)
00123 {
00124 Inherited::initMethod(ePhase);
00125
00126 if(ePhase == TypeObject::SystemPost)
00127 {
00128 _extTex3D =
00129 Window::registerExtension("GL_EXT_texture3D" );
00130 _arbCubeTex =
00131 Window::registerExtension("GL_ARB_texture_cube_map");
00132 _sgisGenerateMipmap =
00133 Window::registerExtension("GL_SGIS_generate_mipmap" );
00134 _arbTextureCompression =
00135 Window::registerExtension("GL_ARB_texture_compression" );
00136 _arbTextureRectangle =
00137 Window::registerExtension("GL_ARB_texture_rectangle" );
00138 _arbTextureNonPowerOfTwo =
00139 Window::registerExtension("GL_ARB_texture_non_power_of_two" );
00140 _extTextureFilterAnisotropic =
00141 Window::registerExtension("GL_EXT_texture_filter_anisotropic" );
00142
00143 _extShadow =
00144 Window::registerExtension("GL_ARB_shadow" );
00145 _extDepthTexture =
00146 Window::registerExtension("GL_ARB_depth_texture" );
00147
00148 _funcTexImage3D =
00149 Window::registerFunction (GL_FUNC_TEXIMAGE3D,
00150 _extTex3D,
00151 0x0102 );
00152 _funcTexSubImage3D =
00153 Window::registerFunction (GL_FUNC_TEXSUBIMAGE3D,
00154 _extTex3D,
00155 0x0102);
00156
00157 _funcCompressedTexImage1D = Window::registerFunction(
00158 OSG_DLSYM_UNDERSCORE"glCompressedTexImage1DARB" ,
00159 _arbTextureCompression);
00160
00161 _funcCompressedTexSubImage1D = Window::registerFunction(
00162 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage1DARB" ,
00163 _arbTextureCompression);
00164
00165 _funcCompressedTexImage2D = Window::registerFunction(
00166 OSG_DLSYM_UNDERSCORE"glCompressedTexImage2DARB" ,
00167 _arbTextureCompression);
00168
00169 _funcCompressedTexSubImage2D = Window::registerFunction(
00170 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage2DARB" ,
00171 _arbTextureCompression);
00172
00173 _funcCompressedTexImage3D = Window::registerFunction(
00174 OSG_DLSYM_UNDERSCORE"glCompressedTexImage3DARB" ,
00175 _arbTextureCompression);
00176
00177 _funcCompressedTexSubImage3D = Window::registerFunction(
00178 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage3DARB" ,
00179 _arbTextureCompression);
00180
00181 Window::registerConstant(GL_MAX_TEXTURE_UNITS_ARB );
00182 Window::registerConstant(GL_MAX_TEXTURE_IMAGE_UNITS_ARB);
00183 Window::registerConstant(GL_MAX_TEXTURE_COORDS_ARB );
00184 }
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 TextureObjChunk::TextureObjChunk(void) :
00199 Inherited()
00200 {
00201 }
00202
00203 TextureObjChunk::TextureObjChunk(const TextureObjChunk &source) :
00204 Inherited(source)
00205 {
00206 }
00207
00208 TextureObjChunk::~TextureObjChunk(void)
00209 {
00210 if(getGLId() > 0)
00211 Window::destroyGLObject(getGLId(), 1);
00212 }
00213
00214
00215
00216 bool TextureObjChunk::isCubeTexture(void)
00217 {
00218 return
00219 this->getImage() != NullFC &&
00220 this->getImage()->getSideCount() == 6;
00221 }
00222
00223
00224
00230 void TextureObjChunk::changed(ConstFieldMaskArg whichField,
00231 UInt32 origin,
00232 BitVector details)
00233 {
00234 GLenum id = _sfGLId.getValue();
00235 #ifdef GV_CHECK
00236 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00237 {
00238 if(getGLId() == 0)
00239 {
00240 TextureObjChunkPtr tmpPtr(*this);
00241
00242 beginEditCP(tmpPtr, TextureObjChunk::GLIdFieldMask);
00243
00244 setGLId(
00245 Window::registerGLObject(
00246 boost::bind(&TextureObjChunk::handleGL, tmpPtr,
00247 _1, _2, _3),
00248 &TextureObjChunk::handleDestroyGL
00249 ));
00250
00251 endEditCP(tmpPtr, TextureObjChunk::GLIdFieldMask);
00252 }
00253 }
00254 #endif
00255
00256
00257 if((whichField & ~(MinFilterFieldMask | MagFilterFieldMask)) == 0)
00258 {
00259 if((getMinFilter() != GL_NEAREST) &&
00260 (getMinFilter() != GL_LINEAR))
00261 {
00262 #ifdef GV_CHECK
00263 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00264 {
00265 #endif
00266 Window::reinitializeGLObject(id);
00267 #ifdef GV_CHECK
00268 }
00269 #endif
00270 }
00271 else
00272 {
00273 imageContentChanged();
00274 }
00275 }
00276 else if((whichField & ~PriorityFieldMask || FrameFieldMask) == 0)
00277 {
00278 imageContentChanged();
00279 }
00280 else if ((whichField & ~(DirtyMinXFieldMask | DirtyMaxXFieldMask |
00281 DirtyMinYFieldMask | DirtyMaxYFieldMask |
00282 DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
00283 {
00284 #ifdef GV_CHECK
00285 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00286 {
00287 #endif
00288 Window::refreshGLObject(id);
00289 #ifdef GV_CHECK
00290 }
00291 #endif
00292 }
00293 else
00294 {
00295 #ifdef GV_CHECK
00296 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00297 {
00298 #endif
00299 if(origin == ChangedOrigin::Child &&
00300 0x0000 != (whichField & ImageFieldMask))
00301 {
00302 if((details & ~(Image::PixelFieldMask)) == 0)
00303 {
00304 Window::refreshGLObject(id);
00305 }
00306 else
00307 {
00308 if(0x0000 != (whichField & (Image::WidthFieldMask |
00309 Image::HeightFieldMask |
00310 Image::DepthFieldMask)))
00311 {
00312 Window::reinitializeGLObject(id);
00313 }
00314 }
00315 }
00316 else
00317 {
00318 Window::reinitializeGLObject(id);
00319 }
00320 #ifdef GV_CHECK
00321 }
00322 #endif
00323 }
00324
00325 Inherited::changed(whichField, origin, details);
00326 }
00327
00328 bool TextureObjChunk::isTransparent(void) const
00329 {
00330
00331
00332 return false;
00333 }
00334
00335
00336
00337
00338 void TextureObjChunk::onCreate(const TextureObjChunk *source)
00339 {
00340 Inherited::onCreate(source);
00341
00342 if(GlobalSystemState == Startup)
00343 return;
00344
00345 #ifdef GV_CHECK
00346 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00347 {
00348 #endif
00349
00350 setGLId(Window::registerGLObject(
00351 boost::bind(&TextureObjChunk::handleGL, this,
00352 _1, _2, _3),
00353 &TextureObjChunk::handleDestroyGL
00354 ));
00355
00356 #ifdef GV_CHECK
00357 }
00358 #endif
00359 }
00360
00361 void TextureObjChunk::onCreateAspect(const TextureObjChunk *createAspect,
00362 const TextureObjChunk *source )
00363 {
00364 Inherited::onCreateAspect(createAspect, source);
00365 }
00366
00367
00368
00369 void TextureObjChunk::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00370 const BitVector OSG_CHECK_ARG(bvFlags )) const
00371 {
00372 SLOG << "Dump TextureObjChunk NI" << std::endl;
00373 }
00374
00375
00376
00377 void TextureObjChunk::handleTexture(Window *win,
00378 UInt32 id,
00379 GLenum bindtarget,
00380 GLenum paramtarget,
00381 GLenum imgtarget,
00382 Window::GLObjectStatusE mode,
00383 ImagePtr img,
00384 Int32 side)
00385 {
00386 if( img==NullFC || ! img->getDimension())
00387 return;
00388
00389 if(mode == Window::initialize || mode == Window::reinitialize)
00390 {
00391 if( bindtarget == GL_TEXTURE_3D &&
00392 !win->hasExtension(_extTex3D) &&
00393 win->getGLVersion() < 0x0102 )
00394 {
00395 FNOTICE(("3D textures not supported on Window %p!\n", win));
00396 return;
00397 }
00398
00399 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB &&
00400 !win->hasExtension(_arbTextureRectangle))
00401 {
00402 FNOTICE(("Rectangular textures not supported on Window %p!\n",
00403 win));
00404 return;
00405 }
00406
00407 if(paramtarget == GL_TEXTURE_CUBE_MAP_ARB &&
00408 !win->hasExtension(_arbCubeTex))
00409 {
00410 FNOTICE(("Cube textures not supported on Window %p!\n", win));
00411 return;
00412 }
00413
00414 if(img->hasCompressedData() &&
00415 !win->hasExtension(_arbTextureCompression))
00416 {
00417 FNOTICE(("Compressed textures not supported on Window %p!\n",
00418 win));
00419 return;
00420 }
00421
00422 #if 0 // ????? GV
00423 if(mode == Window::reinitialize)
00424 {
00425 GLuint tex = id;
00426 glDeleteTextures(1, &tex);
00427 }
00428 #endif
00429
00430
00431 void (OSG_APIENTRY *TexImage3D)(GLenum target,
00432 GLint level,
00433 GLenum internalformat,
00434 GLsizei width,
00435 GLsizei height,
00436 GLsizei depth,
00437 GLint border,
00438 GLenum format,
00439 GLenum type,
00440 const GLvoid *pixels) =
00441 (void (OSG_APIENTRY*)(GLenum target,
00442 GLint level,
00443 GLenum internalformat,
00444 GLsizei width,
00445 GLsizei height,
00446 GLsizei depth,
00447 GLint border,
00448 GLenum format,
00449 GLenum type,
00450 const GLvoid *pixels))
00451 win->getFunction(_funcTexImage3D);
00452
00453 void (OSG_APIENTRY*TexSubImage3D)
00454 (GLenum target, GLint level, GLint xoffset,
00455 GLint yoffset, GLint zoffset, GLsizei width,
00456 GLsizei height, GLsizei depth, GLenum format,
00457 GLenum type, const GLvoid *pixels) =
00458 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset,
00459 GLint yoffset, GLint zoffset, GLsizei width,
00460 GLsizei height, GLsizei depth, GLenum format,
00461 GLenum type, const GLvoid *pixels))
00462 win->getFunction(_funcTexSubImage3D);
00463
00464
00465
00466 void (OSG_APIENTRY*CompressedTexImage1D)(GLenum target,
00467 GLint level,
00468 GLenum internalformat,
00469 GLsizei width, GLint border,
00470 GLsizei imageSize,
00471 const GLvoid *pixels) =
00472 (void (OSG_APIENTRY*)(GLenum target,
00473 GLint level,
00474 GLenum internalformat,
00475 GLsizei width,
00476 GLint border,
00477 GLsizei imageSize,
00478 const GLvoid *pixels))
00479 win->getFunction(_funcCompressedTexImage1D);
00480
00481 void (OSG_APIENTRY*CompressedTexSubImage1D)(GLenum target,
00482 GLint level,
00483 GLint xoffset,
00484 GLsizei width,
00485 GLenum format,
00486 GLsizei imageSize,
00487 const GLvoid *pixels) =
00488 (void (OSG_APIENTRY*)(GLenum target,
00489 GLint level,
00490 GLint xoffset,
00491 GLsizei width,
00492 GLenum format,
00493 GLsizei imageSize,
00494 const GLvoid *pixels))
00495 win->getFunction(_funcCompressedTexSubImage1D);
00496
00497 void (OSG_APIENTRY*CompressedTexImage2D)(GLenum target,
00498 GLint level,
00499 GLenum internalformat,
00500 GLsizei width,
00501 GLsizei height,
00502 GLint border,
00503 GLsizei imageSize,
00504 const GLvoid *pixels) =
00505 (void (OSG_APIENTRY*)(GLenum target,
00506 GLint level,
00507 GLenum internalformat,
00508 GLsizei width,
00509 GLsizei height,
00510 GLint border,
00511 GLsizei imageSize,
00512 const GLvoid *pixels))
00513 win->getFunction(_funcCompressedTexImage2D);
00514
00515 void (OSG_APIENTRY*CompressedTexSubImage2D)(GLenum target,
00516 GLint level,
00517 GLint xoffset,
00518 GLint yoffset,
00519 GLsizei width,
00520 GLsizei height,
00521 GLenum format,
00522 GLsizei imageSize,
00523 const GLvoid *pixels) =
00524 (void (OSG_APIENTRY*)(GLenum target,
00525 GLint level,
00526 GLint xoffset,
00527 GLint yoffset,
00528 GLsizei width,
00529 GLsizei height,
00530 GLenum format,
00531 GLsizei imageSize,
00532 const GLvoid *pixels))
00533 win->getFunction(_funcCompressedTexSubImage2D);
00534
00535 void (OSG_APIENTRY*CompressedTexImage3D)(GLenum target,
00536 GLint level,
00537 GLenum internalformat,
00538 GLsizei width,
00539 GLsizei height,
00540 GLsizei depth,
00541 GLint border,
00542 GLsizei imageSize,
00543 const GLvoid *pixels) =
00544 (void (OSG_APIENTRY*)(GLenum target,
00545 GLint level,
00546 GLenum internalformat,
00547 GLsizei width,
00548 GLsizei height,
00549 GLsizei depth,
00550 GLint border,
00551 GLsizei imageSize,
00552 const GLvoid *pixels))
00553 win->getFunction(_funcCompressedTexImage3D);
00554
00555 void (OSG_APIENTRY*CompressedTexSubImage3D)(GLenum target,
00556 GLint level,
00557 GLint xoffset,
00558 GLint yoffset,
00559 GLint zoffset,
00560 GLsizei width,
00561 GLsizei height,
00562 GLsizei depth,
00563 GLenum format,
00564 GLsizei imageSize,
00565 const GLvoid *pixels) =
00566 (void (OSG_APIENTRY*)(GLenum target,
00567 GLint level,
00568 GLint xoffset,
00569 GLint yoffset,
00570 GLint zoffset,
00571 GLsizei width,
00572 GLsizei height,
00573 GLsizei depth,
00574 GLenum format,
00575 GLsizei imageSize,
00576 const GLvoid *pixels))
00577 win->getFunction(_funcCompressedTexSubImage3D);
00578
00579
00580
00581 if(! img || ! img->getDimension())
00582 return;
00583
00584 glErr("TextureObjChunk::initialize precheck");
00585
00586 FDEBUG(("texture (re-)initialize\n"));
00587
00588 glBindTexture(bindtarget, id);
00589
00590 if(paramtarget != GL_NONE)
00591 {
00592
00593 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY, getPriority());
00594 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, getMinFilter());
00595 glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER, getMagFilter());
00596 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_S, getWrapS());
00597
00598 if(paramtarget == GL_TEXTURE_2D ||
00599 paramtarget == GL_TEXTURE_3D ||
00600 paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00601 {
00602 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_T, getWrapT());
00603 }
00604
00605 if(paramtarget == GL_TEXTURE_3D ||
00606 paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00607 {
00608 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_R, getWrapR());
00609 }
00610
00611 if(getAnisotropy() > 1.0f &&
00612 win->hasExtension(_extTextureFilterAnisotropic))
00613 {
00614 glTexParameterf(paramtarget,
00615 GL_TEXTURE_MAX_ANISOTROPY_EXT,
00616 getAnisotropy());
00617 }
00618
00619 glTexParameterfv(paramtarget,
00620 GL_TEXTURE_BORDER_COLOR,
00621 (GLfloat *) getBorderColor().getValuesRGBA());
00622
00623 if(getCompareMode() != GL_NONE &&
00624 win->hasExtension(_extShadow))
00625 {
00626 glTexParameteri(paramtarget,
00627 GL_TEXTURE_COMPARE_MODE,
00628 getCompareMode());
00629 glTexParameteri(paramtarget,
00630 GL_TEXTURE_COMPARE_FUNC,
00631 getCompareFunc());
00632 }
00633
00634 if(getDepthMode() != GL_LUMINANCE &&
00635 win->hasExtension(_extDepthTexture))
00636 {
00637 glTexParameteri(paramtarget,
00638 GL_DEPTH_TEXTURE_MODE,
00639 getDepthMode());
00640 }
00641
00642 glErr("TextureObjChunk::initialize params");
00643 }
00644
00645
00646 GLenum internalFormat = getInternalFormat();
00647 GLenum externalFormat = img->getPixelFormat();
00648 GLenum type = img->getDataType();
00649 UInt32 width = img->getWidth();
00650 UInt32 height = img->getHeight();
00651 UInt32 depth = img->getDepth();
00652 bool compressedData = img->hasCompressedData();
00653
00654 bool doScale = getScale();
00655 UInt32 frame = getFrame();
00656
00657 bool defined = false;
00658 bool needMipmaps = getMinFilter() == GL_NEAREST_MIPMAP_NEAREST ||
00659 getMinFilter() == GL_LINEAR_MIPMAP_NEAREST ||
00660 getMinFilter() == GL_NEAREST_MIPMAP_LINEAR ||
00661 getMinFilter() == GL_LINEAR_MIPMAP_LINEAR ;
00662
00663 if(internalFormat == GL_NONE)
00664 {
00665 switch(externalFormat)
00666 {
00667 #if defined(GL_BGR) && defined(GL_BGR_EXT)
00668 case GL_BGR:
00669 #else
00670 # if defined(GL_BGR)
00671 case GL_BGR:
00672 # endif
00673 # if defined(GL_BGR_EXT)
00674 case GL_BGR_EXT:
00675 # endif
00676 #endif
00677 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00678 internalFormat = GL_RGB;
00679 break;
00680 #endif
00681 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
00682 case GL_BGRA:
00683 #else
00684 # if defined(GL_BGRA)
00685 case GL_BGRA:
00686 # endif
00687 # if defined(GL_BGRA_EXT)
00688 case GL_BGRA_EXT:
00689 # endif
00690 #endif
00691 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00692 internalFormat = GL_RGBA;
00693 break;
00694 #endif
00695 case GL_INTENSITY:
00696 internalFormat = GL_INTENSITY;
00697 externalFormat = GL_LUMINANCE;
00698 break;
00699
00700 default:
00701 internalFormat = externalFormat;
00702 break;
00703 }
00704 }
00705
00706 if(getExternalFormat() != GL_NONE)
00707 externalFormat = getExternalFormat();
00708
00709 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && needMipmaps)
00710 {
00711 SWARNING << "TextureObjChunk::initialize1: Can't do mipmaps"
00712 << "with GL_TEXTURE_RECTANGLE_ARB target! Ignored"
00713 << std::endl;
00714 needMipmaps= false;
00715 }
00716
00717
00718 if(needMipmaps)
00719 {
00720
00721 if(img->getMipMapCount() == img->calcMipmapLevelCount() &&
00722 osgIsPower2(width) && osgIsPower2(height) &&
00723 osgIsPower2(depth)
00724 )
00725 {
00726 for(UInt16 i = 0; i < img->getMipMapCount(); i++)
00727 {
00728 UInt32 w, h, d;
00729 img->calcMipmapGeometry(i, w, h, d);
00730
00731 if(compressedData)
00732 {
00733 switch (imgtarget)
00734 {
00735 case GL_TEXTURE_1D:
00736 CompressedTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00737 w, getBorderWidth(),
00738 img->calcMipmapLevelSize(i),
00739 img->getData(i, frame, side));
00740 break;
00741 case GL_TEXTURE_2D:
00742 CompressedTexImage2D(imgtarget, i, internalFormat,
00743 w, h, getBorderWidth(),
00744 img->calcMipmapLevelSize(i),
00745 img->getData(i, frame, side));
00746 break;
00747 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00748 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00749 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00750 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00751 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00752 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00753 CompressedTexImage2D(imgtarget, i, internalFormat,
00754 w, h, getBorderWidth(),
00755 img->calcMipmapLevelSize(i),
00756 img->getData(i, frame, side));
00757 break;
00758 case GL_TEXTURE_3D:
00759 CompressedTexImage3D(GL_TEXTURE_3D, i, internalFormat,
00760 w, h, d, getBorderWidth(),
00761 img->calcMipmapLevelSize(i),
00762 img->getData(i, frame, side));
00763 break;
00764 default:
00765 SFATAL << "TextureObjChunk::initialize1: unknown target "
00766 << imgtarget << "!!!" << std::endl;
00767 break;
00768 }
00769 }
00770 else
00771 {
00772 switch (imgtarget)
00773 {
00774 case GL_TEXTURE_1D:
00775 glTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00776 w, getBorderWidth(),
00777 externalFormat, type,
00778 img->getData(i, frame, side));
00779 break;
00780 case GL_TEXTURE_2D:
00781 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00782 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00783 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00784 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00785 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00786 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00787 glTexImage2D(imgtarget, i, internalFormat,
00788 w, h, getBorderWidth(),
00789 externalFormat, type,
00790 img->getData(i, frame, side));
00791 break;
00792 case GL_TEXTURE_3D:
00793 TexImage3D(GL_TEXTURE_3D, i, internalFormat,
00794 w, h, d, getBorderWidth(),
00795 externalFormat, type,
00796 img->getData(i, frame, side));
00797 break;
00798 default:
00799 SFATAL << "TextureObjChunk::initialize1: unknown target "
00800 << imgtarget << "!!!" << std::endl;
00801 break;
00802 }
00803 }
00804 }
00805 defined = true;
00806 }
00807
00808 if(! defined)
00809 {
00810
00811 if(win->hasExtension(_sgisGenerateMipmap))
00812 {
00813 if(paramtarget != GL_NONE)
00814 glTexParameteri(paramtarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00815 glErr("TextureObjChunk::activate generate_mipmaps");
00816 needMipmaps = false;
00817 }
00818 else
00819 {
00820
00821 void *data = NULL;
00822
00823
00824 if(! osgIsPower2(width) ||
00825 ! osgIsPower2(height) ||
00826 ! osgIsPower2(depth)
00827 )
00828 {
00829
00830 if(imgtarget != GL_TEXTURE_2D)
00831 {
00832 SWARNING << "TextureObjChunk::initialize: can't mipmap "
00833 << "non-2D textures that are not 2^x !!!"
00834 << std::endl;
00835 }
00836 else
00837 {
00838 UInt32 outw = osgNextPower2(width);
00839 UInt32 outh = osgNextPower2(height);
00840
00841 data = malloc(outw * outh * img->getBpp());
00842
00843
00844 if(doScale)
00845 {
00846 GLint res = gluScaleImage(externalFormat,
00847 width, height, type, img->getData(0, frame, side),
00848 outw, outh, type, data);
00849
00850 if(res)
00851 {
00852 SWARNING << "TextureObjChunk::initialize: "
00853 << "gluScaleImage failed: "
00854 << gluErrorString(res) << "("
00855 << res << ")!"
00856 << std::endl;
00857 free(data);
00858 data = NULL;
00859 }
00860 else
00861 {
00862 width = outw;
00863 height = outh;
00864 }
00865 }
00866 else
00867 {
00868 memset(data, 0, outw * outh * img->getBpp());
00869
00870 UInt16 bpl = width * img->getBpp();
00871 UInt8 * src = (UInt8 *) img->getData(0, frame, side);
00872 UInt8 * dest= (UInt8 *) data;
00873
00874 for(UInt32 y = 0; y < height; y++)
00875 {
00876 memcpy(dest, src, bpl);
00877
00878 src += bpl;
00879 dest += outw * img->getBpp();
00880 }
00881 width = outw;
00882 height = outh;
00883 }
00884 }
00885 }
00886 else
00887 {
00888 data = const_cast<void *>(
00889 static_cast<const void *>(img->getData(0,
00890 frame,
00891 side)));
00892 }
00893
00894 if(data)
00895 {
00896 switch (imgtarget)
00897 {
00898 case GL_TEXTURE_1D:
00899 gluBuild1DMipmaps(imgtarget, internalFormat, width,
00900 externalFormat, type, data);
00901 break;
00902 case GL_TEXTURE_2D:
00903 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00904 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00905 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00906 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00907 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00908 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00909 gluBuild2DMipmaps(imgtarget, internalFormat,
00910 width, height,
00911 externalFormat, type, data);
00912 break;
00913 case GL_TEXTURE_3D:
00914 # ifdef GLU_VERSION_1_3
00915 gluBuild3DMipmaps(imgtarget, internalFormat,
00916 width, height, depth,
00917 externalFormat, type, data);
00918 # else
00919 FWARNING(("TextureObjChunk::initialize: 3d textures "
00920 "supported, but GLU version < 1.3, thus "
00921 "gluBuild3DMipmaps not supported!\n"));
00922 # endif
00923 break;
00924 default:
00925 SFATAL << "TextureObjChunk::initialize2: unknown target "
00926 << imgtarget << "!!!" << std::endl;
00927 }
00928
00929 if(data != img->getData(0, frame, side))
00930 free(data);
00931 defined = true;
00932 }
00933 }
00934 }
00935 }
00936
00937
00938 if(! defined)
00939 {
00940
00941 if(needMipmaps && paramtarget != GL_NONE)
00942 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00943
00944 void * data = NULL;
00945 UInt32 datasize = 0;
00946
00947
00948 if(imgtarget != GL_TEXTURE_RECTANGLE_ARB &&
00949 !win->hasExtension(_arbTextureNonPowerOfTwo) &&
00950 (!osgIsPower2(width) || !osgIsPower2(height) || !osgIsPower2(depth))
00951 )
00952 {
00953
00954
00955
00956 if(doScale)
00957 {
00958
00959 if(imgtarget != GL_TEXTURE_2D &&
00960 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
00961 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
00962 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
00963 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
00964 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
00965 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
00966 )
00967 {
00968 SWARNING << "TextureObjChunk::initialize: can't scale "
00969 << "non-2D textures that are not 2^x !!!"
00970 << std::endl;
00971 }
00972 else
00973 {
00974 UInt32 outw = osgNextPower2(width);
00975 UInt32 outh = osgNextPower2(height);
00976
00977 data = malloc(outw * outh * img->getBpp());
00978 datasize = outw * outh * img->getBpp();
00979
00980 GLint res = gluScaleImage(externalFormat,
00981 width, height, type,
00982 img->getData(0, frame, side),
00983 outw, outh, type, data);
00984
00985 if(res)
00986 {
00987 SWARNING << "TextureObjChunk::initialize: "
00988 << "gluScaleImage failed: "
00989 << gluErrorString(res) << "("
00990 << res << ")!" << std::endl;
00991 free(data);
00992 data = NULL;
00993 }
00994 else
00995 {
00996 width = outw;
00997 height = outh;
00998 }
00999 }
01000 }
01001 else
01002 {
01003 if(compressedData)
01004 {
01005 switch (imgtarget)
01006 {
01007 case GL_TEXTURE_1D:
01008 CompressedTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01009 osgNextPower2(width), getBorderWidth(), 0, NULL);
01010 CompressedTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
01011 externalFormat,
01012 img->getFrameSize(),
01013 img->getData(0, frame, side));
01014 break;
01015 case GL_TEXTURE_2D:
01016 CompressedTexImage2D(imgtarget, 0, internalFormat,
01017 osgNextPower2(width),
01018 osgNextPower2(height),
01019 getBorderWidth(),
01020 0, NULL);
01021 CompressedTexSubImage2D(imgtarget, 0, 0, 0, width, height,
0102