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 <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include "OSGConfig.h"
00047
00048 #include <OSGGL.h>
00049 #include <OSGGLU.h>
00050 #include <OSGGLEXT.h>
00051 #include <OSGImage.h>
00052
00053 #include "OSGDrawActionBase.h"
00054 #include "OSGRenderAction.h"
00055
00056 #include "OSGTextureChunk.h"
00057
00058 OSG_USING_NAMESPACE
00059
00060
00061
00062
00063
00064
00097
00098
00099
00100
00101 char TextureChunk::cvsid[] = "@(#)$Id: OSGTextureChunk.cpp,v 1.41 2002/06/17 12:27:14 jbehr Exp $";
00102
00103 StateChunkClass TextureChunk::_class("Texture", osgMaxTexImages);
00104
00105 UInt32 TextureChunk::_extTex3D;
00106 UInt32 TextureChunk::_arbMultiTex;
00107 UInt32 TextureChunk::_arbCubeTex;
00108 UInt32 TextureChunk::_nvPointSprite;
00109 UInt32 TextureChunk::_nvTextureShader;
00110 UInt32 TextureChunk::_nvTextureShader2;
00111 UInt32 TextureChunk::_nvTextureShader3;
00112 UInt32 TextureChunk::_sgisGenerateMipmap;
00113 UInt32 TextureChunk::_extTextureLodBias;
00114 UInt32 TextureChunk::_arbTextureCompression;
00115 UInt32 TextureChunk::_arbTextureRectangle;
00116 UInt32 TextureChunk::_funcTexImage3D = Window::invalidFunctionID;
00117 UInt32 TextureChunk::_funcTexSubImage3D = Window::invalidFunctionID;
00118 UInt32 TextureChunk::_funcActiveTexture = Window::invalidFunctionID;
00119 UInt32 TextureChunk::_funcCompressedTexImage1D = Window::invalidFunctionID;
00120 UInt32 TextureChunk::_funcCompressedTexSubImage1D = Window::invalidFunctionID;
00121 UInt32 TextureChunk::_funcCompressedTexImage2D = Window::invalidFunctionID;
00122 UInt32 TextureChunk::_funcCompressedTexSubImage2D = Window::invalidFunctionID;
00123 UInt32 TextureChunk::_funcCompressedTexImage3D = Window::invalidFunctionID;
00124 UInt32 TextureChunk::_funcCompressedTexSubImage3D = Window::invalidFunctionID;
00125
00126
00127 #ifndef GL_VERSION_1_2
00128 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3DEXT"
00129 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3DEXT"
00130 #else
00131 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3D"
00132 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3D"
00133 #endif
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void TextureChunk::initMethod (void)
00145 {
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 TextureChunk::TextureChunk(void) :
00160 Inherited()
00161 {
00162 _extTex3D =
00163 Window::registerExtension("GL_EXT_texture3D" );
00164 _arbMultiTex =
00165 Window::registerExtension("GL_ARB_multitexture" );
00166 _arbCubeTex =
00167 Window::registerExtension("GL_ARB_texture_cube_map" );
00168 _nvPointSprite =
00169 Window::registerExtension("GL_NV_point_sprite" );
00170 _nvTextureShader =
00171 Window::registerExtension("GL_NV_texture_shader" );
00172 _nvTextureShader2 =
00173 Window::registerExtension("GL_NV_texture_shader2" );
00174 _nvTextureShader3 =
00175 Window::registerExtension("GL_NV_texture_shader3" );
00176 _sgisGenerateMipmap =
00177 Window::registerExtension("GL_SGIS_generate_mipmap" );
00178 _extTextureLodBias =
00179 Window::registerExtension("GL_EXT_texture_lod_bias" );
00180 _arbTextureCompression =
00181 Window::registerExtension("GL_ARB_texture_compression" );
00182 _arbTextureRectangle =
00183 Window::registerExtension("GL_ARB_texture_rectangle" );
00184
00185 _funcTexImage3D =
00186 Window::registerFunction (GL_FUNC_TEXIMAGE3D ,
00187 _extTex3D);
00188 _funcTexSubImage3D =
00189 Window::registerFunction (GL_FUNC_TEXSUBIMAGE3D ,
00190 _extTex3D);
00191 _funcActiveTexture =
00192 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glActiveTextureARB" ,
00193 _arbMultiTex);
00194 _funcCompressedTexImage1D =
00195 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00196 "glCompressedTexImage1DARB" ,
00197 _arbTextureCompression);
00198 _funcCompressedTexSubImage1D =
00199 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00200 "glCompressedTexSubImage1DARB" ,
00201 _arbTextureCompression);
00202 _funcCompressedTexImage2D =
00203 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00204 "glCompressedTexImage2DARB" ,
00205 _arbTextureCompression);
00206 _funcCompressedTexSubImage2D =
00207 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00208 "glCompressedTexSubImage2DARB" ,
00209 _arbTextureCompression);
00210 _funcCompressedTexImage3D =
00211 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00212 "glCompressedTexImage3DARB" ,
00213 _arbTextureCompression);
00214 _funcCompressedTexSubImage3D =
00215 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00216 "glCompressedTexSubImage3DARB" ,
00217 _arbTextureCompression);
00218
00219 Window::registerConstant(GL_MAX_TEXTURE_UNITS_ARB);
00220 Window::registerConstant(GL_MAX_TEXTURE_IMAGE_UNITS_ARB);
00221 Window::registerConstant(GL_MAX_TEXTURE_COORDS_ARB);
00222 }
00223
00224 TextureChunk::TextureChunk(const TextureChunk &source) :
00225 Inherited(source)
00226 {
00227 }
00228
00229 TextureChunk::~TextureChunk(void)
00230 {
00231 if(_sfImage.getValue() != NullFC)
00232 subRefCP(_sfImage.getValue());
00233 if(getGLId() > 0)
00234 Window::destroyGLObject(getGLId(), 1);
00235 }
00236
00237
00238
00239 const StateChunkClass *TextureChunk::getClass(void) const
00240 {
00241 return &_class;
00242 }
00243
00244
00245
00251 void TextureChunk::changed(BitVector whichField, UInt32 origin)
00252 {
00253
00254 if((whichField & ~(MinFilterFieldMask | MagFilterFieldMask)) == 0)
00255 {
00256 if((getMinFilter() != GL_NEAREST) &&
00257 (getMinFilter() != GL_LINEAR))
00258 {
00259 Window::reinitializeGLObject(getGLId());
00260 }
00261 else
00262 {
00263 imageContentChanged();
00264 }
00265 }
00266 else if((whichField & ~(PriorityFieldMask | FrameFieldMask)) == 0)
00267 {
00268 imageContentChanged();
00269 }
00270 else if ((whichField & ~(DirtyMinXFieldMask | DirtyMaxXFieldMask |
00271 DirtyMinYFieldMask | DirtyMaxYFieldMask |
00272 DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
00273 {
00274 Window::refreshGLObject(getGLId());
00275 }
00276 else
00277 {
00278 Window::reinitializeGLObject(getGLId());
00279 }
00280
00281 if(whichField & ImageFieldMask)
00282 {
00283 if(origin & ChangedOrigin::Abstract)
00284 {
00285 if(origin & ChangedOrigin::AbstrIncRefCount)
00286 {
00287 addRefCP(_sfImage.getValue());
00288 }
00289 else
00290 {
00291 ImagePtr pImage = _sfImage.getValue();
00292
00293 _sfImage.setValue(NullFC);
00294
00295 setImage(pImage);
00296 }
00297 }
00298 }
00299
00300 Inherited::changed(whichField, origin);
00301 }
00302
00303 bool TextureChunk::isTransparent(void) const
00304 {
00305
00306
00307 return false;
00308 }
00309
00310
00311
00312
00313 void TextureChunk::onCreate(const TextureChunk *)
00314 {
00315 if(GlobalSystemState == Startup)
00316 return;
00317
00318
00319
00320
00321 TextureChunkPtr tmpPtr(*this);
00322
00323 beginEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00324
00325 setGLId(
00326 Window::registerGLObject(
00327 osgTypedMethodVoidFunctor2ObjCPtrPtr<TextureChunkPtr,
00328 Window ,
00329 UInt32>(
00330 tmpPtr,
00331 &TextureChunk::handleGL),
00332 1));
00333
00334 endEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00335 }
00336
00337
00338
00339
00340 void TextureChunk::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00341 const BitVector OSG_CHECK_ARG(bvFlags )) const
00342 {
00343 SLOG << "Dump TextureChunk NI" << std::endl;
00344 }
00345
00346
00347
00348
00353 void TextureChunk::handleTextureShader(Window *win, GLenum bindtarget)
00354 {
00355 if(!win->hasExtension(_nvTextureShader))
00356 {
00357 if(getShaderOperation() != GL_NONE)
00358 FINFO(("NV Texture Shaders not supported on Window %p!\n", win));
00359 return;
00360 }
00361
00362 glErr("textureShader precheck");
00363
00364 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
00365 getShaderOperation());
00366
00367 glErr("textureShader setup: operation");
00368
00369 if(getShaderOperation() == GL_NONE)
00370 return;
00371
00372 if(bindtarget == GL_TEXTURE_3D && !win->hasExtension(_nvTextureShader2))
00373 {
00374 FINFO(("NV Texture Shaders 2 not supported on Window %p!\n", win));
00375 return;
00376 }
00377
00378 if(getShaderInput() != GL_NONE)
00379 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,
00380 getShaderInput());
00381
00382 glErr("textureShader setup: input");
00383
00384 if(getShaderRGBADotProduct() != GL_NONE)
00385 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV,
00386 getShaderRGBADotProduct());
00387
00388 glErr("textureShader setup: rgba dotprod");
00389
00390 if(getShaderOffsetMatrix().size() == 4)
00391 {
00392 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,
00393 (GLfloat*)&(getShaderOffsetMatrix()[0]));
00394
00395 glErr("textureShader setup: offset matrix");
00396 }
00397 else if(getShaderOffsetMatrix().size() != 0)
00398 {
00399 FWARNING(("TextureChunk::handleTextureShader: shaderOffsetMatrix has"
00400 " to have 4 entries, not %d!\n",
00401 getShaderOffsetMatrix().size() ));
00402 }
00403
00404 glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV,
00405 getShaderOffsetScale());
00406
00407 glErr("textureShader setup: offset scale");
00408
00409 glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV,
00410 getShaderOffsetBias());
00411
00412 glErr("textureShader setup: offset bias");
00413
00414 GLint cullmodes[4];
00415 if(getShaderCullModes() & 0x1)
00416 {
00417 cullmodes[0] = GL_GEQUAL;
00418 }
00419 else
00420 {
00421 cullmodes[0] = GL_LESS;
00422 }
00423
00424 if(getShaderCullModes() & 0x2)
00425 {
00426 cullmodes[1] = GL_GEQUAL;
00427 }
00428 else
00429 {
00430 cullmodes[1] = GL_LESS;
00431 }
00432
00433 if(getShaderCullModes() & 0x4)
00434 {
00435 cullmodes[2] = GL_GEQUAL;
00436 }
00437 else
00438 {
00439 cullmodes[2] = GL_LESS;
00440 }
00441
00442 if(getShaderCullModes() & 0x8)
00443 {
00444 cullmodes[3] = GL_GEQUAL;
00445 }
00446 else
00447 {
00448 cullmodes[3] = GL_LESS;
00449 }
00450
00451 glTexEnviv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV,
00452 cullmodes);
00453
00454 glErr("textureShader setup: cull modes");
00455
00456 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV,
00457 getShaderConstEye().getValues());
00458
00459 glErr("textureShader setup: const eye");
00460
00461
00462
00463 #ifdef OSG_DEBUG
00464 GLint consistent;
00465 glGetTexEnviv(GL_TEXTURE_SHADER_NV, GL_SHADER_CONSISTENT_NV,
00466 &consistent);
00467 if(!consistent)
00468 {
00469 FWARNING(("Texture shaders not consistent!\n"));
00470 }
00471 #endif
00472 }
00473
00474 void TextureChunk::handleTexture(Window *win, UInt32 id,
00475 GLenum bindtarget,
00476 GLenum paramtarget,
00477 GLenum imgtarget,
00478 Window::GLObjectStatusE mode, ImagePtr img, int side)
00479 {
00480 if( img==NullFC || ! img->getDimension())
00481 return;
00482
00483 if(mode == Window::initialize || mode == Window::reinitialize)
00484 {
00485 if(bindtarget == GL_TEXTURE_3D && !win->hasExtension(_extTex3D))
00486 {
00487 FNOTICE(("3D textures not supported on Window %p!\n", win));
00488 return;
00489 }
00490
00491 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB &&
00492 !win->hasExtension(_arbTextureRectangle))
00493 {
00494 FNOTICE(("Rectangular textures not supported on Window %p!\n", win));
00495 return;
00496 }
00497
00498 if(paramtarget == GL_TEXTURE_CUBE_MAP_ARB &&
00499 !win->hasExtension(_arbCubeTex))
00500 {
00501 FNOTICE(("Cube textures not supported on Window %p!\n", win));
00502 return;
00503 }
00504
00505 if(img->hasCompressedData() &&
00506 !win->hasExtension(_arbTextureCompression))
00507 {
00508 FNOTICE(("Compressed textures not supported on Window %p!\n", win));
00509 return;
00510 }
00511
00512 if(mode == Window::reinitialize)
00513 {
00514 GLuint tex = id;
00515 glDeleteTextures(1, &tex);
00516 }
00517
00518
00519 void (OSG_APIENTRY*TexImage3D)(GLenum target, GLint level, GLenum internalformat,
00520 GLsizei width, GLsizei height, GLsizei depth,
00521 GLint border, GLenum format, GLenum type,
00522 const GLvoid *pixels) =
00523 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLenum internalformat,
00524 GLsizei width, GLsizei height, GLsizei depth,
00525 GLint border, GLenum format, GLenum type,
00526 const GLvoid *pixels))
00527 win->getFunction(_funcTexImage3D);
00528
00529 void (OSG_APIENTRY*TexSubImage3D)
00530 (GLenum target, GLint level, GLint xoffset,
00531 GLint yoffset, GLint zoffset, GLsizei width,
00532 GLsizei height, GLsizei depth, GLenum format,
00533 GLenum type, const GLvoid *pixels) =
00534 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset,
00535 GLint yoffset, GLint zoffset, GLsizei width,
00536 GLsizei height, GLsizei depth, GLenum format,
00537 GLenum type, const GLvoid *pixels))
00538 win->getFunction(_funcTexSubImage3D);
00539
00540
00541 void (OSG_APIENTRY*CompressedTexImage1D)(GLenum target, GLint level,
00542 GLenum internalformat, GLsizei width, GLint border,
00543 GLsizei imageSize, const GLvoid *pixels) =
00544 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00545 GLenum internalformat, GLsizei width, GLint border,
00546 GLsizei imageSize, const GLvoid *pixels))
00547 win->getFunction(_funcCompressedTexImage1D);
00548
00549 void (OSG_APIENTRY*CompressedTexSubImage1D)
00550 (GLenum target, GLint level, GLint xoffset, GLsizei width,
00551 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
00552 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset, GLsizei width,
00553 GLenum format, GLsizei imageSize, const GLvoid *pixels))
00554 win->getFunction(_funcCompressedTexSubImage1D);
00555
00556 void (OSG_APIENTRY*CompressedTexImage2D)(GLenum target, GLint level,
00557 GLenum internalformat, GLsizei width, GLsizei height,
00558 GLint border,
00559 GLsizei imageSize, const GLvoid *pixels) =
00560 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00561 GLenum internalformat, GLsizei width, GLsizei height,
00562 GLint border,
00563 GLsizei imageSize, const GLvoid *pixels))
00564 win->getFunction(_funcCompressedTexImage2D);
00565
00566 void (OSG_APIENTRY*CompressedTexSubImage2D)
00567 (GLenum target, GLint level,
00568 GLint xoffset, GLint yoffset,
00569 GLsizei width, GLsizei height, GLenum format,
00570 GLsizei imageSize, const GLvoid *pixels) =
00571 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00572 GLint xoffset, GLint yoffset,
00573 GLsizei width, GLsizei height, GLenum format,
00574 GLsizei imageSize, const GLvoid *pixels))
00575 win->getFunction(_funcCompressedTexSubImage2D);
00576
00577 void (OSG_APIENTRY*CompressedTexImage3D)(GLenum target, GLint level,
00578 GLenum internalformat,
00579 GLsizei width, GLsizei height, GLsizei depth,
00580 GLint border,
00581 GLsizei imageSize, const GLvoid *pixels) =
00582 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00583 GLenum internalformat,
00584 GLsizei width, GLsizei height, GLsizei depth,
00585 GLint border,
00586 GLsizei imageSize, const GLvoid *pixels))
00587 win->getFunction(_funcCompressedTexImage3D);
00588
00589 void (OSG_APIENTRY*CompressedTexSubImage3D)
00590 (GLenum target, GLint level,
00591 GLint xoffset, GLint yoffset, GLint zoffset,
00592 GLsizei width, GLsizei height, GLsizei depth,
00593 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
00594 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00595 GLint xoffset, GLint yoffset, GLint zoffset,
00596 GLsizei width, GLsizei height, GLsizei depth,
00597 GLenum format, GLsizei imageSize, const GLvoid *pixels))
00598 win->getFunction(_funcCompressedTexSubImage3D);
00599
00600
00601
00602 if(! img || ! img->getDimension())
00603 return;
00604
00605 glErr("TextureChunk::initialize precheck");
00606
00607 FDEBUG(("texture (re-)initialize\n"));
00608
00609 glBindTexture(bindtarget, id);
00610
00611 if(paramtarget != GL_NONE)
00612 {
00613
00614 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY, getPriority());
00615 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, getMinFilter());
00616 glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER, getMagFilter());
00617 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_S, getWrapS());
00618 if(paramtarget == GL_TEXTURE_2D ||
00619 paramtarget == GL_TEXTURE_3D ||
00620 paramtarget == GL_TEXTURE_CUBE_MAP_ARB
00621 )
00622 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_T, getWrapT());
00623 if(paramtarget == GL_TEXTURE_3D ||
00624 paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00625 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_R, getWrapR());
00626
00627 glErr("TextureChunk::initialize params");
00628 }
00629
00630
00631 GLenum internalFormat = getInternalFormat();
00632 GLenum externalFormat = img->getPixelFormat();
00633 GLenum type = img->getDataType();
00634 UInt32 width = img->getWidth();
00635 UInt32 height = img->getHeight();
00636 UInt32 depth = img->getDepth();
00637 bool compressedData = img->hasCompressedData();
00638
00639 bool doScale = getScale();
00640 UInt32 frame = getFrame();
00641
00642 bool defined = false;
00643 bool needMipmaps = getMinFilter() == GL_NEAREST_MIPMAP_NEAREST ||
00644 getMinFilter() == GL_LINEAR_MIPMAP_NEAREST ||
00645 getMinFilter() == GL_NEAREST_MIPMAP_LINEAR ||
00646 getMinFilter() == GL_LINEAR_MIPMAP_LINEAR ;
00647
00648 if(internalFormat == GL_NONE)
00649 {
00650 switch(externalFormat)
00651 {
00652 #if defined(GL_BGR) && defined(GL_BGR_EXT)
00653 case GL_BGR:
00654 #else
00655 # if defined(GL_BGR)
00656 case GL_BGR:
00657 # endif
00658 # if defined(GL_BGR_EXT)
00659 case GL_BGR_EXT:
00660 # endif
00661 #endif
00662 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00663 internalFormat = GL_RGB;
00664 break;
00665 #endif
00666 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
00667 case GL_BGRA:
00668 #else
00669 # if defined(GL_BGRA)
00670 case GL_BGRA:
00671 # endif
00672 # if defined(GL_BGRA_EXT)
00673 case GL_BGRA_EXT:
00674 # endif
00675 #endif
00676 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00677 internalFormat = GL_RGBA;
00678 break;
00679 #endif
00680 case GL_INTENSITY:
00681 internalFormat = GL_INTENSITY;
00682 externalFormat = GL_LUMINANCE;
00683 break;
00684
00685 default: internalFormat = externalFormat;
00686 break;
00687 }
00688 }
00689
00690 if(getExternalFormat() != GL_NONE)
00691 externalFormat = getExternalFormat();
00692
00693 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && needMipmaps)
00694 {
00695 SWARNING << "TextureChunk::initialize: Can't do mipmaps"
00696 << "with GL_TEXTURE_RECTANGLE_ARB target! Ignored"
00697 << std::endl;
00698 needMipmaps= false;
00699 }
00700
00701
00702 if(needMipmaps)
00703 {
00704
00705 if(img->getMipMapCount() == img->calcMipmapLevelCount() &&
00706 osgispower2(width) && osgispower2(height) &&
00707 osgispower2(depth)
00708 )
00709 {
00710 for(UInt16 i = 0; i < img->getMipMapCount(); i++)
00711 {
00712 UInt32 w, h, d;
00713 img->calcMipmapGeometry(i, w, h, d);
00714
00715 if(compressedData)
00716 {
00717 switch (imgtarget)
00718 {
00719 case GL_TEXTURE_1D:
00720 CompressedTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00721 w, 0,
00722 img->calcMipmapLevelSize(i),
00723 img->getData(i, frame, side));
00724 break;
00725 case GL_TEXTURE_2D:
00726 CompressedTexImage2D(imgtarget, i, internalFormat,
00727 w, h, 0,
00728 img->calcMipmapLevelSize(i),
00729 img->getData(i, frame, side));
00730 break;
00731 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00732 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00733 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00734 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00735 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00736 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00737 CompressedTexImage2D(imgtarget, i, internalFormat,
00738 w, h, 0,
00739 img->calcMipmapLevelSize(i),
00740 img->getData(i, frame, side));
00741 break;
00742 case GL_TEXTURE_3D:
00743 CompressedTexImage3D(GL_TEXTURE_3D, i, internalFormat,
00744 w, h, d, 0,
00745 img->calcMipmapLevelSize(i),
00746 img->getData(i, frame, side));
00747 break;
00748 default:
00749 SFATAL << "TextureChunk::initialize1: unknown target "
00750 << imgtarget << "!!!" << std::endl;
00751 break;
00752 }
00753 }
00754 else
00755 {
00756 switch (imgtarget)
00757 {
00758 case GL_TEXTURE_1D:
00759 glTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00760 w, 0,
00761 externalFormat, type,
00762 img->getData(i, frame, side));
00763 break;
00764 case GL_TEXTURE_2D:
00765 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00766 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00767 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00768 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00769 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00770 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00771 glTexImage2D(imgtarget, i, internalFormat,
00772 w, h, 0,
00773 externalFormat, type,
00774 img->getData(i, frame, side));
00775 break;
00776 case GL_TEXTURE_3D:
00777 TexImage3D(GL_TEXTURE_3D, i, internalFormat,
00778 w, h, d, 0,
00779 externalFormat, type,
00780 img->getData(i, frame, side));
00781 break;
00782 default:
00783 SFATAL << "TextureChunk::initialize1: unknown target "
00784 << imgtarget << "!!!" << std::endl;
00785 break;
00786 }
00787 }
00788 }
00789 defined = true;
00790 }
00791
00792 if(! defined)
00793 {
00794
00795 if(win->hasExtension(_sgisGenerateMipmap))
00796 {
00797 if(paramtarget != GL_NONE)
00798 glTexParameteri(paramtarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00799 glErr("TextureChunk::activate generate_mipmaps");
00800 needMipmaps = false;
00801 }
00802 else
00803 {
00804
00805 void * data = NULL;
00806
00807
00808 if(! osgispower2(width) ||
00809 ! osgispower2(height) ||
00810 ! osgispower2(depth)
00811 )
00812 {
00813
00814 if(imgtarget != GL_TEXTURE_2D)
00815 {
00816 SWARNING << "TextureChunk::initialize: can't mipmap "
00817 << "non-2D textures that are not 2^x !!!"
00818 << std::endl;
00819 }
00820 else
00821 {
00822 UInt32 outw = osgnextpower2(width);
00823 UInt32 outh = osgnextpower2(height);
00824
00825 data = malloc(outw * outh * img->getBpp());
00826
00827
00828 if(doScale)
00829 {
00830 GLint res = gluScaleImage(externalFormat,
00831 width, height, type, img->getData(0, frame, side),
00832 outw, outh, type, data);
00833
00834 if(res)
00835 {
00836 SWARNING << "TextureChunk::initialize: "
00837 << "gluScaleImage failed: "
00838 << gluErrorString(res) << "("
00839 << res << ")!"
00840 << std::endl;
00841 free(data);
00842 data = NULL;
00843 }
00844 else
00845 {
00846 width = outw;
00847 height = outh;
00848 }
00849 }
00850 else
00851 {
00852 memset(data, 0, outw * outh * img->getBpp());
00853
00854 UInt16 bpl = width * img->getBpp();
00855 UInt8 * src = (UInt8 *) img->getData(0, frame, side);
00856 UInt8 * dest= (UInt8 *) data;
00857
00858 for(UInt32 y = 0; y < height; y++)
00859 {
00860 memcpy(dest, src, bpl);
00861
00862 src += bpl;
00863 dest += outw * img->getBpp();
00864 }
00865 width = outw;
00866 height = outh;
00867 }
00868 }
00869 }
00870 else
00871 data = img->getData(0, frame, side);
00872
00873 if(data)
00874 {
00875 switch (imgtarget)
00876 {
00877 case GL_TEXTURE_1D:
00878 gluBuild1DMipmaps(imgtarget, internalFormat, width,
00879 externalFormat, type, data);
00880 break;
00881 case GL_TEXTURE_2D:
00882 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00883 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00884 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00885 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00886 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00887 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00888 gluBuild2DMipmaps(imgtarget, internalFormat,
00889 width, height,
00890 externalFormat, type, data);
00891 break;
00892 case GL_TEXTURE_3D:
00893 # ifdef GLU_VERSION_1_3
00894 gluBuild3DMipmaps(imgtarget, internalFormat,
00895 width, height, depth,
00896 externalFormat, type, data);
00897 # else
00898 FWARNING(("TextureChunk::initialize: 3d textures "
00899 "supported, but GLU version < 1.3, thus "
00900 "gluBuild3DMipmaps not supported!\n"));
00901 # endif
00902 break;
00903 default:
00904 SFATAL << "TextureChunk::initialize2: unknown target "
00905 << imgtarget << "!!!" << std::endl;
00906 }
00907
00908
00909 if(data != img->getData(0, frame, side))
00910 free(data);
00911 defined = true;
00912 }
00913 }
00914 }
00915 }
00916
00917
00918 if(! defined)
00919 {
00920
00921 if(needMipmaps && paramtarget != GL_NONE)
00922 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00923
00924 void * data = NULL;
00925 UInt32 datasize = 0;
00926
00927
00928 if(imgtarget != GL_TEXTURE_RECTANGLE_ARB &&
00929 (!osgispower2(width) || !osgispower2(height) || !osgispower2(depth))
00930 )
00931 {
00932
00933
00934
00935 if(doScale)
00936 {
00937
00938 if(imgtarget != GL_TEXTURE_2D &&
00939 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
00940 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
00941 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
00942 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
00943 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
00944 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
00945 )
00946 {
00947 SWARNING << "TextureChunk::initialize: can't scale "
00948 << "non-2D textures that are not 2^x !!!"
00949 << std::endl;
00950 }
00951 else
00952 {
00953 UInt32 outw = osgnextpower2(width);
00954 UInt32 outh = osgnextpower2(height);
00955
00956 data = malloc(outw * outh * img->getBpp());
00957 datasize = outw * outh * img->getBpp();
00958
00959 GLint res = gluScaleImage(externalFormat,
00960 width, height, type,
00961 img->getData(0, frame, side),
00962 outw, outh, type, data);
00963
00964 if(res)
00965 {
00966 SWARNING << "TextureChunk::initialize: "
00967 << "gluScaleImage failed: "
00968 << gluErrorString(res) << "("
00969 << res << ")!" << std::endl;
00970 free(data);
00971 data = NULL;
00972 }
00973 else
00974 {
00975 width = outw;
00976 height = outh;
00977 }
00978 }
00979 }
00980 else
00981 {
00982 if(compressedData)
00983 {
00984 switch (imgtarget)
00985 {
00986 case GL_TEXTURE_1D:
00987 CompressedTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
00988 osgnextpower2(width), 0, 0, NULL);
00989 CompressedTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
00990 externalFormat,
00991 img->getFrameSize(),
00992 img->getData(0, frame, side));
00993 break;
00994 case GL_TEXTURE_2D:
00995 CompressedTexImage2D(imgtarget, 0, internalFormat,
00996 osgnextpower2(width),
00997 osgnextpower2(height), 0,
00998 0, NULL);
00999 CompressedTexSubImage2D(imgtarget, 0, 0, 0, width, height,
01000 externalFormat,
01001 img->getFrameSize(),
01002 img->getData(0, frame, side));
01003 break;
01004 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01005 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01006 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01007 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01008 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01009 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01010 CompressedTexImage2D(imgtarget, 0, internalFormat,
01011 osgnextpower2(width),
01012 osgnextpower2(height), 0,
01013 0, NULL);
01014 CompressedTexSubImage2D(imgtarget, 0, 0, 0, width, height,
01015 externalFormat,
01016 (img->getSideCount() > 1) ? img->getSideSize() :
01017 img->getFrameSize(),
01018 img->getData(0, frame, side));
01019 break;
01020 case GL_TEXTURE_RECTANGLE_ARB:
01021 CompressedTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat,
01022 width, height, 0,
01023 img->getFrameSize(),
01024 img->getData(0, frame, side));
01025 break;
01026 case GL_TEXTURE_3D:
01027 CompressedTexImage3D(GL_TEXTURE_3D, 0, internalFormat,
01028 osgnextpower2(width),
01029 osgnextpower2(height),
01030 osgnextpower2(depth),
01031 0, 0, NULL);
01032 CompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
01033 width, height, depth,
01034 externalFormat,
01035 img->getFrameSize(),
01036 img->getData(0, frame, side));
01037 break;
01038 default:
01039 SFATAL << "TextureChunk::initialize4: unknown target "
01040 << imgtarget << "!!!" << std::endl;
01041 }
01042 }
01043 else
01044 {
01045 switch (imgtarget)
01046 {
01047 case GL_TEXTURE_1D:
01048 glTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01049 osgnextpower2(width), 0,
01050 externalFormat, type,
01051 NULL);
01052 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
01053 externalFormat, type,
01054 img->getData(0, frame, side));
01055 break;
01056 case GL_TEXTURE_2D:
01057 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01058 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01059 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01060 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01061 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: