fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / State / Base / OSGTextureObjChunk.cpp
blob21e0efeeed4f64bcdb9a77e518b9170d701b3d61
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include <boost/bind.hpp>
48 #include "OSGConfig.h"
50 #include "OSGGL.h"
51 #include "OSGGLU.h"
52 #include "OSGGLEXT.h"
53 #include "OSGGLFuncProtos.h"
54 #include "OSGImage.h"
56 #include "OSGDrawEnv.h"
58 #include "OSGTextureObjChunk.h"
60 //#define OSG_DUMP_TEX
62 OSG_USING_NAMESPACE
64 // Documentation for this class is emited in the
65 // OSGTextureObjChunkBase.cpp file.
66 // To modify it, please change the .fcd file (OSGTextureObjChunk.fcd) and
67 // regenerate the base file.
69 /***************************************************************************\
70 * Class variables *
71 \***************************************************************************/
73 typedef OSG::Window Win;
75 UInt32 TextureObjChunk::_extTex3D = Win::invalidExtensionID;
76 UInt32 TextureObjChunk::_extTextureArray = Win::invalidExtensionID;
77 UInt32 TextureObjChunk::_arbCubeTex = Win::invalidExtensionID;
78 UInt32 TextureObjChunk::_sgisGenerateMipmap = Win::invalidExtensionID;
79 UInt32 TextureObjChunk::_arbTextureCompression = Win::invalidExtensionID;
80 UInt32 TextureObjChunk::_arbTextureRectangle = Win::invalidExtensionID;
81 UInt32 TextureObjChunk::_arbTextureNonPowerOfTwo = Win::invalidExtensionID;
82 UInt32 TextureObjChunk::_extTextureFilterAnisotropic = Win::invalidExtensionID;
83 UInt32 TextureObjChunk::_extShadow = Win::invalidExtensionID;
84 UInt32 TextureObjChunk::_extDepthTexture = Win::invalidExtensionID;
86 UInt32 TextureObjChunk::_funcTexImage3D = Win::invalidFunctionID;
87 UInt32 TextureObjChunk::_funcTexImage3DExt = Win::invalidFunctionID;
88 UInt32 TextureObjChunk::_funcTexSubImage3D = Win::invalidFunctionID;
89 UInt32 TextureObjChunk::_funcTexSubImage3DExt = Win::invalidFunctionID;
90 UInt32 TextureObjChunk::_funcCompressedTexImage1D = Win::invalidFunctionID;
91 UInt32 TextureObjChunk::_funcCompressedTexSubImage1D = Win::invalidFunctionID;
92 UInt32 TextureObjChunk::_funcCompressedTexImage2D = Win::invalidFunctionID;
93 UInt32 TextureObjChunk::_funcCompressedTexSubImage2D = Win::invalidFunctionID;
94 UInt32 TextureObjChunk::_funcCompressedTexImage3D = Win::invalidFunctionID;
95 UInt32 TextureObjChunk::_funcCompressedTexSubImage3D = Win::invalidFunctionID;
98 StatElemDesc<StatIntOnceElem> TextureObjChunk::statNTextures(
99 "NTextures",
100 "number of texture changes");
102 StatElemDesc<StatIntOnceElem> TextureObjChunk::statNTexBytes(
103 "NTexBytes",
104 "sum of all used textures' sizes (approx., in bytes)");
107 /***************************************************************************\
108 * Class methods *
109 \***************************************************************************/
111 /*-------------------------------------------------------------------------*\
112 - private -
113 \*-------------------------------------------------------------------------*/
115 void TextureObjChunk::initMethod(InitPhase ePhase)
117 Inherited::initMethod(ePhase);
119 if(ePhase == TypeObject::SystemPost)
121 _extTex3D =
122 Window::registerExtension("GL_EXT_texture3D" );
123 _extTextureArray =
124 Window::registerExtension("GL_EXT_texture_array" );
125 _arbCubeTex =
126 Window::registerExtension("GL_ARB_texture_cube_map");
127 _sgisGenerateMipmap =
128 Window::registerExtension("GL_SGIS_generate_mipmap" );
129 _arbTextureCompression =
130 Window::registerExtension("GL_ARB_texture_compression" );
131 _arbTextureRectangle =
132 Window::registerExtension("GL_ARB_texture_rectangle" );
133 _arbTextureNonPowerOfTwo =
134 Window::registerExtension("GL_ARB_texture_non_power_of_two" );
135 _extTextureFilterAnisotropic =
136 Window::registerExtension("GL_EXT_texture_filter_anisotropic" );
138 _extShadow =
139 Window::registerExtension("GL_ARB_shadow" );
140 _extDepthTexture =
141 Window::registerExtension("GL_ARB_depth_texture" );
143 _funcTexImage3D = Window::registerFunction(
144 OSG_DLSYM_UNDERSCORE"glTexImage3D", _extTex3D, 0x0102);
145 _funcTexImage3DExt = Window::registerFunction(
146 OSG_DLSYM_UNDERSCORE"glTexImage3DEXT", _extTex3D, 0x0102);
148 _funcTexSubImage3D = Window::registerFunction(
149 OSG_DLSYM_UNDERSCORE"glTexSubImage3D", _extTex3D, 0x0102);
150 _funcTexSubImage3DExt = Window::registerFunction(
151 OSG_DLSYM_UNDERSCORE"glTexSubImage3DEXT", _extTex3D, 0x0102);
153 _funcCompressedTexImage1D = Window::registerFunction(
154 OSG_DLSYM_UNDERSCORE"glCompressedTexImage1DARB" ,
155 _arbTextureCompression);
157 _funcCompressedTexSubImage1D = Window::registerFunction(
158 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage1DARB" ,
159 _arbTextureCompression);
161 _funcCompressedTexImage2D = Window::registerFunction(
162 OSG_DLSYM_UNDERSCORE"glCompressedTexImage2DARB" ,
163 _arbTextureCompression);
165 _funcCompressedTexSubImage2D = Window::registerFunction(
166 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage2DARB" ,
167 _arbTextureCompression);
169 _funcCompressedTexImage3D = Window::registerFunction(
170 OSG_DLSYM_UNDERSCORE"glCompressedTexImage3DARB" ,
171 _arbTextureCompression);
173 _funcCompressedTexSubImage3D = Window::registerFunction(
174 OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage3DARB" ,
175 _arbTextureCompression);
177 Window::registerConstant(GL_MAX_TEXTURE_UNITS_ARB );
178 Window::registerConstant(GL_MAX_TEXTURE_IMAGE_UNITS_ARB);
179 Window::registerConstant(GL_MAX_TEXTURE_COORDS_ARB );
183 /***************************************************************************\
184 * Instance methods *
185 \***************************************************************************/
187 /*-------------------------------------------------------------------------*\
188 - private -
189 \*-------------------------------------------------------------------------*/
192 /*------------- constructors & destructors --------------------------------*/
194 TextureObjChunk::TextureObjChunk(void) :
195 Inherited()
199 TextureObjChunk::TextureObjChunk(const TextureObjChunk &source) :
200 Inherited(source)
204 TextureObjChunk::~TextureObjChunk(void)
208 /*------------------------- Chunk Class Access ---------------------------*/
210 bool TextureObjChunk::isCubeTexture(void)
212 return
213 this->getImage() != NULL &&
214 this->getImage()->getSideCount() == 6;
217 /*------------------------------- Sync -----------------------------------*/
219 /*! React to field changes.
220 Note: this function also handles CubeTexture changes, make sure to keep
221 it consistent with the cubeTexture specifics
224 void TextureObjChunk::changed(ConstFieldMaskArg whichField,
225 UInt32 origin,
226 BitVector details)
228 GLenum id = _sfGLId.getValue();
230 // Only filter changed? Mipmaps need reinit.
231 if((whichField & ~(MinFilterFieldMask | MagFilterFieldMask)) == 0)
233 if((getMinFilter() != GL_NEAREST) &&
234 (getMinFilter() != GL_LINEAR))
236 Window::reinitializeGLObject(id);
238 else
240 imageContentChanged();
242 } // Only priority changed? Refresh is fine.
243 else if((whichField & ~(PriorityFieldMask | FrameFieldMask)) == 0)
245 imageContentChanged();
246 } // Only dirty rectangle changed? Refresh is fine.
247 else if ((whichField & ~(DirtyMinXFieldMask | DirtyMaxXFieldMask |
248 DirtyMinYFieldMask | DirtyMaxYFieldMask |
249 DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
251 Window::refreshGLObject(id);
253 else
255 if(origin == ChangedOrigin::Child &&
256 0x0000 != (whichField & ImageFieldMask))
258 if((details & ~(Image::PixelFieldMask)) == 0)
260 Window::refreshGLObject(id);
262 else
264 if(0x0000 != (whichField & (Image::WidthFieldMask |
265 Image::HeightFieldMask |
266 Image::DepthFieldMask)))
268 Window::reinitializeGLObject(id);
272 else
274 Window::reinitializeGLObject(id);
278 Inherited::changed(whichField, origin, details);
281 bool TextureObjChunk::isTransparent(void) const
283 // Even if the texture has alpha, the Blending makes the sorting
284 // important, thus textures per se are not transparent
285 return false;
289 /*----------------------------- onCreate --------------------------------*/
291 void TextureObjChunk::onCreate(const TextureObjChunk *source)
293 Inherited::onCreate(source);
295 if(GlobalSystemState == Startup)
296 return;
298 setGLId(Window::registerGLObject(
299 boost::bind(&TextureObjChunk::handleGL,
300 TextureObjChunkMTUncountedPtr(this),
301 _1, _2, _3, _4),
302 &TextureObjChunk::handleDestroyGL));
305 void TextureObjChunk::onCreateAspect(const TextureObjChunk *createAspect,
306 const TextureObjChunk *source )
308 Inherited::onCreateAspect(createAspect, source);
311 void TextureObjChunk::onDestroy(UInt32 uiContainerId)
313 if(getGLId() > 0)
314 Window::destroyGLObject(getGLId(), 1);
316 Inherited::onDestroy(uiContainerId);
319 /*------------------------------ Output ----------------------------------*/
321 void TextureObjChunk::dump( UInt32 uiIndent,
322 const BitVector bvFlags ) const
324 Inherited::dump(uiIndent, bvFlags);
326 if((bvFlags & ImageFieldMask) != 0)
328 indentLog(uiIndent, PLOG);
329 PLOG << "image " << _sfImage.getValue() << "\n";
332 if((bvFlags & InternalFormatFieldMask) != 0)
334 indentLog(uiIndent, PLOG);
335 PLOG << "internalFormat "
336 << GLDefineMapper::the()->toString(_sfInternalFormat.getValue())
337 << "\n";
340 if((bvFlags & ExternalFormatFieldMask) != 0)
342 indentLog(uiIndent, PLOG);
343 PLOG << "externalFormat "
344 << GLDefineMapper::the()->toString(_sfExternalFormat.getValue())
345 << "\n";
348 if((bvFlags & ScaleFieldMask) != 0)
350 indentLog(uiIndent, PLOG);
351 PLOG << "scale " << _sfScale.getValue() << "\n";
354 if((bvFlags & FrameFieldMask) != 0)
356 indentLog(uiIndent, PLOG);
357 PLOG << "frame " << _sfFrame.getValue() << "\n";
360 if((bvFlags & MinFilterFieldMask) != 0)
362 indentLog(uiIndent, PLOG);
363 PLOG << "minFilter "
364 << GLDefineMapper::the()->toString(_sfMinFilter.getValue())
365 << "\n";
368 if((bvFlags & MagFilterFieldMask) != 0)
370 indentLog(uiIndent, PLOG);
371 PLOG << "magFilter "
372 << GLDefineMapper::the()->toString(_sfMagFilter.getValue())
373 << "\n";
376 if((bvFlags & WrapSFieldMask) != 0)
378 indentLog(uiIndent, PLOG);
379 PLOG << "warpS "
380 << GLDefineMapper::the()->toString(_sfWrapS.getValue())
381 << "\n";
384 if((bvFlags & WrapTFieldMask) != 0)
386 indentLog(uiIndent, PLOG);
387 PLOG << "warpT "
388 << GLDefineMapper::the()->toString(_sfWrapT.getValue())
389 << "\n";
392 if((bvFlags & WrapRFieldMask) != 0)
394 indentLog(uiIndent, PLOG);
395 PLOG << "warpR "
396 << GLDefineMapper::the()->toString(_sfWrapR.getValue())
397 << "\n";
400 if((bvFlags & AnisotropyFieldMask) != 0)
402 indentLog(uiIndent, PLOG);
403 PLOG << "anisotropy " << _sfAnisotropy.getValue() << "\n";
406 if((bvFlags & BorderColorFieldMask) != 0)
408 indentLog(uiIndent, PLOG);
409 PLOG << "borderColor " << _sfBorderColor.getValue() << "\n";
412 if((bvFlags & CompareModeFieldMask) != 0)
414 indentLog(uiIndent, PLOG);
415 PLOG << "compareMode "
416 << GLDefineMapper::the()->toString(_sfCompareMode.getValue())
417 << "\n";
420 if((bvFlags & CompareFuncFieldMask) != 0)
422 indentLog(uiIndent, PLOG);
423 PLOG << "compareFunc "
424 << GLDefineMapper::the()->toString(_sfCompareFunc.getValue())
425 << "\n";
428 if((bvFlags & DepthModeFieldMask) != 0)
430 indentLog(uiIndent, PLOG);
431 PLOG << "depthMode "
432 << GLDefineMapper::the()->toString(_sfDepthMode.getValue())
433 << "\n";
436 if((bvFlags & BorderWidthFieldMask) != 0)
438 indentLog(uiIndent, PLOG);
439 PLOG << "borderWidth " << _sfBorderWidth.getValue() << "\n";
442 if((bvFlags & SkipMipMapLevelsFieldMask) != 0)
444 indentLog(uiIndent, PLOG);
445 PLOG << "skipMipMapLevels " << _sfSkipMipMapLevels.getValue() << "\n";
451 void TextureObjChunk::handleTexture(Window *win,
452 UInt32 id,
453 GLenum bindtarget,
454 GLenum paramtarget,
455 GLenum imgtarget,
456 Window::GLObjectStatusE mode,
457 Image *img,
458 Int32 side)
460 if( img==NULL || ! img->getDimension()) // no image ?
461 return;
463 // Early out if we don't have any image data, probably because we cleared
464 // on upload.
465 // NOTE: We need to be absolutely sure that no changes happen to the
466 // texture object after the first initialization.
467 if (img->getClearOnLoad() && img->getMFPixel()->empty())
469 return;
472 if(mode == Window::initialize || mode == Window::reinitialize)
474 if( bindtarget == GL_TEXTURE_3D &&
475 !win->hasExtOrVersion(_extTex3D, 0x0102))
477 FWARNING(("3D textures not supported on Window %p!\n",
478 static_cast<void *>(win)));
479 return;
482 if((imgtarget == GL_TEXTURE_1D_ARRAY ||
483 imgtarget == GL_TEXTURE_2D_ARRAY ||
484 imgtarget == GL_TEXTURE_CUBE_MAP_ARRAY) &&
485 !win->hasExtOrVersion(_extTextureArray, 0x0300))
487 FWARNING(("texture arrays not supported on Window %p!\n",
488 static_cast<void *>(win)));
489 return;
492 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB &&
493 !win->hasExtOrVersion(_arbTextureRectangle, 0x0301))
495 FWARNING(("Rectangular textures not supported on Window %p!\n",
496 static_cast<void *>(win)));
497 return;
500 if(paramtarget == GL_TEXTURE_CUBE_MAP_ARB &&
501 !win->hasExtOrVersion(_arbCubeTex, 0x0103, 0x0200))
503 FNOTICE(("Cube textures not supported on Window %p!\n",
504 static_cast<void *>(win)));
505 return;
508 if(img->hasCompressedData() &&
509 !win->hasExtOrVersion(_arbTextureCompression, 0x0103, 0x0200))
511 FWARNING(("Compressed textures not supported on Window %p!\n",
512 static_cast<void *>(win)));
513 return;
516 #if 0 // ????? GV
517 if(mode == Window::reinitialize)
519 GLuint tex = id;
520 glDeleteTextures(1, &tex);
522 #endif
524 // 3D texture functions
525 OSGGETGLFUNCBYID_GL3( glTexImage3D,
526 osgGlTexImage3D,
527 _funcTexImage3D,
528 win);
530 // standard function not available? try extension
531 if(osgGlTexImage3D == NULL)
533 OSGGETGLFUNCBYID_NV_GL3( glTexImage3D,
534 osgGlTexImage3D,
535 _funcTexImage3DExt,
536 win);
539 OSGGETGLFUNCBYID_GL3( glTexSubImage3D,
540 osgGlTexSubImage3D,
541 _funcTexSubImage3D,
542 win);
544 // standard function not available? try extension
545 if(osgGlTexSubImage3D == NULL)
547 OSGGETGLFUNCBYID_NV_GL3( glTexSubImage3D,
548 osgGlTexSubImage3D,
549 _funcTexSubImage3DExt,
550 win);
553 #ifndef OSG_OGL_ES2
554 // Compressed texture functions
555 OSGGETGLFUNCBYID_GL3 ( glCompressedTexImage1D,
556 osgGlCompressedTexImage1D,
557 _funcCompressedTexImage1D,
558 win);
559 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage1D,
560 osgGlCompressedTexSubImage1D,
561 _funcCompressedTexSubImage1D,
562 win);
563 #endif
564 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexImage2D,
565 osgGlCompressedTexImage2D,
566 _funcCompressedTexImage2D,
567 win);
568 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexSubImage2D,
569 osgGlCompressedTexSubImage2D,
570 _funcCompressedTexSubImage2D,
571 win);
572 OSGGETGLFUNCBYID_GL3 ( glCompressedTexImage3D,
573 osgGlCompressedTexImage3D,
574 _funcCompressedTexImage3D,
575 win);
576 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage3D,
577 osgGlCompressedTexSubImage3D,
578 _funcCompressedTexSubImage3D,
579 win);
581 // as we're not allocating anything here, the same code can be used
582 // for reinitialization
584 glErr("TextureObjChunk::initialize precheck");
586 FDEBUG(("texture (re-)initialize\n"));
588 glBindTexture(bindtarget, id);
590 if(paramtarget != GL_NONE)
592 // set the parameters
593 #if !defined(OSG_OGL_COREONLY) && !defined(OSG_OGL_ES2)
594 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY, getPriority());
595 #endif
596 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, getMinFilter());
597 glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER, getMagFilter());
598 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_S, getWrapS());
600 if(paramtarget == GL_TEXTURE_2D ||
601 paramtarget == GL_TEXTURE_2D_ARRAY ||
602 paramtarget == GL_TEXTURE_3D ||
603 paramtarget == GL_TEXTURE_CUBE_MAP_ARB ||
604 paramtarget == GL_TEXTURE_CUBE_MAP_ARRAY ||
605 paramtarget == GL_TEXTURE_RECTANGLE_ARB )
607 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_T, getWrapT());
610 if(paramtarget == GL_TEXTURE_2D_ARRAY ||
611 paramtarget == GL_TEXTURE_3D ||
612 paramtarget == GL_TEXTURE_CUBE_MAP_ARB ||
613 paramtarget == GL_TEXTURE_CUBE_MAP_ARRAY )
616 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_R, getWrapR());
619 if(getAnisotropy() > 1.0f &&
620 win->hasExtension(_extTextureFilterAnisotropic))
622 glTexParameterf(paramtarget,
623 GL_TEXTURE_MAX_ANISOTROPY_EXT,
624 getAnisotropy());
627 #ifndef OSG_OGL_ES2
628 glTexParameterfv(paramtarget,
629 GL_TEXTURE_BORDER_COLOR,
630 const_cast<GLfloat *>(
631 getBorderColor().getValuesRGBA()));
632 #endif
634 if(getCompareMode() != GL_NONE &&
635 win->hasExtOrVersion(_extShadow, 0x0104))
637 glTexParameteri(paramtarget,
638 GL_TEXTURE_COMPARE_MODE,
639 getCompareMode());
640 glTexParameteri(paramtarget,
641 GL_TEXTURE_COMPARE_FUNC,
642 getCompareFunc());
645 if(getDepthMode() != GL_LUMINANCE &&
646 win->hasExtOrVersion(_extDepthTexture, 0x0104))
648 glTexParameteri(paramtarget,
649 GL_DEPTH_TEXTURE_MODE,
650 getDepthMode());
653 glErr("TextureObjChunk::initialize params");
656 // set the image
657 GLenum internalFormat = GL_NONE;
658 GLenum externalFormat = GL_NONE;
659 GLenum type = img->getDataType();
660 UInt32 width = img->getWidth();
661 UInt32 height = img->getHeight();
662 UInt32 depth = img->getDepth();
663 bool compressedData = img->hasCompressedData();
665 #ifndef OSG_OGL_ES2
666 bool doScale = getScale(); // scale the texture to 2^?
667 #endif
668 UInt32 frame = getFrame();
670 bool defined = false; // Texture defined ?
671 bool needMipmaps = getMinFilter() == GL_NEAREST_MIPMAP_NEAREST ||
672 getMinFilter() == GL_LINEAR_MIPMAP_NEAREST ||
673 getMinFilter() == GL_NEAREST_MIPMAP_LINEAR ||
674 getMinFilter() == GL_LINEAR_MIPMAP_LINEAR ;
676 determineFormats(internalFormat, externalFormat);
678 if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && needMipmaps)
680 SWARNING << "TextureObjChunk::initialize1: Can't do mipmaps"
681 << "with GL_TEXTURE_RECTANGLE_ARB target! Ignored"
682 << std::endl;
683 needMipmaps= false;
686 // do we need mipmaps?
687 if(needMipmaps)
689 // do we have usable mipmaps ?
690 if(img->getMipMapCount() == Int32(img->calcMipmapLevelCount()) &&
691 osgIsPower2(width) && osgIsPower2(height) &&
692 osgIsPower2(depth)
695 UInt16 baseLevel = 0;
696 Real32 skipLevels = osgClamp(0.f, getSkipMipMapLevels(), 1.f);
698 if(img->getMipMapCount() != 0)
700 baseLevel =
701 UInt16(skipLevels * (img->getMipMapCount() - 1));
704 for(UInt16 i = baseLevel; i < img->getMipMapCount(); i++)
706 UInt32 w, h, d;
707 img->calcMipmapGeometry(i, w, h, d);
709 if(compressedData)
711 switch (imgtarget)
713 #ifndef OSG_OGL_ES2
714 case GL_TEXTURE_1D:
715 osgGlCompressedTexImage1D(
716 GL_TEXTURE_1D,
717 i - baseLevel,
718 internalFormat,
720 getBorderWidth(),
721 img->calcMipmapLevelSize(i),
722 img->getData(i, frame, side));
723 break;
724 #endif
725 case GL_TEXTURE_2D:
726 case GL_TEXTURE_1D_ARRAY:
727 osgGlCompressedTexImage2D(
728 imgtarget,
729 i - baseLevel,
730 internalFormat,
733 getBorderWidth(),
734 img->calcMipmapLevelSize(i),
735 img->getData(i, frame, side));
736 break;
737 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
738 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
739 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
740 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
741 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
742 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
743 osgGlCompressedTexImage2D(
744 imgtarget,
745 i - baseLevel,
746 internalFormat,
749 getBorderWidth(),
750 img->calcMipmapLevelSize(i),
751 img->getData(i, frame, side));
752 break;
753 case GL_TEXTURE_3D:
754 case GL_TEXTURE_2D_ARRAY:
755 case GL_TEXTURE_CUBE_MAP_ARRAY:
756 osgGlCompressedTexImage3D(
757 imgtarget,
758 i - baseLevel,
759 internalFormat,
763 getBorderWidth(),
764 img->calcMipmapLevelSize(i),
765 img->getData(i, frame, side));
766 break;
767 default:
768 SFATAL << "TextureObjChunk::initialize1: "
769 << "unknown target "
770 << imgtarget << "!!!" << std::endl;
771 break;
774 else
776 switch (imgtarget)
778 #ifndef OSG_OGL_ES2
779 case GL_TEXTURE_1D:
780 glTexImage1D(GL_TEXTURE_1D,
781 i - baseLevel,
782 internalFormat,
784 getBorderWidth(),
785 externalFormat,
786 type,
787 img->getData(i, frame, side));
788 break;
789 #endif
790 case GL_TEXTURE_2D:
791 case GL_TEXTURE_1D_ARRAY:
792 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
793 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
794 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
795 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
796 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
797 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
798 glTexImage2D(imgtarget,
799 i - baseLevel,
800 internalFormat,
803 getBorderWidth(),
804 externalFormat,
805 type,
806 img->getData(i, frame, side));
807 break;
808 case GL_TEXTURE_3D:
809 case GL_TEXTURE_2D_ARRAY:
810 case GL_TEXTURE_CUBE_MAP_ARRAY:
811 osgGlTexImage3D(imgtarget,
812 i - baseLevel,
813 internalFormat,
817 getBorderWidth(),
818 externalFormat,
819 type,
820 img->getData(i, frame, side));
821 break;
822 default:
823 SFATAL << "TextureObjChunk::initialize1: "
824 << "unknown target "
825 << imgtarget << "!!!" << std::endl;
826 break;
830 defined = true;
833 if(! defined)
835 // Nope, do we have SGIS_generate_mipmaps?
836 if(win->hasExtOrVersion(_sgisGenerateMipmap, 0x0104))
838 if(paramtarget != GL_NONE)
840 glTexParameteri(paramtarget,
841 GL_GENERATE_MIPMAP_SGIS,
842 GL_TRUE);
845 // same as GL_GENERATE_MIPMAP which is part of the
846 // standard since 1.4
848 glErr("TextureObjChunk::activate generate_mipmaps");
849 needMipmaps = false; // automagic does it
851 else
853 // Nope, try to use gluBuild?DMipmaps
854 void *data = NULL;
856 // can we use it directly?
857 if(! osgIsPower2(width) ||
858 ! osgIsPower2(height) ||
859 ! osgIsPower2(depth)
862 // scale is only implemented for 2D
863 if(imgtarget != GL_TEXTURE_2D)
865 SWARNING << "TextureObjChunk::initialize: can't "
866 << "mipmap non-2D textures that are "
867 << "not 2^x !!!"
868 << std::endl;
870 else
872 UInt32 outw = osgNextPower2(width);
873 UInt32 outh = osgNextPower2(height);
875 data = malloc(outw * outh * img->getBpp());
877 #ifndef OSG_OGL_ES2
878 // should we scale to next power of 2?
879 if(doScale)
881 GLint res = gluScaleImage(externalFormat,
882 width,
883 height,
884 type,
885 img->getData(0,
886 frame,
887 side),
888 outw,
889 outh,
890 type,
891 data);
893 if(res)
895 SWARNING << "TextureObjChunk::initialize: "
896 << "gluScaleImage failed: "
897 << gluErrorString(res) << "("
898 << res << ")!"
899 << std::endl;
900 free(data);
901 data = NULL;
903 else
905 width = outw;
906 height = outh;
909 // nope, just copy the image to the lower left part
910 else
911 #endif
913 memset(data, 0, outw * outh * img->getBpp());
915 UInt16 bpl = width * img->getBpp();
917 const UInt8 * src = img->getData(0,
918 frame,
919 side);
921 UInt8 * dest= static_cast<UInt8 *>(data);
923 for(UInt32 y = 0; y < height; y++)
925 memcpy(dest, src, bpl);
927 src += bpl;
928 dest += outw * img->getBpp();
930 width = outw;
931 height = outh;
935 else
937 data = const_cast<void *>(
938 static_cast<const void *>(img->getData(0,
939 frame,
940 side)));
943 if(data)
945 switch (imgtarget)
947 #ifndef OSG_OGL_ES2
948 case GL_TEXTURE_1D:
949 gluBuild1DMipmaps(imgtarget,
950 internalFormat,
951 width,
952 externalFormat,
953 type,
954 data);
955 break;
956 case GL_TEXTURE_2D:
957 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
958 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
959 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
960 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
961 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
962 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
963 gluBuild2DMipmaps(imgtarget, internalFormat,
964 width, height,
965 externalFormat, type, data);
966 break;
967 #endif
968 case GL_TEXTURE_3D:
969 # ifdef GLU_VERSION_1_3
970 gluBuild3DMipmaps(imgtarget, internalFormat,
971 width, height, depth,
972 externalFormat, type, data);
973 # else
974 FWARNING(("TextureObjChunk::initialize: 3d "
975 "textures supported, but GLU version "
976 "< 1.3, thus gluBuild3DMipmaps not "
977 "supported!\n"));
978 # endif
979 break;
980 default:
981 SFATAL << "TextureObjChunk::initialize2: "
982 << "unknown target "
983 << imgtarget << "!!!" << std::endl;
986 if(data != img->getData(0, frame, side))
987 free(data);
988 defined = true;
989 } // data
990 } // need to use gluBuildMipmaps?
991 } // got them from the image already?
992 } // need mipmaps?
994 // no mipmaps, or mipmapping failed?
995 if(! defined)
997 // got here needing mipmaps?
998 if(needMipmaps && paramtarget != GL_NONE) // turn them off
999 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1001 void * data = NULL;
1002 UInt32 datasize = 0;
1004 // Do we need to massage the texture or can we just use it?
1005 if(imgtarget != GL_TEXTURE_RECTANGLE_ARB &&
1006 !win->hasExtOrVersion(_arbTextureNonPowerOfTwo,
1007 0x0200, 0x0200 ) &&
1008 (!osgIsPower2(width) || !osgIsPower2(height) ||
1009 !osgIsPower2(depth)))
1011 // No, need to scale or cut
1013 #ifndef OSG_OGL_ES2
1014 // should we scale to next power of 2?
1015 if(doScale)
1017 // scale is only implemented for 2D
1018 if(imgtarget != GL_TEXTURE_2D &&
1019 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1020 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
1021 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
1022 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
1023 imgtarget != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
1024 imgtarget != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
1027 SWARNING << "TextureObjChunk::initialize: can't scale "
1028 << "non-2D textures that are not 2^x !!!"
1029 << std::endl;
1031 else
1033 UInt32 outw = osgNextPower2(width);
1034 UInt32 outh = osgNextPower2(height);
1036 data = malloc(outw * outh * img->getBpp());
1037 datasize = outw * outh * img->getBpp();
1039 GLint res = gluScaleImage(externalFormat,
1040 width, height, type,
1041 img->getData(0, frame, side),
1042 outw, outh, type, data);
1044 if(res)
1046 SWARNING << "TextureObjChunk::initialize: "
1047 << "gluScaleImage failed: "
1048 << gluErrorString(res) << "("
1049 << res << ")!" << std::endl;
1050 free(data);
1051 data = NULL;
1053 else
1055 width = outw;
1056 height = outh;
1060 else // don't scale, just use ll corner
1061 #endif
1063 if(compressedData)
1065 switch (imgtarget)
1067 #ifndef OSG_OGL_ES2
1068 case GL_TEXTURE_1D:
1069 osgGlCompressedTexImage1D(GL_TEXTURE_1D, 0,
1070 internalFormat,
1071 osgNextPower2(width),
1072 getBorderWidth(),
1073 0, NULL);
1074 osgGlCompressedTexSubImage1D(GL_TEXTURE_1D,
1075 0, 0, width,
1076 externalFormat,
1077 img->getFrameSize(),
1078 img->getData(0,
1079 frame,
1080 side));
1081 break;
1082 #endif
1083 case GL_TEXTURE_2D:
1084 case GL_TEXTURE_1D_ARRAY:
1085 osgGlCompressedTexImage2D(imgtarget, 0,
1086 internalFormat,
1087 osgNextPower2(width),
1088 osgNextPower2(height),
1089 getBorderWidth(),
1090 0, NULL);
1091 osgGlCompressedTexSubImage2D(imgtarget, 0, 0, 0,
1092 width, height,
1093 externalFormat,
1094 img->getFrameSize(),
1095 img->getData(0,
1096 frame,
1097 side));
1098 break;
1099 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1100 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1101 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1102 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1103 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1104 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1105 osgGlCompressedTexImage2D(imgtarget, 0,
1106 internalFormat,
1107 osgNextPower2(width),
1108 osgNextPower2(height),
1109 getBorderWidth(),
1110 0, NULL);
1111 osgGlCompressedTexSubImage2D(imgtarget, 0, 0, 0,
1112 width, height,
1113 externalFormat,
1114 (img->getSideCount() > 1) ? img->getSideSize() :
1115 img->getFrameSize(),
1116 img->getData(0,
1117 frame,
1118 side));
1119 break;
1120 case GL_TEXTURE_RECTANGLE_ARB:
1121 osgGlCompressedTexImage2D(
1122 GL_TEXTURE_RECTANGLE_ARB,
1123 0, internalFormat,
1124 width, height,
1125 getBorderWidth(),
1126 img->getFrameSize(),
1127 img->getData(0,
1128 frame,
1129 side));
1130 break;
1131 case GL_TEXTURE_3D:
1132 case GL_TEXTURE_2D_ARRAY:
1133 case GL_TEXTURE_CUBE_MAP_ARRAY:
1134 osgGlCompressedTexImage3D(imgtarget, 0,
1135 internalFormat,
1136 osgNextPower2(width),
1137 osgNextPower2(height),
1138 osgNextPower2(depth),
1139 getBorderWidth(), 0,
1140 NULL);
1141 osgGlCompressedTexSubImage3D(imgtarget,
1142 0, 0, 0,
1144 width, height,
1145 depth,
1146 externalFormat,
1147 img->getFrameSize(),
1148 img->getData(0,
1149 frame,
1150 side));
1151 break;
1152 default:
1153 SFATAL << "TextureObjChunk::initialize4: "
1154 << "unknown target "
1155 << imgtarget << "!!!" << std::endl;
1158 else
1160 switch (imgtarget)
1162 #ifndef OSG_OGL_ES2
1163 case GL_TEXTURE_1D:
1164 glTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
1165 osgNextPower2(width),
1166 getBorderWidth(),
1167 externalFormat, type,
1168 NULL);
1169 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, width,
1170 externalFormat, type,
1171 img->getData(0, frame, side));
1172 break;
1173 #endif
1174 case GL_TEXTURE_2D:
1175 case GL_TEXTURE_1D_ARRAY:
1176 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1177 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1178 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1179 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1180 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1181 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1182 glTexImage2D(imgtarget, 0, internalFormat,
1183 osgNextPower2(width),
1184 osgNextPower2(height),
1185 getBorderWidth(),
1186 externalFormat, type,
1187 NULL);
1188 glTexSubImage2D(imgtarget, 0, 0, 0, width,
1189 height,
1190 externalFormat, type,
1191 img->getData(0, frame, side));
1192 break;
1193 case GL_TEXTURE_RECTANGLE_ARB:
1194 glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
1195 internalFormat,
1196 width, height, getBorderWidth(),
1197 externalFormat, type,
1198 img->getData(0, frame, side));
1199 break;
1200 case GL_TEXTURE_3D:
1201 case GL_TEXTURE_2D_ARRAY:
1202 case GL_TEXTURE_CUBE_MAP_ARRAY:
1203 osgGlTexImage3D(imgtarget,
1205 internalFormat,
1206 osgNextPower2(width),
1207 osgNextPower2(height),
1208 osgNextPower2(depth),
1209 getBorderWidth(),
1210 externalFormat, type, NULL);
1211 osgGlTexSubImage3D(imgtarget, 0, 0, 0, 0,
1212 width, height, depth,
1213 externalFormat, type,
1214 img->getData(0, frame, side));
1215 break;
1216 default:
1217 SFATAL << "TextureObjChunk::initialize4: "
1218 << "unknown target "
1219 << imgtarget << "!!!" << std::endl;
1220 } // switch imgtarget
1221 } // compressed data?
1223 defined = true;
1224 } // do scale
1226 else // can we use it directly?
1228 data = const_cast<void *>(
1229 static_cast<const void *>(img->getData(0,
1230 frame,
1231 side)));
1233 datasize = (img->getSideCount() > 1) ? img->getSideSize() :
1234 img->getFrameSize();
1235 } // can we use it directly?
1237 // either we can use the texture directly, or it was scaled
1238 if(!defined)
1240 // A image without data is quite handy if you need the
1241 // texture only on the graphics card. So don't check for data
1242 // here
1244 if(compressedData)
1246 switch (imgtarget)
1248 #ifndef OSG_OGL_ES2
1249 case GL_TEXTURE_1D:
1250 osgGlCompressedTexImage1D(GL_TEXTURE_1D, 0,
1251 internalFormat,
1252 width, getBorderWidth(),
1253 datasize, data);
1254 break;
1255 #endif
1256 case GL_TEXTURE_2D:
1257 case GL_TEXTURE_1D_ARRAY:
1258 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1259 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1260 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1261 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1262 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1263 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1264 osgGlCompressedTexImage2D(imgtarget,
1265 0, internalFormat,
1266 width, height,
1267 getBorderWidth(),
1268 datasize, data);
1269 break;
1270 case GL_TEXTURE_RECTANGLE_ARB:
1271 osgGlCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
1273 internalFormat,
1274 width, height,
1275 getBorderWidth(),
1276 datasize, data);
1277 break;
1278 case GL_TEXTURE_3D:
1279 case GL_TEXTURE_2D_ARRAY:
1280 case GL_TEXTURE_CUBE_MAP_ARRAY:
1281 osgGlCompressedTexImage3D(imgtarget, 0,
1282 internalFormat,
1283 width, height, depth,
1284 getBorderWidth(),
1285 datasize, data);
1286 break;
1287 default:
1288 SFATAL << "TextureObjChunk::initialize3: "
1289 << "unknown target "
1290 << imgtarget << "!!!" << std::endl;
1293 else
1295 switch (imgtarget)
1297 #ifndef OSG_OGL_ES2
1298 case GL_TEXTURE_1D:
1299 glTexImage1D(GL_TEXTURE_1D, 0, internalFormat,
1300 width, getBorderWidth(),
1301 externalFormat, type,
1302 data);
1303 break;
1304 #endif
1305 case GL_TEXTURE_2D:
1306 case GL_TEXTURE_1D_ARRAY:
1307 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1308 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1309 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1310 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1311 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1312 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1313 glTexImage2D(imgtarget, 0, internalFormat,
1314 width, height, getBorderWidth(),
1315 externalFormat, type,
1316 data);
1317 break;
1318 case GL_TEXTURE_RECTANGLE_ARB:
1319 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
1320 internalFormat,
1321 width, height, getBorderWidth(),
1322 externalFormat, type,
1323 data);
1324 break;
1325 case GL_TEXTURE_3D:
1326 case GL_TEXTURE_2D_ARRAY:
1327 case GL_TEXTURE_CUBE_MAP_ARRAY:
1328 osgGlTexImage3D(imgtarget, 0, internalFormat,
1329 width, height, depth,
1330 getBorderWidth(),
1331 externalFormat, type,
1332 data);
1333 break;
1334 default:
1335 SFATAL << "TextureObjChunk::initialize3: "
1336 << "unknown target "
1337 << imgtarget << "!!!" << std::endl;
1342 if(data != img->getData(0, frame, side))
1343 free(data);
1346 glErr("TextureObjChunk::initialize image");
1348 // unbind texture
1349 glBindTexture(bindtarget, 0);
1351 // Clear image data after upload to the graphics card.
1352 if (img->getClearOnLoad())
1354 img->clearData();
1357 else if(mode == Window::needrefresh)
1359 // 3D texture functions
1360 OSGGETGLFUNCBYID_GL3( glTexSubImage3D,
1361 osgGlTexSubImage3D,
1362 _funcTexSubImage3D,
1363 win);
1365 #ifndef OSG_OGL_ES2
1366 // Compressed texture functions
1367 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage1D,
1368 osgGlCompressedTexSubImage1D,
1369 _funcCompressedTexSubImage1D,
1370 win);
1371 #endif
1372 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexSubImage2D,
1373 osgGlCompressedTexSubImage2D,
1374 _funcCompressedTexSubImage2D,
1375 win);
1376 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage3D,
1377 osgGlCompressedTexSubImage3D,
1378 _funcCompressedTexSubImage3D,
1379 win);
1381 GLenum externalFormat = img->getPixelFormat();
1382 GLenum type = img->getDataType();
1383 bool compressedData = img->hasCompressedData();
1384 bool has3DTex = win->hasExtOrVersion(_extTex3D, 0x0102);
1386 if(bindtarget == GL_TEXTURE_3D && !has3DTex)
1388 FINFO(("3D textures not supported on Window %p!\n",
1389 static_cast<void *>(win)));
1390 return;
1393 if(! img) // no image ?
1394 return;
1396 if(getExternalFormat() != GL_NONE)
1397 externalFormat = getExternalFormat();
1399 if(!getScale() || imgtarget == GL_TEXTURE_RECTANGLE_ARB
1400 || win->hasExtOrVersion(_arbTextureNonPowerOfTwo, 0x0200, 0x0200)
1401 || (osgIsPower2(img->getWidth() ) &&
1402 osgIsPower2(img->getHeight()) &&
1403 osgIsPower2(img->getDepth() )
1406 // activate the texture
1407 glBindTexture(bindtarget, id);
1409 // Find out what to update
1410 UInt32 ix, ax, iy, ay, iz, az;
1411 ix = (getDirtyMinX()!=-1) ? getDirtyMinX() : 0;
1412 ax = (getDirtyMaxX()!=-1) ? getDirtyMaxX() : img->getWidth() - 1;
1413 iy = (getDirtyMinY()!=-1) ? getDirtyMinY() : 0;
1414 ay = (getDirtyMaxY()!=-1) ? getDirtyMaxY() : img->getHeight() - 1;
1415 iz = (getDirtyMinZ()!=-1) ? getDirtyMinZ() : 0;
1416 az = (getDirtyMaxZ()!=-1) ? getDirtyMaxZ() : img->getDepth() - 1;
1418 UInt32 w, h, d;
1419 w = ax - ix + 1;
1420 h = ay - iy + 1;
1421 d = az - iz + 1;
1423 #ifndef OSG_OGL_ES2
1424 if(w != UInt32(img->getWidth()))
1425 glPixelStorei(GL_UNPACK_ROW_LENGTH, img->getWidth());
1426 if(ix != 0)
1427 glPixelStorei(GL_UNPACK_SKIP_PIXELS, ix);
1428 if(iy != 0)
1429 glPixelStorei(GL_UNPACK_SKIP_ROWS, iy);
1430 if(has3DTex && iz != 0)
1431 glPixelStorei(GL_UNPACK_SKIP_IMAGES, iz);
1432 #endif
1434 if(compressedData)
1436 switch (imgtarget)
1438 #ifndef OSG_OGL_ES2
1439 case GL_TEXTURE_1D:
1440 osgGlCompressedTexSubImage1D(GL_TEXTURE_1D, 0, ix, w,
1441 externalFormat,
1442 img->getFrameSize(),
1443 img->getData( 0,
1444 getFrame(),
1445 side ) );
1446 break;
1447 #endif
1448 case GL_TEXTURE_2D:
1449 case GL_TEXTURE_1D_ARRAY:
1450 osgGlCompressedTexSubImage2D(imgtarget, 0, ix, iy, w, h,
1451 externalFormat,
1452 img->getFrameSize(),
1453 img->getData( 0,
1454 getFrame(),
1455 side ) );
1456 break;
1457 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1458 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1459 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1460 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1461 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1462 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1463 osgGlCompressedTexSubImage2D(imgtarget, 0, ix, iy, w, h,
1464 externalFormat,
1465 (img->getSideCount() > 1) ? img->getSideSize() :
1466 img->getFrameSize(),
1467 img->getData( 0,
1468 getFrame(),
1469 side ) );
1470 break;
1471 case GL_TEXTURE_RECTANGLE_ARB:
1472 osgGlCompressedTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB,
1474 ix, iy, w, h,
1475 externalFormat,
1476 img->getFrameSize(),
1477 img->getData( 0,
1478 getFrame(),
1479 side ) );
1480 break;
1481 case GL_TEXTURE_3D:
1482 case GL_TEXTURE_2D_ARRAY:
1483 case GL_TEXTURE_CUBE_MAP_ARRAY:
1484 osgGlCompressedTexSubImage3D(imgtarget, 0,
1485 ix, iy, iz,
1486 w, h, d,
1487 externalFormat,
1488 img->getFrameSize(),
1489 img->getData( 0,
1490 getFrame(),
1491 side ) );
1492 break;
1493 default:
1494 SFATAL << "TextureObjChunk::refresh: unknown target "
1495 << imgtarget << "!!!" << std::endl;
1498 else
1500 switch (imgtarget)
1502 #ifndef OSG_OGL_ES2
1503 case GL_TEXTURE_1D:
1504 glTexSubImage1D(GL_TEXTURE_1D, 0, ix, w,
1505 externalFormat, type,
1506 img->getData( 0, getFrame(), side ) );
1507 break;
1508 #endif
1509 case GL_TEXTURE_2D:
1510 case GL_TEXTURE_1D_ARRAY:
1511 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1512 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1513 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1514 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1515 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1516 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1517 glTexSubImage2D(imgtarget, 0, ix, iy, w, h,
1518 externalFormat, type,
1519 img->getData( 0, getFrame(), side ) );
1520 break;
1521 case GL_TEXTURE_RECTANGLE_ARB:
1522 glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
1523 ix, iy, w, h,
1524 externalFormat, type,
1525 img->getData( 0, getFrame(), side ) );
1526 break;
1527 case GL_TEXTURE_3D:
1528 case GL_TEXTURE_2D_ARRAY:
1529 case GL_TEXTURE_CUBE_MAP_ARRAY:
1530 osgGlTexSubImage3D(imgtarget, 0, ix, iy, iz,
1531 w, h, d,
1532 externalFormat, type,
1533 img->getData(0, getFrame(), side));
1534 break;
1535 default:
1536 SFATAL << "TextureObjChunk::refresh: unknown target "
1537 << imgtarget << "!!!" << std::endl;
1542 #ifndef OSG_OGL_ES2
1543 if(w != UInt32(img->getWidth()))
1544 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1545 if(ix != 0)
1546 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1547 if(iy != 0)
1548 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1549 if(has3DTex && iz != 0)
1550 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
1551 #endif
1553 if(paramtarget != GL_NONE)
1555 #if !defined(OSG_OGL_COREONLY) && !defined(OSG_OGL_ES2)
1556 glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY,
1557 getPriority());
1558 #endif
1559 glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER,
1560 getMinFilter() );
1561 glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER,
1562 getMagFilter() );
1565 // unbind the texture
1566 glBindTexture(bindtarget, 0);
1568 else
1570 SWARNING << "TextureObjChunk::refresh: not implemented yet for "
1571 << "scaling!!!" << std::endl;
1574 glErr("TextureObjChunk::refresh image");
1580 /*! GL object handler
1581 create the texture and destroy it
1583 UInt32 TextureObjChunk::handleGL(DrawEnv *pEnv,
1584 UInt32 osgid,
1585 Window::GLObjectStatusE mode,
1586 UInt64 uiOptions)
1588 Window *win = pEnv->getWindow();
1589 GLuint id = win->getGLObjectId(osgid);
1591 if(mode == Window::initialize || mode == Window::reinitialize ||
1592 mode == Window::needrefresh )
1594 if(mode == Window::initialize)
1596 glGenTextures(1, &id);
1597 win->setGLObjectId(osgid, id);
1600 GLenum target;
1602 Image *img = getImage();
1604 if (img != NULL)
1606 if(img->getSideCount() == 1)
1608 target = getTarget();
1609 if ( target == GL_NONE )
1611 if(img->getDepth() > 1)
1613 if(win->hasExtOrVersion(_extTex3D, 0x0102))
1615 target = GL_TEXTURE_3D;
1617 else
1619 FWARNING(
1620 ("TextureObjChunk::initialize: 3D textures not "
1621 "supported for this window!\n"));
1622 return 0;
1625 else if(img->getHeight() > 1)
1627 target = GL_TEXTURE_2D;
1629 else
1631 #ifndef OSG_OGL_ES2
1632 target = GL_TEXTURE_1D;
1633 #endif
1637 handleTexture(win, id, target, target, target, mode, img);
1639 else
1641 handleTexture(win, id,
1642 GL_TEXTURE_CUBE_MAP_ARB,
1643 GL_TEXTURE_CUBE_MAP_ARB,
1644 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
1645 mode, getImage(), 5);
1646 // Have to use initialize mode here, otherwise the
1647 // texture is destroyed for every side
1648 handleTexture(win, id,
1649 GL_TEXTURE_CUBE_MAP_ARB,
1650 GL_NONE,
1651 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
1652 Window::initialize, getImage(), 4);
1653 handleTexture(win, id,
1654 GL_TEXTURE_CUBE_MAP_ARB,
1655 GL_NONE,
1656 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
1657 Window::initialize, getImage(), 3);
1658 handleTexture(win, id,
1659 GL_TEXTURE_CUBE_MAP_ARB,
1660 GL_NONE,
1661 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
1662 Window::initialize, getImage(), 2);
1663 handleTexture(win, id,
1664 GL_TEXTURE_CUBE_MAP_ARB,
1665 GL_NONE,
1666 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
1667 Window::initialize, getImage(), 1);
1668 handleTexture(win, id,
1669 GL_TEXTURE_CUBE_MAP_ARB,
1670 GL_NONE,
1671 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
1672 Window::initialize, getImage(), 0);
1676 else
1678 SWARNING << "TextureObjChunk(" << this << ")::handleGL: No image."
1679 << std::endl;
1682 else
1684 SWARNING << "TextureObjChunk(" << this << "::handleGL: Illegal mode: "
1685 << mode << " for id " << id << std::endl;
1688 return 0;
1691 /*! GL object handler
1692 destroy it
1694 void TextureObjChunk::handleDestroyGL(DrawEnv *pEnv,
1695 UInt32 osgid,
1696 Window::GLObjectStatusE mode)
1698 Window *win = pEnv->getWindow();
1699 GLuint id = win->getGLObjectId(osgid);
1701 if(mode == Window::destroy)
1703 glDeleteTextures(1, &id);
1704 win->setGLObjectId(osgid, 0);
1706 else if(mode == Window::finaldestroy)
1708 //SWARNING << "Last texture user destroyed" << std::endl;
1710 else
1712 SWARNING << "TextureObjChunk::handleDestroyGL: Illegal mode: "
1713 << mode << " for id " << id << std::endl;
1718 void TextureObjChunk::activate(DrawEnv *pEnv, UInt32 idx)
1720 #ifdef OSG_DUMP_TEX
1721 fprintf(stderr, "Activate %d\n", _uiChunkId);
1722 #endif
1724 Window *win = pEnv->getWindow();
1726 Real32 nteximages; //, ntexcoords;
1728 if((nteximages = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
1729 Window::unknownConstant)
1731 nteximages = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
1733 // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
1734 if(nteximages == Window::unknownConstant)
1735 nteximages = 1.0f;
1738 #if 0
1739 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
1740 Window::unknownConstant)
1742 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
1744 // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
1745 if(ntexcoords == Window::unknownConstant)
1746 ntexcoords = 1.0f;
1748 #endif
1750 if(idx >= static_cast<UInt32>(nteximages))
1752 #ifdef OSG_DEBUG
1753 FWARNING(("TextureObjChunk::activate: Trying to bind image unit %d,"
1754 " but Window %p only supports %lf!\n",
1755 idx, static_cast<void *>(win), nteximages));
1756 #endif
1757 return;
1760 if(activateTexture(win, idx))
1761 return; // trying to access too many textures
1763 win->validateGLObject(getGLId(), pEnv);
1765 Image *img = getImage();
1766 GLenum target = getTarget();
1768 if(img == NULL || ! img->getDimension()) // no image ?
1769 return;
1771 glErr("TextureObjChunk::activate precheck");
1773 if(img->getSideCount() == 1)
1775 if(target == GL_NONE)
1777 if(img->getDepth() > 1)
1779 if(win->hasExtOrVersion(_extTex3D, 0x0102))
1781 target = GL_TEXTURE_3D;
1783 else
1785 FWARNING(("TextureObjChunk::activate: 3D textures not "
1786 "supported for this window!\n"));
1787 return;
1790 else if(img->getHeight() > 1)
1792 target = GL_TEXTURE_2D;
1794 else
1796 #ifndef OSG_OGL_ES2
1797 target = GL_TEXTURE_1D;
1798 #endif
1802 else
1804 target = GL_TEXTURE_CUBE_MAP_ARB;
1807 #ifdef OSG_DUMP_TEX
1808 FDEBUG(("TextureObjChunk::activate - %d\n", getGLId()));
1809 #endif
1811 // Update the texture statistics
1812 StatCollectorP pColl = pEnv->getStatCollector();
1814 if(NULL != pColl)
1816 pColl->getElem(statNTextures)->inc(getGLId());
1817 pColl->getElem(statNTexBytes)->add(getGLId(),
1818 img->getSize(true,true,true));
1820 pEnv->incNumChunkChanges();
1823 glBindTexture(target, win->getGLObjectId(getGLId()));
1825 pEnv->setActiveTexTarget(idx, target);
1827 Real32 ntexunits = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
1829 // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
1830 if(ntexunits == Window::unknownConstant)
1831 ntexunits = 1.0f;
1833 if(idx < static_cast<UInt32>(ntexunits))
1835 glEnable(target);
1838 glErr("TextureObjChunk::activate");
1842 void TextureObjChunk::changeFrom(DrawEnv *pEnv,
1843 StateChunk *old ,
1844 UInt32 idx )
1846 // change from me to me?
1847 // this assumes I haven't changed in the meantime.
1848 // is that a valid assumption?
1849 if(old == this)
1850 return;
1852 // If the old one is not a texture chunk, deactivate it and activate
1853 // ourselves
1854 // Need to check for exact type, as derived chunks might change
1855 // different state (e.g. CubeTexture)
1856 if(getTypeId() != old->getTypeId())
1858 old->deactivate(pEnv, idx);
1859 activate(pEnv, idx);
1860 return;
1863 TextureObjChunk *oldp = dynamic_cast<TextureObjChunk *>(old);
1865 #ifdef OSG_DUMP_TEX
1866 fprintf(stderr, "Change %d %d\n", oldp->_uiChunkId, _uiChunkId);
1867 #endif
1869 Image *img = getImage();
1870 GLenum target = getTarget();
1871 GLenum oldtarget = oldp->getTarget();
1872 bool oldused = (oldp->getImage() != NULL &&
1873 oldp->getImage()->getDimension());
1875 if(img == NULL || img->getDimension() == 0)
1877 oldp->deactivate(pEnv, idx);
1878 return;
1881 glErr("TextureObjChunk::changeFrom precheck");
1883 Window *win = pEnv->getWindow();
1885 if(activateTexture(win, idx))
1886 return; // trying to use too many textures
1888 UInt32 nteximages, ntexunits; //, ntexcoords
1890 Real32 dummy = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
1892 if(dummy == Window::unknownConstant)
1894 ntexunits = 1;
1896 else
1898 ntexunits = static_cast<UInt32>(dummy);
1901 if((dummy = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
1902 Window::unknownConstant
1905 nteximages = ntexunits;
1907 else
1909 nteximages = static_cast<UInt32>(dummy);
1912 #if 0
1913 if((dummy = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
1914 Window::unknownConstant
1917 ntexcoords = ntexunits;
1919 else
1921 ntexcoords = static_cast<UInt32>(dummy);
1923 #endif
1925 if(idx >= nteximages)
1927 #ifdef OSG_DEBUG
1928 FWARNING(("TextureObjChunk::activate: Trying to bind image unit %d,"
1929 " but Window %p only supports %d!\n",
1930 idx, static_cast<void *>(win), nteximages));
1931 #endif
1932 return;
1935 if(img->getSideCount() == 1)
1937 if(target == GL_NONE)
1939 if(img->getDepth() > 1)
1941 if(win->hasExtOrVersion(_extTex3D, 0x0102))
1943 target = GL_TEXTURE_3D;
1945 else
1947 FWARNING(("TextureObjChunk::changeFrom: 3D textures not "
1948 "supported for this window!\n"));
1949 oldp->deactivate(pEnv, idx);
1950 return;
1953 else if(img->getHeight() > 1)
1954 target = GL_TEXTURE_2D;
1955 #ifndef OSG_OGL_ES2
1956 else
1957 target = GL_TEXTURE_1D;
1958 #endif
1961 else
1963 target = GL_TEXTURE_CUBE_MAP_ARB;
1966 if(oldused)
1968 if(oldp->getImage()->getSideCount() == 1)
1970 if(oldtarget == GL_NONE)
1972 if(oldp->getImage()->getDepth() > 1)
1974 if(win->hasExtOrVersion(_extTex3D, 0x0102))
1976 oldtarget = GL_TEXTURE_3D;
1978 else
1980 FWARNING(("TextureObjChunk::changeFrom: 3D textures "
1981 "not supported for this window!\n"));
1982 oldp->deactivate(pEnv, idx);
1983 return;
1986 else if(oldp->getImage()->getHeight() > 1)
1988 oldtarget = GL_TEXTURE_2D;
1990 else
1992 #ifndef OSG_OGL_ES2
1993 oldtarget = GL_TEXTURE_1D;
1994 #endif
1998 else
2000 oldtarget = GL_TEXTURE_CUBE_MAP_ARB;
2003 if(target != oldtarget && idx < ntexunits)
2005 glDisable(oldtarget);
2009 win->validateGLObject(getGLId(), pEnv);
2012 // Update the texture statistics
2013 StatCollectorP pColl = pEnv->getStatCollector();
2015 if(NULL != pColl)
2017 pColl->getElem(statNTextures)->inc(getGLId());
2018 pColl->getElem(statNTexBytes)->add(getGLId(),
2019 img->getSize(true,true,true));
2023 glBindTexture(target, win->getGLObjectId(getGLId()));
2025 pEnv->setActiveTexTarget(idx, GL_TEXTURE_CUBE_MAP_ARB);
2028 if(idx < ntexunits)
2030 if(target != oldtarget)
2032 glEnable(target);
2036 glErr("TextureObjChunk::changeFrom");
2039 void TextureObjChunk::deactivate(DrawEnv *pEnv, UInt32 idx)
2041 #ifdef OSG_DUMP_TEX
2042 fprintf(stderr, "Deactivate %d\n", _uiChunkId);
2043 #endif
2045 Window *win = pEnv->getWindow();
2047 Real32 nteximages; //, ntexcoords;
2048 if((nteximages = win->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB)) ==
2049 Window::unknownConstant
2052 nteximages = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
2054 // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
2055 if(nteximages == Window::unknownConstant)
2056 nteximages = 1.0f;
2059 #if 0
2060 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
2061 Window::unknownConstant
2064 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
2066 // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
2067 if(ntexcoords == Window::unknownConstant)
2068 ntexcoords = 1.0f;
2070 #endif
2072 if(idx >= static_cast<UInt32>(nteximages))
2074 #ifdef OSG_DEBUG
2075 FWARNING(("TextureObjChunk::deactivate: Trying to bind image unit %d,"
2076 " but Window %p only supports %lf!\n",
2077 idx, static_cast<void *>(win), nteximages));
2078 #endif
2079 return;
2082 Image *img = getImage();
2083 GLenum target = getTarget();
2085 if(img == NULL || ! img->getDimension())
2086 return;
2088 glErr("TextureObjChunk::deactivate precheck");
2090 bool isActive = false;
2093 Real32 ntexunits = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
2095 if(ntexunits == Window::unknownConstant)
2096 ntexunits = 1.0f;
2098 if(idx >= static_cast<UInt32>(ntexunits))
2099 return; // textures >= MTU are not enabled and don't have an env
2101 if(!isActive)
2102 activateTexture(win, idx);
2104 if(img->getSideCount() == 1)
2106 if ( target == GL_NONE )
2108 if ( img->getDepth() > 1 )
2110 if(win->hasExtOrVersion(_extTex3D, 0x0102))
2112 target = GL_TEXTURE_3D;
2114 else
2116 FWARNING(("TextureObjChunk::deactivate: 3D textures not "
2117 "supported for this window!\n"));
2118 return;
2121 else if(img->getHeight() > 1)
2122 target = GL_TEXTURE_2D;
2123 #ifndef OSG_OGL_ES2
2124 else
2125 target = GL_TEXTURE_1D;
2126 #endif
2129 else
2131 target = GL_TEXTURE_CUBE_MAP_ARB;
2134 glDisable(target);
2136 pEnv->setActiveTexTarget(idx, GL_NONE);
2138 glErr("TextureObjChunk::deactivate");
2141 GLenum TextureObjChunk::determineTextureTarget(Window *pWindow) const
2143 GLenum target = GL_NONE;
2145 Image *img = getImage();
2147 if(img != NULL)
2149 target = getTarget();
2151 if(target == GL_NONE)
2153 if(img->getDepth() > 1)
2155 if(pWindow->hasExtOrVersion(_extTex3D, 0x0102))
2157 target = GL_TEXTURE_3D;
2159 else
2161 FWARNING(("TexturObjChunk::initialize: 3D textures not "
2162 "supported for this window!\n"));
2163 return target;
2166 else if(img->getHeight() > 1)
2168 target = GL_TEXTURE_2D;
2170 else
2172 #ifndef OSG_OGL_ES2
2173 target = GL_TEXTURE_1D;
2174 #endif
2179 return target;
2182 void TextureObjChunk::determineFormats(
2183 GLenum &internalFormat, GLenum &externalFormat) const
2185 Image *img = getImage ();
2186 internalFormat = getInternalFormat();
2188 if(img != NULL)
2190 externalFormat = img->getPixelFormat();
2191 GLenum type = img->getDataType ();
2193 if(internalFormat == GL_NONE)
2195 switch(externalFormat)
2197 #if defined(GL_BGR) && defined(GL_BGR_EXT)
2198 case GL_BGR:
2199 #else
2200 # if defined(GL_BGR)
2201 case GL_BGR:
2202 # endif
2203 # if defined(GL_BGR_EXT)
2204 case GL_BGR_EXT:
2205 # endif
2206 #endif
2207 case GL_RGB:
2209 switch(type)
2211 #if defined(GL_ARB_texture_float)
2212 case GL_FLOAT:
2213 internalFormat = GL_RGB32F;
2214 break;
2216 case GL_HALF_FLOAT_NV:
2217 internalFormat = GL_RGB16F;
2218 break;
2219 #endif
2221 default:
2222 internalFormat = GL_RGB;
2225 break;
2227 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
2228 case GL_BGRA:
2229 #else
2230 # if defined(GL_BGRA)
2231 case GL_BGRA:
2232 # endif
2233 # if defined(GL_BGRA_EXT)
2234 case GL_BGRA_EXT:
2235 # endif
2236 #endif
2237 case GL_RGBA:
2239 switch(type)
2241 #if defined(GL_ARB_texture_float)
2242 case GL_FLOAT:
2243 internalFormat = GL_RGBA32F;
2244 break;
2246 case GL_HALF_FLOAT_NV:
2247 internalFormat = GL_RGBA16F;
2248 break;
2249 #endif
2250 default:
2251 internalFormat = GL_RGBA;
2254 break;
2256 case GL_INTENSITY:
2257 internalFormat = GL_INTENSITY;
2258 externalFormat = GL_LUMINANCE;
2259 break;
2261 default:
2262 internalFormat = externalFormat;
2263 break;
2267 else
2269 externalFormat = getExternalFormat();
2272 if(getExternalFormat() != GL_NONE)
2273 externalFormat = getExternalFormat();
2276 /*-------------------------- Comparison -----------------------------------*/
2278 Real32 TextureObjChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
2280 return 0;
2283 bool TextureObjChunk::operator < (const StateChunk &other) const
2285 return this < &other;
2288 bool TextureObjChunk::operator == (const StateChunk &other) const
2290 TextureObjChunk const *tother =
2291 dynamic_cast<TextureObjChunk const*>(&other);
2293 if(!tother)
2294 return false;
2296 if(tother == this)
2297 return true;
2300 bool returnValue =
2301 getImage () == tother->getImage () &&
2302 getMinFilter () == tother->getMinFilter () &&
2303 getMagFilter () == tother->getMagFilter () &&
2304 getWrapS () == tother->getWrapS () &&
2305 getWrapT () == tother->getWrapT () &&
2306 getWrapR () == tother->getWrapR () &&
2307 getPriority () == tother->getPriority ();
2309 return returnValue;
2312 bool TextureObjChunk::operator != (const StateChunk &other) const
2314 return ! (*this == other);
2317 void TextureObjChunk::validate(DrawEnv *pEnv)
2319 pEnv->getWindow()->validateGLObject(this->getGLId(),
2320 pEnv );
2323 Int32 TextureObjChunk::getOpenGLId(DrawEnv *pEnv)
2325 return pEnv->getWindow()->getGLObjectId(this->getGLId());
2328 GLenum TextureObjChunk::determineInternalFormat(void)
2330 Image *img = getImage ();
2331 GLenum internalFormat = getInternalFormat();
2333 if(img != NULL)
2335 GLenum externalFormat = img->getPixelFormat();
2336 GLenum type = img->getDataType ();
2338 if(internalFormat == GL_NONE)
2340 switch(externalFormat)
2342 #if defined(GL_BGR) && defined(GL_BGR_EXT)
2343 case GL_BGR:
2344 #else
2345 # if defined(GL_BGR)
2346 case GL_BGR:
2347 # endif
2348 # if defined(GL_BGR_EXT)
2349 case GL_BGR_EXT:
2350 # endif
2351 #endif
2352 case GL_RGB:
2354 switch(type)
2356 #if defined(GL_ARB_texture_float)
2357 case GL_FLOAT:
2358 internalFormat = GL_RGB32F;
2359 break;
2361 case GL_HALF_FLOAT_NV:
2362 internalFormat = GL_RGB16F;
2363 break;
2364 #endif
2366 default:
2367 internalFormat = GL_RGB;
2370 break;
2372 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
2373 case GL_BGRA:
2374 #else
2375 # if defined(GL_BGRA)
2376 case GL_BGRA:
2377 # endif
2378 # if defined(GL_BGRA_EXT)
2379 case GL_BGRA_EXT:
2380 # endif
2381 #endif
2382 case GL_RGBA:
2384 switch(type)
2386 #if defined(GL_ARB_texture_float)
2387 case GL_FLOAT:
2388 internalFormat = GL_RGBA32F;
2389 break;
2391 case GL_HALF_FLOAT_NV:
2392 internalFormat = GL_RGBA16F;
2393 break;
2394 #endif
2395 default:
2396 internalFormat = GL_RGBA;
2399 break;
2401 case GL_INTENSITY:
2402 internalFormat = GL_INTENSITY;
2403 break;
2405 default:
2406 internalFormat = externalFormat;
2407 break;
2412 return internalFormat;