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::_arbTextureNonPowerOfTwo;
00117 UInt32 TextureChunk::_extTextureFilterAnisotropic;
00118 UInt32 TextureChunk::_funcTexImage3D = Window::invalidFunctionID;
00119 UInt32 TextureChunk::_funcTexSubImage3D = Window::invalidFunctionID;
00120 UInt32 TextureChunk::_funcActiveTexture = Window::invalidFunctionID;
00121 UInt32 TextureChunk::_funcCompressedTexImage1D = Window::invalidFunctionID;
00122 UInt32 TextureChunk::_funcCompressedTexSubImage1D = Window::invalidFunctionID;
00123 UInt32 TextureChunk::_funcCompressedTexImage2D = Window::invalidFunctionID;
00124 UInt32 TextureChunk::_funcCompressedTexSubImage2D = Window::invalidFunctionID;
00125 UInt32 TextureChunk::_funcCompressedTexImage3D = Window::invalidFunctionID;
00126 UInt32 TextureChunk::_funcCompressedTexSubImage3D = Window::invalidFunctionID;
00127
00128
00129 #ifndef GL_VERSION_1_2
00130 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3DEXT"
00131 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3DEXT"
00132 #else
00133 # define GL_FUNC_TEXIMAGE3D OSG_DLSYM_UNDERSCORE"glTexImage3D"
00134 # define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3D"
00135 #endif
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 void TextureChunk::initMethod (void)
00150 {
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 TextureChunk::TextureChunk(void) :
00165 Inherited()
00166 {
00167 _extTex3D =
00168 Window::registerExtension("GL_EXT_texture3D" );
00169 _arbMultiTex =
00170 Window::registerExtension("GL_ARB_multitexture" );
00171 _arbCubeTex =
00172 Window::registerExtension("GL_ARB_texture_cube_map" );
00173 _nvPointSprite =
00174 Window::registerExtension("GL_NV_point_sprite" );
00175 _nvTextureShader =
00176 Window::registerExtension("GL_NV_texture_shader" );
00177 _nvTextureShader2 =
00178 Window::registerExtension("GL_NV_texture_shader2" );
00179 _nvTextureShader3 =
00180 Window::registerExtension("GL_NV_texture_shader3" );
00181 _sgisGenerateMipmap =
00182 Window::registerExtension("GL_SGIS_generate_mipmap" );
00183 _extTextureLodBias =
00184 Window::registerExtension("GL_EXT_texture_lod_bias" );
00185 _arbTextureCompression =
00186 Window::registerExtension("GL_ARB_texture_compression" );
00187 _arbTextureRectangle =
00188 Window::registerExtension("GL_ARB_texture_rectangle" );
00189 _arbTextureNonPowerOfTwo =
00190 Window::registerExtension("GL_ARB_texture_non_power_of_two" );
00191 _extTextureFilterAnisotropic =
00192 Window::registerExtension("GL_EXT_texture_filter_anisotropic" );
00193
00194 _funcTexImage3D =
00195 Window::registerFunction (GL_FUNC_TEXIMAGE3D ,
00196 _extTex3D, 0x0102);
00197 _funcTexSubImage3D =
00198 Window::registerFunction (GL_FUNC_TEXSUBIMAGE3D ,
00199 _extTex3D, 0x0102);
00200 _funcActiveTexture =
00201 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glActiveTextureARB" ,
00202 _arbMultiTex);
00203 _funcCompressedTexImage1D =
00204 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00205 "glCompressedTexImage1DARB" ,
00206 _arbTextureCompression);
00207 _funcCompressedTexSubImage1D =
00208 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00209 "glCompressedTexSubImage1DARB" ,
00210 _arbTextureCompression);
00211 _funcCompressedTexImage2D =
00212 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00213 "glCompressedTexImage2DARB" ,
00214 _arbTextureCompression);
00215 _funcCompressedTexSubImage2D =
00216 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00217 "glCompressedTexSubImage2DARB" ,
00218 _arbTextureCompression);
00219 _funcCompressedTexImage3D =
00220 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00221 "glCompressedTexImage3DARB" ,
00222 _arbTextureCompression);
00223 _funcCompressedTexSubImage3D =
00224 Window::registerFunction(OSG_DLSYM_UNDERSCORE
00225 "glCompressedTexSubImage3DARB" ,
00226 _arbTextureCompression);
00227
00228 Window::registerConstant(GL_MAX_TEXTURE_UNITS_ARB);
00229 Window::registerConstant(GL_MAX_TEXTURE_IMAGE_UNITS_ARB);
00230 Window::registerConstant(GL_MAX_TEXTURE_COORDS_ARB);
00231 }
00232
00233 TextureChunk::TextureChunk(const TextureChunk &source) :
00234 Inherited(source)
00235 {
00236 }
00237
00238 TextureChunk::~TextureChunk(void)
00239 {
00240 }
00241
00242
00243
00244 const StateChunkClass *TextureChunk::getClass(void) const
00245 {
00246 return &_class;
00247 }
00248
00249
00250
00256 void TextureChunk::changed(BitVector whichField, UInt32 origin)
00257 {
00258 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00259 {
00260 if(getGLId() == 0)
00261 {
00262 TextureChunkPtr tmpPtr(*this);
00263
00264 beginEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00265
00266 setGLId(
00267 Window::registerGLObject(
00268 osgTypedMethodVoidFunctor2ObjCPtrPtr<TextureChunkPtr,
00269 Window ,
00270 UInt32>(
00271 tmpPtr,
00272 &TextureChunk::handleGL),
00273 1));
00274
00275 endEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00276 }
00277 }
00278
00279
00280 if((whichField & ~(MinFilterFieldMask | MagFilterFieldMask)) == 0)
00281 {
00282 if((getMinFilter() != GL_NEAREST) &&
00283 (getMinFilter() != GL_LINEAR))
00284 {
00285 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00286 {
00287 Window::reinitializeGLObject(getGLId());
00288 }
00289 }
00290 else
00291 {
00292 imageContentChanged();
00293 }
00294 }
00295 else if((whichField & ~(PriorityFieldMask | FrameFieldMask)) == 0)
00296 {
00297 imageContentChanged();
00298 }
00299 else if ((whichField & ~(DirtyMinXFieldMask | DirtyMaxXFieldMask |
00300 DirtyMinYFieldMask | DirtyMaxYFieldMask |
00301 DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
00302 {
00303 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00304 {
00305 Window::refreshGLObject(getGLId());
00306 }
00307 }
00308 else
00309 {
00310 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00311 {
00312 Window::reinitializeGLObject(getGLId());
00313 }
00314 }
00315
00316 if(whichField & ImageFieldMask)
00317 {
00318 if(origin & ChangedOrigin::Abstract)
00319 {
00320 if(origin & ChangedOrigin::AbstrIncRefCount)
00321 {
00322 addRefCP(_sfImage.getValue());
00323 }
00324 else
00325 {
00326 ImagePtr pImage = _sfImage.getValue();
00327
00328 _sfImage.setValue(NullFC);
00329
00330 setImage(pImage);
00331 }
00332 }
00333 }
00334
00335 Inherited::changed(whichField, origin);
00336 }
00337
00338 bool TextureChunk::isTransparent(void) const
00339 {
00340
00341
00342 return false;
00343 }
00344
00345
00346
00347
00348 void TextureChunk::onCreate(const TextureChunk *)
00349 {
00350 if(GlobalSystemState == Startup)
00351 return;
00352
00353
00354
00355
00356 TextureChunkPtr tmpPtr(*this);
00357
00358 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00359 {
00360 beginEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00361
00362 setGLId(
00363 Window::registerGLObject(
00364 osgTypedMethodVoidFunctor2ObjCPtrPtr<TextureChunkPtr,
00365 Window ,
00366 UInt32>(
00367 tmpPtr,
00368 &TextureChunk::handleGL),
00369 1));
00370
00371 endEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00372 }
00373 }
00374
00375 void TextureChunk::onDestroy(void)
00376 {
00377 Inherited::onDestroy();
00378
00379 if(_sfImage.getValue() != NullFC)
00380 subRefCP(_sfImage.getValue());
00381 if(getGLId() > 0)
00382 Window::destroyGLObject(getGLId(), 1);
00383 }
00384
00385
00386
00387 void TextureChunk::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00388 const BitVector OSG_CHECK_ARG(bvFlags )) const
00389 {
00390 SLOG << "Dump TextureChunk NI" << std::endl;
00391 }
00392
00393
00394
00395
00400 void TextureChunk::handleTextureShader(Window *win, GLenum bindtarget)
00401 {
00402 if(!win->hasExtension(_nvTextureShader))
00403 {
00404 if(getShaderOperation() != GL_NONE)
00405 FINFO(("NV Texture Shaders not supported on Window %p!\n", win));
00406 return;
00407 }
00408
00409 glErr("textureShader precheck");
00410
00411 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
00412 getShaderOperation());
00413
00414 glErr("textureShader setup: operation");
00415
00416 if(getShaderOperation() == GL_NONE)
00417 return;
00418
00419 if(bindtarget == GL_TEXTURE_3D && !win->hasExtension(_nvTextureShader2))
00420 {
00421 FINFO(("NV Texture Shaders 2 not supported on Window %p!\n", win));
00422 return;
00423 }
00424
00425 if(getShaderInput() != GL_NONE)
00426 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,
00427 getShaderInput());
00428
00429 glErr("textureShader setup: input");
00430
00431 if(getShaderRGBADotProduct() != GL_NONE)
00432 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV,
00433 getShaderRGBADotProduct());
00434
00435 glErr("textureShader setup: rgba dotprod");
00436
00437 if(getShaderOffsetMatrix().size() == 4)
00438 {
00439 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,
00440 (GLfloat*)&(getShaderOffsetMatrix()[0]));
00441
00442 glErr("textureShader setup: offset matrix");
00443 }
00444 else if(getShaderOffsetMatrix().size() != 0)
00445 {
00446 FWARNING(("TextureChunk::handleTextureShader: shaderOffsetMatrix has"
00447 " to have 4 entries, not %d!\n",
00448 getShaderOffsetMatrix().size() ));
00449 }
00450
00451 glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV,
00452 getShaderOffsetScale());
00453
00454 glErr("textureShader setup: offset scale");
00455
00456 glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV,
00457 getShaderOffsetBias());
00458
00459 glErr("textureShader setup: offset bias");
00460
00461 GLint cullmodes[4];
00462 if(getShaderCullModes() & 0x1)
00463 {
00464 cullmodes[0] = GL_GEQUAL;
00465 }
00466 else
00467 {
00468 cullmodes[0] = GL_LESS;
00469 }
00470
00471 if(getShaderCullModes() & 0x2)
00472 {
00473 cullmodes[1] = GL_GEQUAL;
00474 }
00475 else
00476 {
00477 cullmodes[1] = GL_LESS;
00478 }
00479
00480 if(getShaderCullModes() & 0x4)
00481 {
00482 cullmodes[2] = GL_GEQUAL;
00483 }
00484 else
00485 {
00486 cullmodes[2] = GL_LESS;
00487 }
00488
00489 if(getShaderCullModes() & 0x8)
00490 {
00491 cullmodes[3] = GL_GEQUAL;
00492 }
00493 else
00494 {
00495 cullmodes[3] = GL_LESS;
00496 }
00497
00498 glTexEnviv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV,
00499 cullmodes);
00500
00501 glErr("textureShader setup: cull modes");
00502
00503 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV,
00504 getShaderConstEye().getValues());
00505
00506 glErr("textureShader setup: const eye");
00507
00508
00509
00510 #ifdef OSG_DEBUG
00511 GLint consistent;
00512 glGetTexEnviv(GL_TEXTURE_SHADER_NV, GL_SHADER_CONSISTENT_NV,
00513 &consistent);
00514 if(!consistent)
00515 {
00516 FWARNING(("Texture shaders not consistent!\n"));
00517 }
00518 #endif
00519 }
00520
00521 void TextureChunk::handleTexture(Window *win, UInt32 id,
00522 GLenum bindtarget,
00523 GLenum paramtarget,
00524 GLenum imgtarget,
00525 Window::GLObjectStatusE mode, ImagePtr img, int side)
00526 {
00527 if( img==NullFC || ! img->getDimension())
00528 return;
00529
00530 if(mode == Window::initialize || mode == Window::reinitialize)
00531 {
00532 if(bindtarget == GL_TEXTURE_3D &&
00533 !win->hasExtension(_extTex3D) &&
00534 win->getGLVersion() < 0x0102
00535 )
00536 {
00537 FNOTICE(("3D textures not supported on Window %p!\n", win));
00538 return;
00539 }
00540
00541 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB &&
00542 !win->hasExtension(_arbTextureRectangle))
00543 {
00544 FNOTICE(("Rectangular textures not supported on Window %p!\n", win));
00545 return;
00546 }
00547
00548 if(paramtarget == GL_TEXTURE_CUBE_MAP_ARB &&
00549 !win->hasExtension(_arbCubeTex))
00550 {
00551 FNOTICE(("Cube textures not supported on Window %p!\n", win));
00552 return;
00553 }
00554
00555 if(img->hasCompressedData() &&
00556 !win->hasExtension(_arbTextureCompression))
00557 {
00558 FNOTICE(("Compressed textures not supported on Window %p!\n", win));
00559 return;
00560 }
00561
00562 if(mode == Window::reinitialize)
00563 {
00564 GLuint tex = id;
00565 glDeleteTextures(1, &tex);
00566 }
00567
00568
00569 void (OSG_APIENTRY*TexImage3D)(GLenum target, GLint level, GLenum internalformat,
00570 GLsizei width, GLsizei height, GLsizei depth,
00571 GLint border, GLenum format, GLenum type,
00572 const GLvoid *pixels) =
00573 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLenum internalformat,
00574 GLsizei width, GLsizei height, GLsizei depth,
00575 GLint border, GLenum format, GLenum type,
00576 const GLvoid *pixels))
00577 win->getFunction(_funcTexImage3D);
00578
00579 void (OSG_APIENTRY*TexSubImage3D)
00580 (GLenum target, GLint level, GLint xoffset,
00581 GLint yoffset, GLint zoffset, GLsizei width,
00582 GLsizei height, GLsizei depth, GLenum format,
00583 GLenum type, const GLvoid *pixels) =
00584 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset,
00585 GLint yoffset, GLint zoffset, GLsizei width,
00586 GLsizei height, GLsizei depth, GLenum format,
00587 GLenum type, const GLvoid *pixels))
00588 win->getFunction(_funcTexSubImage3D);
00589
00590
00591 void (OSG_APIENTRY*CompressedTexImage1D)(GLenum target, GLint level,
00592 GLenum internalformat, GLsizei width, GLint border,
00593 GLsizei imageSize, const GLvoid *pixels) =
00594 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00595 GLenum internalformat, GLsizei width, GLint border,
00596 GLsizei imageSize, const GLvoid *pixels))
00597 win->getFunction(_funcCompressedTexImage1D);
00598
00599 void (OSG_APIENTRY*CompressedTexSubImage1D)
00600 (GLenum target, GLint level, GLint xoffset, GLsizei width,
00601 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
00602 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset, GLsizei width,
00603 GLenum format, GLsizei imageSize, const GLvoid *pixels))
00604 win->getFunction(_funcCompressedTexSubImage1D);
00605
00606 void (OSG_APIENTRY*CompressedTexImage2D)(GLenum target, GLint level,
00607 GLenum internalformat, GLsizei width, GLsizei height,
00608 GLint border,
00609 GLsizei imageSize, const GLvoid *pixels) =
00610 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00611 GLenum internalformat, GLsizei width, GLsizei height,
00612 GLint border,
00613 GLsizei imageSize, const GLvoid *pixels))
00614 win->getFunction(_funcCompressedTexImage2D);
00615
00616 void (OSG_APIENTRY*CompressedTexSubImage2D)
00617 (GLenum target, GLint level,
00618 GLint xoffset, GLint yoffset,
00619 GLsizei width, GLsizei height, GLenum format,
00620 GLsizei imageSize, const GLvoid *pixels) =
00621 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00622 GLint xoffset, GLint yoffset,
00623 GLsizei width, GLsizei height, GLenum format,
00624 GLsizei imageSize, const GLvoid *pixels))
00625 win->getFunction(_funcCompressedTexSubImage2D);
00626
00627 void (OSG_APIENTRY*CompressedTexImage3D)(GLenum target, GLint level,
00628 GLenum internalformat,
00629 GLsizei width, GLsizei height, GLsizei depth,
00630 GLint border,
00631 GLsizei imageSize, const GLvoid *pixels) =
00632 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00633 GLenum internalformat,
00634 GLsizei width, GLsizei height, GLsizei depth,
00635 GLint border,
00636 GLsizei imageSize, const GLvoid *pixels))
00637 win->getFunction(_funcCompressedTexImage3D);
00638
00639 void (OSG_APIENTRY*CompressedTexSubImage3D)
00640 (GLenum target, GLint level,
00641 GLint xoffset, GLint yoffset, GLint zoffset,
00642 GLsizei width, GLsizei height, GLsizei depth,
00643 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
00644 (void (OSG_APIENTRY*)(GLenum target, GLint level,
00645 GLint xoffset, GLint yoffset, GLint zoffset,
00646 GLsizei width, GLsizei height, GLsizei depth,
00647 GLenum format, GLsizei imageSize, const GLvoid *pixels))
00648 win->getFunction(_funcCompressedTexSubImage3D);
00649
00650
00651
00652 if(! img || ! img->getDimension())
00653 return;
00654
00655 glErr("TextureChunk::initialize precheck");
00656
00657 FDEBUG(("texture (re-)initialize\n"));
00658
00659 glBindTexture(bindtarget, id);
00660
00661 if(paramtarget != GL_NONE)
00662 {
00663
00664 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY, getPriority());
00665 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, getMinFilter());
00666 glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER, getMagFilter());
00667 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_S, getWrapS());
00668 if(paramtarget == GL_TEXTURE_2D ||
00669 paramtarget == GL_TEXTURE_3D ||
00670 paramtarget == GL_TEXTURE_CUBE_MAP_ARB ||
00671 paramtarget == GL_TEXTURE_RECTANGLE_ARB
00672 )
00673 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_T, getWrapT());
00674 if(paramtarget == GL_TEXTURE_3D ||
00675 paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00676 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_R, getWrapR());
00677
00678 if(getAnisotropy() > 1.0f && win->hasExtension(_extTextureFilterAnisotropic))
00679 glTexParameterf(paramtarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, getAnisotropy());
00680
00681 glTexParameterfv(paramtarget, GL_TEXTURE_BORDER_COLOR,
00682 (GLfloat*)getBorderColor().getValuesRGBA());
00683
00684 glErr("TextureChunk::initialize params");
00685 }
00686
00687
00688 GLenum internalFormat = getInternalFormat();
00689 GLenum externalFormat = img->getPixelFormat();
00690 GLenum type = img->getDataType();
00691 UInt32 width = img->getWidth();
00692 UInt32 height = img->getHeight();
00693 UInt32 depth = img->getDepth();
00694 bool compressedData = img->hasCompressedData();
00695
00696 bool doScale = getScale();
00697 UInt32 frame = getFrame();
00698
00699 bool defined = false;
00700 bool needMipmaps = getMinFilter() == GL_NEAREST_MIPMAP_NEAREST ||
00701 getMinFilter() == GL_LINEAR_MIPMAP_NEAREST ||
00702 getMinFilter() == GL_NEAREST_MIPMAP_LINEAR ||
00703 getMinFilter() == GL_LINEAR_MIPMAP_LINEAR ;
00704
00705 if(internalFormat == GL_NONE)
00706 {
00707 switch(externalFormat)
00708 {
00709 #if defined(GL_BGR) && defined(GL_BGR_EXT)
00710 case GL_BGR:
00711 #else
00712 # if defined(GL_BGR)
00713 case GL_BGR:
00714 # endif
00715 # if defined(GL_BGR_EXT)
00716 case GL_BGR_EXT:
00717 # endif
00718 #endif
00719 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00720 internalFormat = GL_RGB;
00721 break;
00722 #endif
00723 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
00724 case GL_BGRA:
00725 #else
00726 # if defined(GL_BGRA)
00727 case GL_BGRA:
00728 # endif
00729 # if defined(GL_BGRA_EXT)
00730 case GL_BGRA_EXT:
00731 # endif
00732 #endif
00733 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00734 internalFormat = GL_RGBA;
00735 break;
00736 #endif
00737 case GL_INTENSITY:
00738 internalFormat = GL_INTENSITY;
00739 externalFormat = GL_LUMINANCE;
00740 break;
00741
00742 default: internalFormat = externalFormat;
00743 break;
00744 }
00745 }
00746
00747 if(getExternalFormat() != GL_NONE)
00748 externalFormat = getExternalFormat();
00749
00750 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && needMipmaps)
00751 {
00752 SWARNING << "TextureChunk::initialize: Can't do mipmaps"
00753 << "with GL_TEXTURE_RECTANGLE_ARB target! Ignored"
00754 << std::endl;
00755 needMipmaps= false;
00756 }
00757
00758
00759 if(needMipmaps)
00760 {
00761
00762 if(img->getMipMapCount() == img->calcMipmapLevelCount() &&
00763 osgispower2(width) && osgispower2(height) &&
00764 osgispower2(depth)
00765 )
00766 {
00767 for(UInt16 i = 0; i < img->getMipMapCount(); i++)
00768 {
00769 UInt32 w, h, d;
00770 img->calcMipmapGeometry(i, w, h, d);
00771
00772 if(compressedData)
00773 {
00774 switch (imgtarget)
00775 {
00776 case GL_TEXTURE_1D:
00777 CompressedTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00778 w, getBorderWidth(),
00779 img->calcMipmapLevelSize(i),
00780 img->getData(i, frame, side));
00781 break;
00782 case GL_TEXTURE_2D:
00783 CompressedTexImage2D(imgtarget, i, internalFormat,
00784 w, h, getBorderWidth(),
00785 img->calcMipmapLevelSize(i),
00786 img->getData(i, frame, side));
00787 break;
00788 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00789 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00790 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00791 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00792 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00793 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00794 CompressedTexImage2D(imgtarget, i, internalFormat,
00795 w, h, getBorderWidth(),
00796 img->calcMipmapLevelSize(i),
00797 img->getData(i, frame, side));
00798 break;
00799 case GL_TEXTURE_3D:
00800 CompressedTexImage3D(GL_TEXTURE_3D, i, internalFormat,
00801 w, h, d, getBorderWidth(),
00802 img->calcMipmapLevelSize(i),
00803 img->getData(i, frame, side));
00804 break;
00805 default:
00806 SFATAL << "TextureChunk::initialize1: unknown target "
00807 << imgtarget << "!!!" << std::endl;
00808 break;
00809 }
00810 }
00811 else
00812 {
00813 switch (imgtarget)
00814 {
00815 case GL_TEXTURE_1D:
00816 glTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00817 w, getBorderWidth(),
00818 externalFormat, type,
00819 img->getData(i, frame, side));
00820 break;
00821 case GL_TEXTURE_2D:
00822 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00823 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00824 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00825 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00826 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00827 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00828 glTexImage2D(imgtarget, i, internalFormat,
00829 w, h, getBorderWidth(),
00830 externalFormat, type,
00831 img->getData(i, frame, side));
00832 break;
00833 case GL_TEXTURE_3D:
00834 TexImage3D(GL_TEXTURE_3D, i, internalFormat,
00835 w, h, d, getBorderWidth(),
00836 externalFormat, type,
00837 img->getData(i, frame, side));
00838 break;
00839 default:
00840 SFATAL << "TextureChunk::initialize1: unknown target "
00841 << imgtarget << "!!!" << std::endl;
00842 break;
00843 }
00844 }
00845 }
00846 defined = true;
00847 }
00848
00849 if(! defined)
00850 {
00851
00852 if(win->hasExtension(_sgisGenerateMipmap))
00853 {
00854 if(paramtarget != GL_NONE)
00855 glTexParameteri(paramtarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00856
00857 glErr("TextureChunk::activate generate_mipmaps");
00858 needMipmaps = false;
00859 }
00860 else
00861 {
00862
00863 void * data = NULL;
00864
00865
00866 if(! osgispower2(width) ||
00867 ! osgispower2(height) ||
00868 ! osgispower2(depth)
00869 )
00870 {
00871
00872 if(imgtarget != GL_TEXTURE_2D)
00873 {
00874 SWARNING << "TextureChunk::initialize: can't mipmap "
00875 << "non-2D textures that are not 2^x !!!"
00876 << std::endl;
00877 }
00878 else
00879 {
00880 UInt32 outw = osgnextpower2(width);
00881 UInt32 outh = osgnextpower2(height);
00882
00883 data = malloc(outw * outh * img->getBpp());
00884
00885
00886 if(doScale)
00887 {
00888 GLint res = gluScaleImage(externalFormat,
00889 width, height, type, img->getData(0, frame, side),
00890 outw, outh, type, data);
00891
00892 if(res)
00893 {
00894 SWARNING << "TextureChunk::initialize: "
00895 << "gluScaleImage failed: "
00896 << gluErrorString(res) << "("
00897 << res << ")!"
00898 << std::endl;
00899 free(data);
00900 data = NULL;
00901 }
00902 else
00903 {
00904 width = outw;
00905 height = outh;
00906 }
00907 }
00908 else
00909 {
00910 memset(data, 0, outw * outh * img->getBpp());
00911
00912 UInt16 bpl = width * img->getBpp();
00913 UInt8 * src = (UInt8 *) img->getData(0, frame, side);
00914 UInt8 * dest= (UInt8 *) data;
00915
00916 for(UInt32 y = 0; y < height; y++)
00917 {
00918 memcpy(dest, src, bpl);
00919
00920 src += bpl;
00921 dest += outw * img->getBpp();
00922 }
00923 width = outw;
00924 height = outh;
00925 }
00926 }
00927 }
00928 else
00929 data = img->getData(0, frame, side);
00930
00931 if(data)
00932 {
00933 switch (imgtarget)
00934 {
00935 case GL_TEXTURE_1D:
00936 gluBuild1DMipmaps(imgtarget, internalFormat, width,
00937 externalFormat, type, data);
00938 break;
00939 case GL_TEXTURE_2D:
00940 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00941 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00942 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00943 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00944 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00945 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00946 gluBuild2DMipmaps(imgtarget, internalFormat,
00947 width, height,
00948 externalFormat, type, data);
00949 break;
00950 case GL_TEXTURE_3D:
00951 # ifdef GLU_VERSION_1_3
00952 gluBuild3DMipmaps(imgtarget, internalFormat,
00953 width, height, depth,
00954 externalFormat, type, data);
00955 # else
00956 FWARNING(("TextureChunk::initialize: 3d textures "
00957 "supported, but GLU version < 1.3, thus "
00958 "gluBuild3DMipmaps not supported!\n"));
00959 # endif
00960 break;
00961 default:
00962 SFATAL << "TextureChunk::initialize2: unknown target "
00963 << imgtarget << "!!!" << std::endl;
00964 }
00965
00966
00967 if(data != img->getData(0, frame, side))
00968 free(data);
00969 defined = true;
00970 }
00971 }
00972 }
00973 }
00974
00975
00976 if(! defined)
00977 {
00978
00979 if(needMipmaps && paramtarget != GL_NONE)
00980 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00981
00982 void * data = NULL;
00983 UInt32 datasize = 0;
00984
00985
00986 if(imgtarget != GL_TEXTURE_RECTANGLE_ARB &&
00987 !win->hasExtension(_arbTextureNonPowerOfTwo) &&
00988 (!osgispower2(width) || !osgispower2(height) || !osgispower2(depth))
00989 )
00990 {
00991
00992
00993
00994 if(doScale)
00995 {
00996
00997 if(imgtarget != GL_TEXTURE_2D &&
00998 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
00999 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
01000 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
01001 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
01002 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
01003 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
01004 )
01005 {
01006 SWARNING << "TextureChunk::initialize: can't scale "
01007 << "non-2D textures that are not 2^x !!!"
01008 << std::endl;
01009 }
01010 else
01011 {
01012 UInt32 outw = osgnextpower2(width);
01013 UInt32 outh = osgnextpower2(height);
01014
01015 data = malloc(outw * outh * img->getBpp());
01016 datasize = outw * outh * img->getBpp();
01017
01018 GLint res = gluScaleImage(externalFormat,
01019 width, height, type,
01020 img->getData(0, frame, side),
01021 outw, outh, type, data);
01022
01023 if(res)
01024 {
01025 SWARNING << "TextureChunk::initialize: "
01026 << "gluScaleImage failed: "
01027 << gluErrorString(res) << "("
01028 << res << ")!" << std::endl;
01029 free(data);
01030 data = NULL;
01031 }
01032 else
01033 {
01034 width = outw;
01035 height = outh;
01036 }
01037 }
01038
01039 }
01040 else
01041 {
01042 if(compressedData)
01043 {
01044 switch (imgtarget)
01045 {
01046 case GL_TEXTURE_1D:
01047 CompressedTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01048 osgnextpower2(width), getBorderWidth(), 0, NULL);
01049 CompressedTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
01050 externalFormat,
01051 img->getFrameSize(),
01052 img->getData(0, frame, side));
01053 break;
01054 case GL_TEXTURE_2D:
01055 CompressedTexImage2D(imgtarget, 0, internalFormat,
01056 osgnextpower2(width),
01057 osgnextpower2(height), getBorderWidth(),
01058 0, NULL);
01059 CompressedTexSubImage2D(imgtarget, 0, 0, 0, width, height,
01060 externalFormat,
01061 img->getFrameSize(),
01062 img->getData(0, frame, side));
01063 break;
01064 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01065 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01066 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01067 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01068 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01069 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01070 CompressedTexImage2D(imgtarget, 0, internalFormat,
01071 osgnextpower2(width),
01072 osgnextpower2(height), getBorderWidth(),
01073 0, NULL);
01074 CompressedTexSubImage2D(imgtarget, 0, 0, 0, width, height,
01075 externalFormat,
01076 (img->getSideCount() > 1) ? img->getSideSize() :
01077 img->getFrameSize(),
01078 img->getData(0, frame, side));
01079 break;
01080 case GL_TEXTURE_RECTANGLE_ARB:
01081 CompressedTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat,
01082 width, height, getBorderWidth(),
01083 img->getFrameSize(),
01084 img->getData(0, frame, side));
01085 break;
01086 case GL_TEXTURE_3D:
01087 CompressedTexImage3D(GL_TEXTURE_3D, 0, internalFormat,
01088 osgnextpower2(width),
01089 osgnextpower2(height),
01090 osgnextpower2(depth),
01091 getBorderWidth(), 0, NULL);
01092 CompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
01093 width, height, depth,
01094 externalFormat,
01095 img->getFrameSize(),
01096 img->getData(0, frame, side));
01097 break;
01098 default:
01099 SFATAL << "TextureChunk::initialize4: unknown target "
01100 << imgtarget << "!!!" << std::endl;
01101 }
01102 }
01103 else
01104 {
01105 switch (imgtarget)
01106 {
01107 case GL_TEXTURE_1D:
01108 glTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01109 osgnextpower2(width), getBorderWidth(),
01110 externalFormat, type,
01111 NULL);
01112 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
01113 externalFormat, type,
01114 img->getData(0, frame, side));
01115 break;
01116 case GL_TEXTURE_2D:
01117 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01118 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01119 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01120 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01121 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01122 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01123 glTexImage2D(imgtarget, 0, internalFormat,
01124 osgnextpower2(width),
01125 osgnextpower2(height), getBorderWidth(),
01126 externalFormat, type,
01127 NULL);
01128 glTexSubImage2D(imgtarget, 0, 0, 0, width, height,
01129 externalFormat, type,
01130 img->getData(0, frame, side));
01131 break;
01132 case GL_TEXTURE_RECTANGLE_ARB:
01133 glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat,
01134 width, height, getBorderWidth(),
01135 externalFormat, type,
01136 img->getData(0, frame, side));
01137 break;
01138 case GL_TEXTURE_3D:
01139 TexImage3D(GL_TEXTURE_3D, 0, internalFormat,
01140 osgnextpower2(width),
01141 osgnextpower2(height),
01142 osgnextpower2(depth),
01143 getBorderWidth(), externalFormat, type, NULL);
01144 TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
01145 width, height, depth,
01146 externalFormat, type,
01147 img->getData(0, frame, side));
01148 break;
01149 default:
01150 SFATAL << "TextureChunk::initialize4: unknown target "
01151 << imgtarget << "!!!" << std::endl;
01152 }
01153 }
01154
01155 defined = true;
01156 }
01157 }
01158 else
01159 {
01160 data = img->getData(0, frame, side);
01161 datasize = (img->getSideCount() > 1) ? img->getSideSize() :
01162 img->getFrameSize();
01163 }
01164
01165 if(!defined)
01166 {
01167
01168
01169
01170 if(compressedData)
01171 {
01172 switch (imgtarget)
01173 {
01174 case GL_TEXTURE_1D:
01175 CompressedTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01176 width, getBorderWidth(),
01177 datasize, data);
01178 break;
01179 case GL_TEXTURE_2D:
01180 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01181 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01182 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01183 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01184 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01185 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01186 CompressedTexImage2D(imgtarget, 0, internalFormat,
01187 width, height, getBorderWidth(),
01188 datasize, data);
01189 break;
01190 case GL_TEXTURE_RECTANGLE_ARB:
01191 CompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat,
01192 width, height, getBorderWidth(),
01193 datasize, data);
01194 break;
01195 case GL_TEXTURE_3D:
01196 CompressedTexImage3D(GL_TEXTURE_3D, 0, internalFormat,
01197 width, height, depth, getBorderWidth(),
01198 datasize, data);
01199 break;
01200 default:
01201 SFATAL << "TextureChunk::initialize3: unknown target "
01202 << imgtarget << "!!!" << std::endl;
01203 }
01204 }
01205 else
01206 {
01207 switch (imgtarget)
01208 {
01209 case GL_TEXTURE_1D:
01210 glTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
01211 width, getBorderWidth(),
01212 externalFormat, type,
01213 data);
01214 break;
01215 case GL_TEXTURE_2D:
01216 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01217 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01218 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01219 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01220 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01221 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01222 glTexImage2D(imgtarget, 0, internalFormat,
01223 width, height, getBorderWidth(),
01224 externalFormat, type,
01225 data);
01226 break;
01227 case GL_TEXTURE_RECTANGLE_ARB:
01228 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat,
01229 width, height, getBorderWidth(),
01230 externalFormat, type,
01231 data);
01232 break;
01233 case GL_TEXTURE_3D:
01234 TexImage3D(GL_TEXTURE_3D, 0, internalFormat,
01235 width, height, depth, getBorderWidth(),
01236 externalFormat, type,
01237 data);
01238 break;
01239 default:
01240 SFATAL << "TextureChunk::initialize3: unknown target "
01241 << imgtarget << "!!!" << std::endl;
01242 }
01243 }
01244
01245 }
01246
01247 if(data != img->getData(0, frame, side))
01248 free(data);
01249 }
01250
01251 glErr("TextureChunk::initialize image");
01252 }
01253 else if(mode == Window::needrefresh)
01254 {
01255 void (OSG_APIENTRY*TexSubImage3D)
01256 (GLenum target, GLint level, GLint xoffset,
01257 GLint yoffset, GLint zoffset, GLsizei width,
01258 GLsizei height, GLsizei depth, GLenum format,
01259 GLenum type, const GLvoid *pixels) =
01260 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset,
01261 GLint yoffset, GLint zoffset, GLsizei width,
01262 GLsizei height, GLsizei depth, GLenum format,
01263 GLenum type, const GLvoid *pixels))
01264 win->getFunction(_funcTexSubImage3D);
01265
01266 void (OSG_APIENTRY*CompressedTexSubImage1D)
01267 (GLenum target, GLint level, GLint xoffset, GLsizei width,
01268 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
01269 (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset, GLsizei width,
01270 GLenum format, GLsizei imageSize, const GLvoid *pixels))
01271 win->getFunction(_funcCompressedTexSubImage1D);
01272
01273 void (OSG_APIENTRY*CompressedTexSubImage2D)
01274 (GLenum target, GLint level,
01275 GLint xoffset, GLint yoffset,
01276 GLsizei width, GLsizei height, GLenum format,
01277 GLsizei imageSize, const GLvoid *pixels) =
01278 (void (OSG_APIENTRY*)(GLenum target, GLint level,
01279 GLint xoffset, GLint yoffset,
01280 GLsizei width, GLsizei height, GLenum format,
01281 GLsizei imageSize, const GLvoid *pixels))
01282 win->getFunction(_funcCompressedTexSubImage2D);
01283
01284 void (OSG_APIENTRY*CompressedTexSubImage3D)
01285 (GLenum target, GLint level,
01286 GLint xoffset, GLint yoffset, GLint zoffset,
01287 GLsizei width, GLsizei height, GLsizei depth,
01288 GLenum format, GLsizei imageSize, const GLvoid *pixels) =
01289 (void (OSG_APIENTRY*)(GLenum target, GLint level,
01290 GLint xoffset, GLint yoffset, GLint zoffset,
01291 GLsizei width, GLsizei height, GLsizei depth,
01292 GLenum format, GLsizei imageSize, const GLvoid *pixels))
01293 win->getFunction(_funcCompressedTexSubImage3D);
01294
01295 GLenum externalFormat = img->getPixelFormat();
01296 GLenum type = img->getDataType();
01297 bool compressedData = img->hasCompressedData();
01298 bool has3DTex = win->hasExtension(_extTex3D) ||
01299 win->getGLVersion() >= 0x0102;
01300
01301 if(bindtarget == GL_TEXTURE_3D && !has3DTex)
01302 {
01303 FINFO(("3D textures not supported on Window %p!\n", win));
01304 return;
01305 }
01306
01307 if(! img)
01308 return;
01309
01310 if(getExternalFormat() != GL_NONE)
01311 externalFormat = getExternalFormat();
01312
01313 if(!getScale() || imgtarget == GL_TEXTURE_RECTANGLE_ARB
01314 || win->hasExtension(_arbTextureNonPowerOfTwo)
01315 || (osgispower2(img->getWidth() ) &&
01316 osgispower2(img->getHeight()) &&
01317 osgispower2(img->getDepth() )
01318 ) )
01319 {
01320
01321 glBindTexture(bindtarget, id);
01322
01323
01324 UInt32 ix, ax, iy, ay, iz, az;
01325 ix = (getDirtyMinX()!=-1) ? getDirtyMinX() : 0;
01326 ax = (getDirtyMaxX()!=-1) ? getDirtyMaxX() : img->getWidth() - 1;
01327 iy = (getDirtyMinY()!=-1) ? getDirtyMinY() : 0;
01328 ay = (getDirtyMaxY()!=-1) ? getDirtyMaxY() : img->getHeight() - 1;
01329 iz = (getDirtyMinZ()!=-1) ? getDirtyMinZ() : 0;
01330 az = (getDirtyMaxZ()!=-1) ? getDirtyMaxZ() : img->getDepth() - 1;
01331
01332 UInt32 w, h, d;
01333 w = ax - ix + 1;
01334 h = ay - iy + 1;
01335 d = az - iz + 1;
01336
01337 if(w != img->getWidth())
01338 glPixelStorei(GL_UNPACK_ROW_LENGTH, img->getWidth());
01339 if(ix != 0)
01340 glPixelStorei(GL_UNPACK_SKIP_PIXELS, ix);
01341 if(iy != 0)
01342 glPixelStorei(GL_UNPACK_SKIP_ROWS, iy);
01343 if(has3DTex && iz != 0)
01344 glPixelStorei(GL_UNPACK_SKIP_IMAGES, iz);
01345
01346 if(compressedData)
01347 {
01348 switch (imgtarget)
01349 {
01350 case GL_TEXTURE_1D:
01351 CompressedTexSubImage1D(GL_TEXTURE_1D, 0, ix, w,
01352 externalFormat, img->getFrameSize(),
01353 img->getData( 0, getFrame(), side ) );
01354 break;
01355 case GL_TEXTURE_2D:
01356 CompressedTexSubImage2D(imgtarget, 0, ix, iy, w, h,
01357 externalFormat, img->getFrameSize(),
01358 img->getData( 0, getFrame(), side ) );
01359 break;
01360 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01361 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01362 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01363 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01364 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01365 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01366 CompressedTexSubImage2D(imgtarget, 0, ix, iy, w, h,
01367 externalFormat,
01368 (img->getSideCount() > 1) ? img->getSideSize() :
01369 img->getFrameSize(),
01370 img->getData( 0, getFrame(), side ) );
01371 break;
01372 case GL_TEXTURE_RECTANGLE_ARB:
01373 CompressedTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
01374 ix, iy, w, h,
01375 externalFormat, img->getFrameSize(),
01376 img->getData( 0, getFrame(), side ) );
01377 break;
01378 case GL_TEXTURE_3D:
01379 CompressedTexSubImage3D(GL_TEXTURE_3D, 0, ix, iy, iz,
01380 w, h, d,
01381 externalFormat, img->getFrameSize(),
01382 img->getData( 0, getFrame(), side ) );
01383 break;
01384 default:
01385 SFATAL << "TextureChunk::refresh: unknown target "
01386 << imgtarget << "!!!" << std::endl;
01387 }
01388 }
01389 else
01390 {
01391 switch (imgtarget)
01392 {
01393 case GL_TEXTURE_1D:
01394 glTexSubImage1D(GL_TEXTURE_1D, 0, ix, w,
01395 externalFormat, type,
01396 img->getData( 0, getFrame(), side ) );
01397 break;
01398 case GL_TEXTURE_2D:
01399 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01400 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01401 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01402 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01403 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01404 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01405 glTexSubImage2D(imgtarget, 0, ix, iy, w, h,
01406 externalFormat, type,
01407 img->getData( 0, getFrame(), side ) );
01408 break;
01409 case GL_TEXTURE_RECTANGLE_ARB:
01410 glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
01411 ix, iy, w, h,
01412 externalFormat, type,
01413 img->getData( 0, getFrame(), side ) );
01414 break;
01415 case GL_TEXTURE_3D:
01416 TexSubImage3D(GL_TEXTURE_3D, 0, ix, iy, iz,
01417 w, h, d,
01418 externalFormat, type,
01419 img->getData( 0, getFrame(), side ) );
01420 break;
01421 default:
01422 SFATAL << "TextureChunk::refresh: unknown target "
01423 << imgtarget << "!!!" << std::endl;
01424 }
01425 }
01426
01427
01428 if(w != img->getWidth())
01429 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
01430 if(ix != 0)
01431 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
01432 if(iy != 0)
01433 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
01434 if(has3DTex && iz != 0)
01435 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
01436
01437 if(paramtarget != GL_NONE)
01438 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY,
01439 getPriority());
01440 }
01441 else
01442 {
01443 SWARNING << "TextureChunk::refresh: not implemented yet for "
01444 << "scaling!!!" << std::endl;
01445 }
01446
01447 glErr("TextureChunk::refresh image");
01448 }
01449 }
01450
01451
01455 void TextureChunk::handleGL(Window *win, UInt32 idstatus)
01456 {
01457 Window::GLObjectStatusE mode;
01458 UInt32 osgid;
01459 GLuint id;
01460
01461 Window::unpackIdStatus(idstatus, osgid, mode);
01462
01463 id = win->getGLObjectId(osgid);
01464
01465 if(mode == Window::destroy)
01466 {
01467 glDeleteTextures(1, &id);
01468 win->setGLObjectId(osgid, 0);
01469 }
01470 else if(mode == Window::finaldestroy)
01471 {
01472
01473 }
01474 else if(mode == Window::initialize || mode == Window::reinitialize ||
01475 mode == Window::needrefresh )
01476 {
01477 if(mode == Window::initialize)
01478 {
01479 glGenTextures(1, &id);
01480 win->setGLObjectId(osgid, id);
01481 }
01482
01483 GLenum target;
01484
01485 ImagePtr img = getImage();
01486
01487 if (img != NullFC)
01488 {
01489 if(img->getSideCount() == 1)
01490 {
01491 target = getTarget();
01492 if ( target == GL_NONE )
01493 {
01494 if(img->getDepth() > 1)
01495 {
01496 if(win->hasExtension(_extTex3D) ||
01497 win->getGLVersion() >= 0x0102
01498 )
01499 target = GL_TEXTURE_3D;
01500 else
01501 {
01502 FWARNING(("TextureChunk::initialize: 3D textures not "
01503 "supported for this window!\n"));
01504 return;
01505 }
01506 }
01507 else if(img->getHeight() > 1) target = GL_TEXTURE_2D;
01508 else target = GL_TEXTURE_1D;
01509 }
01510
01511 handleTexture(win, id, target, target, target, mode, img);
01512 }
01513 else
01514 {
01515 handleTexture(win, id,
01516 GL_TEXTURE_CUBE_MAP_ARB,
01517 GL_TEXTURE_CUBE_MAP_ARB,
01518 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
01519 mode, getImage(), 5);
01520
01521
01522 handleTexture(win, id,
01523 GL_TEXTURE_CUBE_MAP_ARB,
01524 GL_NONE,
01525 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
01526 Window::initialize, getImage(), 4);
01527 handleTexture(win, id,
01528 GL_TEXTURE_CUBE_MAP_ARB,
01529 GL_NONE,
01530 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
01531 Window::initialize, getImage(), 3);
01532 handleTexture(win, id,
01533 GL_TEXTURE_CUBE_MAP_ARB,
01534 GL_NONE,
01535 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
01536 Window::initialize, getImage(), 2);
01537 handleTexture(win, id,
01538 GL_TEXTURE_CUBE_MAP_ARB,
01539 GL_NONE,
01540 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
01541 Window::initialize, getImage(), 1);
01542 handleTexture(win, id,
01543 GL_TEXTURE_CUBE_MAP_ARB,
01544 GL_NONE,
01545 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
01546 Window::initialize, getImage(), 0);
01547
01548 }
01549 }
01550 }
01551 else
01552 {
01553 SWARNING << "TextureChunk(" << this << "::handleGL: Illegal mode: "
01554 << mode << " for id " << id << std::endl;
01555 }
01556
01557 }
01558
01559 void TextureChunk::activate( DrawActionBase *action, UInt32 idx )
01560 {
01561 Window *win = action->getWindow();
01562
01563 Real32 nteximages, ntexcoords;
01564 if((nteximages = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
01565 Window::unknownConstant
01566 )
01567 {
01568 nteximages = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
01569
01570 if(nteximages == Window::unknownConstant)
01571 nteximages = 1.0f;
01572 }
01573 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
01574 Window::unknownConstant
01575 )
01576 {
01577 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
01578
01579 if(ntexcoords == Window::unknownConstant)
01580 ntexcoords = 1.0f;
01581 }
01582
01583 if(idx >= static_cast<UInt32>(nteximages))
01584 {
01585 #ifdef OSG_DEBUG
01586 FWARNING(("TextureChunk::activate: Trying to bind image unit %d,"
01587 " but Window %p only supports %d!\n",
01588 idx, win, nteximages));
01589 #endif
01590 return;
01591 }
01592
01593 if(activateTexture(win, idx))
01594 return;
01595
01596 win->validateGLObject(getGLId());
01597
01598 ImagePtr img = getImage();
01599 GLenum target = getTarget();
01600
01601 if( img == NullFC || ! img->getDimension())
01602 return;
01603
01604 glErr("TextureChunk::activate precheck");
01605
01606 if(img->getSideCount() == 1)
01607 {
01608 if ( target == GL_NONE )
01609 {
01610 if ( img->getDepth() > 1 )
01611 {
01612 if(win->hasExtension(_extTex3D) ||
01613 win->getGLVersion() >= 0x0102
01614 )
01615 target = GL_TEXTURE_3D;
01616 else
01617 {
01618 FWARNING(("TextureChunk::activate: 3D textures not "
01619 "supported for this window!\n"));
01620 return;
01621 }
01622 }
01623 else if(img->getHeight() > 1) target = GL_TEXTURE_2D;
01624 else target = GL_TEXTURE_1D;
01625 }
01626 }
01627 else
01628 {
01629 target = GL_TEXTURE_CUBE_MAP_ARB;
01630 }
01631
01632 FDEBUG(("TextureChunk::activate - %d\n", getGLId()));
01633
01634 action->getStatistics()->getElem(RenderAction::statNTextures)->inc(getGLId());
01635 action->getStatistics()->getElem(RenderAction::statNTexBytes)->add(
01636 getGLId(), getImage()->getSize());
01637
01638 glBindTexture(target, win->getGLObjectId(getGLId()));
01639
01640 #ifdef GL_NV_point_sprite
01641 if(idx < static_cast<UInt32>(ntexcoords))
01642 {
01643 if(getPointSprite() &&
01644 win->hasExtension(_nvPointSprite))
01645 {
01646 glTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_TRUE);
01647 }
01648 }
01649 #endif
01650
01651 if(idx < static_cast<UInt32>(nteximages))
01652 {
01653 if(getLodBias() != 0.0f &&
01654 win->hasExtension(_extTextureLodBias))
01655 {
01656 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT,
01657 getLodBias());
01658 }
01659 }
01660
01661 Real32 ntexunits = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
01662
01663
01664 if(ntexunits == Window::unknownConstant)
01665 ntexunits = 1.0f;
01666
01667 if(idx < static_cast<UInt32>(ntexunits))
01668 {
01669
01670 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, getEnvMode());
01671 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
01672 (GLfloat*)getEnvColor().getValuesRGBA());
01673
01674 if(getEnvMode() == GL_COMBINE_EXT)
01675 {
01676 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, getEnvCombineRGB ());
01677 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, getEnvScaleRGB ());
01678 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, getEnvSource0RGB ());
01679 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, getEnvSource1RGB ());
01680 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, getEnvSource2RGB ());
01681 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, getEnvOperand0RGB());
01682 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, getEnvOperand1RGB());
01683 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, getEnvOperand2RGB());
01684
01685 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, getEnvCombineAlpha ());
01686 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, getEnvScaleAlpha ());
01687 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, getEnvSource0Alpha ());
01688 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, getEnvSource1Alpha ());
01689 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, getEnvSource2Alpha ());
01690 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT,getEnvOperand0Alpha());
01691 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT,getEnvOperand1Alpha());
01692 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT,getEnvOperand2Alpha());
01693 }
01694
01695 handleTextureShader(win, target);
01696
01697 if(getShaderOperation() != GL_NONE &&
01698 win->hasExtension(_nvTextureShader) &&
01699 idx == 0)
01700 {
01701 glEnable(GL_TEXTURE_SHADER_NV);
01702 }
01703 glEnable(target);
01704 }
01705
01706
01707 UInt32 NpotMatScale = getNPOTMatrixScale();
01708 bool setMatrix = false;
01709
01710 if ( idx < static_cast<UInt32>(ntexcoords) &&
01711 !getScale() && NpotMatScale )
01712 {
01713 ImagePtr i = getImage();
01714
01715 if (i != NullFC)
01716 {
01717 Real32 sw=1.f, sh=1.f, sd=1.f,
01718 tw=0.f, th=0.f, td=0.f;
01719
01720 if ( (NpotMatScale & NPotTexScale_TT) &&
01721 getTarget() != GL_TEXTURE_RECTANGLE_ARB &&
01722 !win->hasExtension(_arbTextureNonPowerOfTwo) )
01723 {
01724 UInt32 w,h,d,nw,nh,nd;
01725
01726 w = i->getWidth();
01727 h = i->getHeight();
01728 d = i->getDepth();
01729
01730 nw = osgnextpower2(w);
01731 nh = osgnextpower2(h);
01732 nd = osgnextpower2(d);
01733
01734 sw = w / static_cast<Real32>(nw);
01735 sh = h / static_cast<Real32>(nh);
01736 sd = d / static_cast<Real32>(nd);
01737
01738 setMatrix = true;
01739 }
01740 if ( (NpotMatScale & XFlip_TT) )
01741 {
01742 tw = sw - 1.f;
01743 sw *= -1.f;
01744
01745 setMatrix = true;
01746 }
01747 if ( (NpotMatScale & YFlip_TT) )
01748 {
01749 th = sh - 1.f;
01750 sh *= -1.f;
01751
01752 setMatrix = true;
01753 }
01754 if ( (NpotMatScale & ZFlip_TT) )
01755 {
01756 td = sd - 1.f;
01757 sd *= -1.f;
01758
01759 setMatrix = true;
01760 }
01761
01762 if (setMatrix)
01763 {
01764 Matrix m;
01765
01766 m.setIdentity();
01767 m.setScale( Vec3f(sw, sh, sd) );
01768 m.setTranslate( Vec3f(tw, th, td) );
01769
01770 glPushAttrib(GL_TRANSFORM_BIT);
01771 glMatrixMode(GL_TEXTURE);
01772 glLoadMatrixf(m.getValues());
01773 glPopAttrib();
01774 }
01775 }
01776 }
01777
01778 if (!setMatrix && idx < static_cast<UInt32>(ntexcoords))
01779 {
01780 glPushAttrib(GL_TRANSFORM_BIT);
01781 glMatrixMode(GL_TEXTURE);
01782 glLoadIdentity();
01783 glPopAttrib();
01784 }
01785
01786 glErr("TextureChunk::activate");
01787 }
01788
01789
01790 void TextureChunk::changeFrom(DrawActionBase *action,
01791 StateChunk *old ,
01792 UInt32 idx )
01793 {
01794
01795
01796
01797 if(old == this)
01798 return;
01799
01800
01801
01802
01803
01804 if(getTypeId() != old->getTypeId())
01805 {
01806 old->deactivate(action, idx);
01807 activate(action, idx);
01808 return;
01809 }
01810
01811 TextureChunk *oldp = dynamic_cast<TextureChunk *>(old);
01812
01813 ImagePtr img = getImage();
01814 GLenum target = getTarget();
01815 GLenum oldtarget = oldp->getTarget();
01816 bool oldused = (oldp->getImage() != NullFC &&
01817 oldp->getImage()->getDimension());
01818
01819 if(img == NullFC || img->getDimension() == 0)
01820 {
01821 oldp->deactivate(action, idx);
01822 return;
01823 }
01824
01825 glErr("TextureChunk::changeFrom precheck");
01826
01827 Window *win = action->getWindow();
01828
01829 if(activateTexture(win, idx))
01830 return;
01831
01832 UInt32 nteximages, ntexcoords, ntexunits;
01833
01834 Real32 dummy = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
01835
01836 if(dummy == Window::unknownConstant)
01837 {
01838 ntexunits = 1;
01839 }
01840 else
01841 {
01842 ntexunits = static_cast<UInt32>(dummy);
01843 }
01844
01845 if((dummy = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
01846 Window::unknownConstant
01847 )
01848 {
01849 nteximages = ntexunits;
01850 }
01851 else
01852 {
01853 nteximages = static_cast<UInt32>(dummy);
01854 }
01855
01856 if((dummy = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
01857 Window::unknownConstant
01858 )
01859 {
01860 ntexcoords = ntexunits;
01861 }
01862 else
01863 {
01864 ntexcoords = static_cast<UInt32>(dummy);
01865 }
01866
01867 if(idx >= nteximages)
01868 {
01869 #ifdef OSG_DEBUG
01870 FWARNING(("TextureChunk::activate: Trying to bind image unit %d,"
01871 " but Window %p only supports %d!\n",
01872 idx, win, nteximages));
01873 #endif
01874 return;
01875 }
01876
01877 if(img->getSideCount() == 1)
01878 {
01879 if ( target == GL_NONE )
01880 {
01881 if ( img->getDepth() > 1 )
01882 {
01883 if(win->hasExtension(_extTex3D) ||
01884 win->getGLVersion() >= 0x0102
01885 )
01886 target = GL_TEXTURE_3D;
01887 else
01888 {
01889 FWARNING(("TextureChunk::activate: 3D textures not "
01890 "supported for this window!\n"));
01891 return;
01892 }
01893 }
01894 else if(img->getHeight() > 1) target = GL_TEXTURE_2D;
01895 else target = GL_TEXTURE_1D;
01896 }
01897 }
01898 else
01899 {
01900 target = GL_TEXTURE_CUBE_MAP_ARB;
01901 }
01902
01903 if(oldused)
01904 {
01905 if(oldp->getImage()->getSideCount() == 1)
01906 {
01907 if(oldtarget == GL_NONE)
01908 {
01909 if(oldp->getImage()->getDepth() > 1)
01910 {
01911 if(win->hasExtension(_extTex3D) ||
01912 win->getGLVersion() >= 0x0102
01913 )
01914 oldtarget = GL_TEXTURE_3D;
01915 else
01916 {
01917 FWARNING(("TextureChunk::changeFrom: 3D textures not "
01918 "supported for this window!\n"));
01919 oldp->deactivate(action, idx);
01920 return;
01921 }
01922 }
01923 else if(oldp->getImage()->getHeight() > 1)
01924 {
01925 oldtarget = GL_TEXTURE_2D;
01926 }
01927 else
01928 {
01929 oldtarget = GL_TEXTURE_1D;
01930 }
01931 }
01932 }
01933 else
01934 {
01935 oldtarget = GL_TEXTURE_CUBE_MAP_ARB;
01936 }
01937
01938 if(target != oldtarget && idx < ntexunits)
01939 {
01940 glDisable(oldtarget);
01941 }
01942 }
01943
01944 win->validateGLObject(getGLId());
01945
01946 action->getStatistics()->getElem(RenderAction::statNTextures)->inc(getGLId());
01947 action->getStatistics()->getElem(RenderAction::statNTexBytes)->add(
01948 getGLId(), getImage()->getSize());
01949
01950 glBindTexture(target, win->getGLObjectId(getGLId()));
01951
01952 #ifdef GL_NV_point_sprite
01953 if(idx < ntexcoords)
01954 {
01955 if((!oldused || oldp->getPointSprite() != getPointSprite()) &&
01956 win->hasExtension(_nvPointSprite)
01957 )
01958 {
01959 glTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, getPointSprite());
01960 }
01961 }
01962 #endif
01963
01964 if(idx < nteximages)
01965 {
01966 if((!oldused || oldp->getLodBias() != getLodBias()) &&
01967 win->hasExtension(_extTextureLodBias)
01968 )
01969 {
01970 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT,
01971 getLodBias());
01972 }
01973 }
01974
01975 if(idx < ntexunits)
01976 {
01977 if(!oldused || oldp->getEnvMode() != getEnvMode())
01978 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, getEnvMode());
01979
01980 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
01981 (GLfloat*)getEnvColor().getValuesRGBA());
01982
01983 if(getEnvMode() == GL_COMBINE_EXT)
01984 {
01985 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, getEnvCombineRGB ());
01986 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, getEnvScaleRGB ());
01987 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, getEnvSource0RGB ());
01988 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, getEnvSource1RGB ());
01989 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, getEnvSource2RGB ());
01990 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, getEnvOperand0RGB());
01991 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, getEnvOperand1RGB());
01992 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, getEnvOperand2RGB());
01993
01994 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, getEnvCombineAlpha ());
01995 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, getEnvScaleAlpha ());
01996 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, getEnvSource0Alpha ());
01997 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, getEnvSource1Alpha ());
01998 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, getEnvSource2Alpha ());
01999 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT,getEnvOperand0Alpha());
02000 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT,getEnvOperand1Alpha());
02001 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT,getEnvOperand2Alpha());
02002 }
02003
02004 if(target != oldtarget)
02005 {
02006 glEnable(target);
02007 }
02008
02009 if(win->hasExtension(_nvTextureShader))
02010 {
02011 if( getShaderOperation() != GL_NONE &&
02012 (!oldused || oldp->getShaderOperation() == GL_NONE)
02013 )
02014 {
02015 handleTextureShader(win, target);
02016 if(idx == 0)
02017 glEnable(GL_TEXTURE_SHADER_NV);
02018 }
02019 else if( getShaderOperation() == GL_NONE &&
02020 (!oldused || oldp->getShaderOperation() != GL_NONE)
02021 )
02022 {
02023 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
02024 if(idx == 0)
02025 glDisable(GL_TEXTURE_SHADER_NV);
02026 }
02027 }
02028 }
02029
02030
02031 UInt32 NpotMatScale = getNPOTMatrixScale();
02032 bool setMatrix = false;
02033
02034 if ( idx < static_cast<UInt32>(ntexcoords) &&
02035 !getScale() && NpotMatScale )
02036 {
02037 ImagePtr i = getImage();
02038
02039 if (i != NullFC)
02040 {
02041 Real32 sw=1.f, sh=1.f, sd=1.f,
02042 tw=0.f, th=0.f, td=0.f;
02043
02044 if ( (NpotMatScale & NPotTexScale_TT) &&
02045 getTarget() != GL_TEXTURE_RECTANGLE_ARB &&
02046 !win->hasExtension(_arbTextureNonPowerOfTwo) )
02047 {
02048 UInt32 w,h,d,nw,nh,nd;
02049
02050 w = i->getWidth();
02051 h = i->getHeight();
02052 d = i->getDepth();
02053
02054 nw = osgnextpower2(w);
02055 nh = osgnextpower2(h);
02056 nd = osgnextpower2(d);
02057
02058 sw = w / static_cast<Real32>(nw);
02059 sh = h / static_cast<Real32>(nh);
02060 sd = d / static_cast<Real32>(nd);
02061
02062 setMatrix = true;
02063 }
02064 if ( (NpotMatScale & XFlip_TT) )
02065 {
02066 tw = sw - 1.f;
02067 sw *= -1.f;
02068
02069 setMatrix = true;
02070 }
02071 if ( (NpotMatScale & YFlip_TT) )
02072 {
02073 th = sh - 1.f;
02074 sh *= -1.f;
02075
02076 setMatrix = true;
02077 }
02078 if ( (NpotMatScale & ZFlip_TT) )
02079 {
02080 td = sd - 1.f;
02081 sd *= -1.f;
02082
02083 setMatrix = true;
02084 }
02085
02086 if (setMatrix)
02087 {
02088 Matrix m;
02089
02090 m.setIdentity();
02091 m.setScale( Vec3f(sw, sh, sd) );
02092 m.setTranslate( Vec3f(tw, th, td) );
02093
02094 glPushAttrib(GL_TRANSFORM_BIT);
02095 glMatrixMode(GL_TEXTURE);
02096 glLoadMatrixf(m.getValues());
02097 glPopAttrib();
02098 }
02099 }
02100 }
02101
02102 if (!setMatrix && idx < static_cast<UInt32>(ntexcoords))
02103 {
02104 glPushAttrib(GL_TRANSFORM_BIT);
02105 glMatrixMode(GL_TEXTURE);
02106 glLoadIdentity();
02107 glPopAttrib();
02108 }
02109
02110 glErr("TextureChunk::changeFrom");
02111 }
02112
02113 void TextureChunk::deactivate(DrawActionBase *action, UInt32 idx)
02114 {
02115 Window *win = action->getWindow();
02116
02117 Real32 nteximages, ntexcoords;
02118 if((nteximages = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
02119 Window::unknownConstant
02120 )
02121 {
02122 nteximages = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
02123
02124 if(nteximages == Window::unknownConstant)
02125 nteximages = 1.0f;
02126 }
02127 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
02128 Window::unknownConstant
02129 )
02130 {
02131 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
02132
02133 if(ntexcoords == Window::unknownConstant)
02134 ntexcoords = 1.0f;
02135 }
02136
02137 if(idx >= static_cast<UInt32>(nteximages))
02138 {
02139 #ifdef OSG_DEBUG
02140 FWARNING(("TextureChunk::deactivate: Trying to bind image unit %d,"
02141 " but Window %p only supports %d!\n",
02142 idx, win, nteximages));
02143 #endif
02144 return;
02145 }
02146
02147 ImagePtr img = getImage();
02148 GLenum target = getTarget();
02149
02150 if(img == NullFC || ! img->getDimension())
02151 return;
02152
02153 glErr("TextureChunk::deactivate precheck");
02154
02155 bool isActive = false;
02156
02157 #ifdef GL_NV_point_sprite
02158 if(getPointSprite() &&
02159 win->hasExtension(_nvPointSprite) &&
02160 idx < static_cast<UInt32>(ntexcoords)
02161 )
02162 {
02163 if(!isActive)
02164 {
02165 activateTexture(win, idx);
02166 isActive = true;
02167 }
02168 glTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_FALSE);
02169 }
02170 #endif
02171
02172 if(getLodBias() != 0.0f &&
02173 win->hasExtension(_extTextureLodBias))
02174 {
02175 if(!isActive)
02176 activateTexture(win, idx);
02177 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT,
02178 0.0f);
02179 }
02180
02181 Real32 ntexunits = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
02182 if(ntexunits == Window::unknownConstant)
02183 ntexunits = 1.0f;
02184
02185 if(idx >= static_cast<UInt32>(ntexunits))
02186 return;
02187
02188 if(!isActive)
02189 activateTexture(win, idx);
02190
02191 if(img->getSideCount() == 1)
02192 {
02193 if ( target == GL_NONE )
02194 {
02195 if ( img->getDepth() > 1 )
02196 {
02197 if(win->hasExtension(_extTex3D) ||
02198 win->getGLVersion() >= 0x0102
02199 )
02200 target = GL_TEXTURE_3D;
02201 else
02202 {
02203 FWARNING(("TextureChunk::activate: 3D textures not "
02204 "supported for this window!\n"));
02205 return;
02206 }
02207 }
02208 else if(img->getHeight() > 1) target = GL_TEXTURE_2D;
02209 else target = GL_TEXTURE_1D;
02210 }
02211 }
02212 else
02213 {
02214 target = GL_TEXTURE_CUBE_MAP_ARB;
02215 }
02216
02217 if(getShaderOperation() != GL_NONE &&
02218 win->hasExtension(_nvTextureShader))
02219 {
02220 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
02221
02222 if(idx == 0)
02223 glDisable(GL_TEXTURE_SHADER_NV);
02224 }
02225
02226
02227
02228
02229 if ( idx < static_cast<UInt32>(ntexcoords) )
02230 {
02231 glPushAttrib(GL_TRANSFORM_BIT);
02232 glMatrixMode(GL_TEXTURE);
02233 glLoadIdentity();
02234 glPopAttrib();
02235 }
02236
02237 glDisable(target);
02238
02239 glErr("TextureChunk::deactivate");
02240 }
02241
02242
02243
02244 Real32 TextureChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
02245 {
02246 return 0;
02247 }
02248
02249 bool TextureChunk::operator < (const StateChunk &other) const
02250 {
02251 return this < &other;
02252 }
02253
02254 bool TextureChunk::operator == (const StateChunk &other) const
02255 {
02256 TextureChunk const *tother = dynamic_cast<TextureChunk const*>(&other);
02257
02258 if(!tother)
02259 return false;
02260
02261 if(tother == this)
02262 return true;
02263
02264 bool returnValue =
02265 getImage () == tother->getImage () &&
02266 getMinFilter() == tother->getMinFilter() &&
02267 getMagFilter() == tother->getMagFilter() &&
02268 getWrapS () == tother->getWrapS () &&
02269 getWrapT () == tother->getWrapT () &&
02270 getWrapR () == tother->getWrapR () &&
02271 getPriority () == tother->getPriority () &&
02272 getEnvMode () == tother->getEnvMode () &&
02273 getNPOTMatrixScale() == tother->getNPOTMatrixScale();
02274
02275 if(returnValue == true && getEnvMode() == GL_COMBINE_EXT)
02276 {
02277 returnValue =
02278 getEnvCombineRGB () == tother->getEnvCombineRGB () &&
02279
02280 getEnvSource0RGB () == tother->getEnvSource0RGB () &&
02281 getEnvSource1RGB () == tother->getEnvSource1RGB () &&
02282 getEnvSource2RGB () == tother->getEnvSource2RGB () &&
02283
02284 getEnvOperand0RGB() == tother->getEnvOperand0RGB () &&
02285 getEnvOperand1RGB() == tother->getEnvOperand1RGB () &&
02286 getEnvOperand2RGB() == tother->getEnvOperand2RGB () &&
02287
02288 getEnvCombineAlpha () == tother->getEnvCombineAlpha () &&
02289
02290 getEnvSource0Alpha () == tother->getEnvSource0Alpha () &&
02291 getEnvSource1Alpha () == tother->getEnvSource1Alpha () &&
02292 getEnvSource2Alpha () == tother->getEnvSource2Alpha () &&
02293
02294 getEnvOperand0Alpha() == tother->getEnvOperand0Alpha() &&
02295 getEnvOperand1Alpha() == tother->getEnvOperand1Alpha() &&
02296 getEnvOperand2Alpha() == tother->getEnvOperand2Alpha();
02297
02298 returnValue &=
02299 (( getEnvScaleRGB () - tother->getEnvScaleRGB ()) < Eps) &&
02300 ((tother->getEnvScaleRGB () - getEnvScaleRGB ()) < Eps) &&
02301 (( getEnvScaleAlpha() - tother->getEnvScaleAlpha()) < Eps) &&
02302 ((tother->getEnvScaleAlpha() - getEnvScaleAlpha()) < Eps);
02303 }
02304
02305 return returnValue;
02306 }
02307
02308 bool TextureChunk::operator != (const StateChunk &other) const
02309 {
02310 return ! (*this == other);
02311 }
02312
02313
02314
02315
02316
02317 #ifdef OSG_SGI_CC
02318 #pragma set woff 1174
02319 #endif
02320
02321 #ifdef OSG_LINUX_ICC
02322 #pragma warning( disable : 177 )
02323 #endif
02324
02325 namespace
02326 {
02327 static Char8 cvsid_cpp [] = "@(#)$Id: FCTemplate_cpp.h,v 1.13 2002/06/01 10:37:25 vossg Exp $";
02328 static Char8 cvsid_hpp [] = OSGTEXTURECHUNK_HEADER_CVSID;
02329 static Char8 cvsid_inl [] = OSGTEXTURECHUNK_INLINE_CVSID;
02330
02331 static Char8 cvsid_fields_hpp[] = OSGTEXTURECHUNKFIELDS_HEADER_CVSID;
02332 }
02333
02334 #ifdef __sgi
02335 #pragma reset woff 1174
02336 #endif
02337