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