1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include <boost/bind.hpp>
48 #include "OSGConfig.h"
53 #include "OSGGLFuncProtos.h"
56 #include "OSGDrawEnv.h"
58 #include "OSGTextureObjChunk.h"
60 //#define OSG_DUMP_TEX
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 /***************************************************************************\
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(
100 "number of texture changes");
102 StatElemDesc
<StatIntOnceElem
> TextureObjChunk::statNTexBytes(
104 "sum of all used textures' sizes (approx., in bytes)");
107 /***************************************************************************\
109 \***************************************************************************/
111 /*-------------------------------------------------------------------------*\
113 \*-------------------------------------------------------------------------*/
115 void TextureObjChunk::initMethod(InitPhase ePhase
)
117 Inherited::initMethod(ePhase
);
119 if(ePhase
== TypeObject::SystemPost
)
122 Window::registerExtension("GL_EXT_texture3D" );
124 Window::registerExtension("GL_EXT_texture_array" );
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" );
139 Window::registerExtension("GL_ARB_shadow" );
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 /***************************************************************************\
185 \***************************************************************************/
187 /*-------------------------------------------------------------------------*\
189 \*-------------------------------------------------------------------------*/
192 /*------------- constructors & destructors --------------------------------*/
194 TextureObjChunk::TextureObjChunk(void) :
199 TextureObjChunk::TextureObjChunk(const TextureObjChunk
&source
) :
204 TextureObjChunk::~TextureObjChunk(void)
208 /*------------------------- Chunk Class Access ---------------------------*/
210 bool TextureObjChunk::isCubeTexture(void)
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
,
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
);
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
);
255 if(origin
== ChangedOrigin::Child
&&
256 0x0000 != (whichField
& ImageFieldMask
))
258 if((details
& ~(Image::PixelFieldMask
)) == 0)
260 Window::refreshGLObject(id
);
264 if(0x0000 != (whichField
& (Image::WidthFieldMask
|
265 Image::HeightFieldMask
|
266 Image::DepthFieldMask
)))
268 Window::reinitializeGLObject(id
);
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
289 /*----------------------------- onCreate --------------------------------*/
291 void TextureObjChunk::onCreate(const TextureObjChunk
*source
)
293 Inherited::onCreate(source
);
295 if(GlobalSystemState
== Startup
)
298 setGLId(Window::registerGLObject(
299 boost::bind(&TextureObjChunk::handleGL
,
300 TextureObjChunkMTUncountedPtr(this),
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
)
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())
340 if((bvFlags
& ExternalFormatFieldMask
) != 0)
342 indentLog(uiIndent
, PLOG
);
343 PLOG
<< "externalFormat "
344 << GLDefineMapper::the()->toString(_sfExternalFormat
.getValue())
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
);
364 << GLDefineMapper::the()->toString(_sfMinFilter
.getValue())
368 if((bvFlags
& MagFilterFieldMask
) != 0)
370 indentLog(uiIndent
, PLOG
);
372 << GLDefineMapper::the()->toString(_sfMagFilter
.getValue())
376 if((bvFlags
& WrapSFieldMask
) != 0)
378 indentLog(uiIndent
, PLOG
);
380 << GLDefineMapper::the()->toString(_sfWrapS
.getValue())
384 if((bvFlags
& WrapTFieldMask
) != 0)
386 indentLog(uiIndent
, PLOG
);
388 << GLDefineMapper::the()->toString(_sfWrapT
.getValue())
392 if((bvFlags
& WrapRFieldMask
) != 0)
394 indentLog(uiIndent
, PLOG
);
396 << GLDefineMapper::the()->toString(_sfWrapR
.getValue())
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())
420 if((bvFlags
& CompareFuncFieldMask
) != 0)
422 indentLog(uiIndent
, PLOG
);
423 PLOG
<< "compareFunc "
424 << GLDefineMapper::the()->toString(_sfCompareFunc
.getValue())
428 if((bvFlags
& DepthModeFieldMask
) != 0)
430 indentLog(uiIndent
, PLOG
);
432 << GLDefineMapper::the()->toString(_sfDepthMode
.getValue())
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
,
456 Window::GLObjectStatusE mode
,
460 if( img
==NULL
|| ! img
->getDimension()) // no image ?
463 // Early out if we don't have any image data, probably because we cleared
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())
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
)));
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
)));
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
)));
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
)));
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
)));
517 if(mode
== Window::reinitialize
)
520 glDeleteTextures(1, &tex
);
524 // 3D texture functions
525 OSGGETGLFUNCBYID_GL3( glTexImage3D
,
530 // standard function not available? try extension
531 if(osgGlTexImage3D
== NULL
)
533 OSGGETGLFUNCBYID_NV_GL3( glTexImage3D
,
539 OSGGETGLFUNCBYID_GL3( glTexSubImage3D
,
544 // standard function not available? try extension
545 if(osgGlTexSubImage3D
== NULL
)
547 OSGGETGLFUNCBYID_NV_GL3( glTexSubImage3D
,
549 _funcTexSubImage3DExt
,
554 // Compressed texture functions
555 OSGGETGLFUNCBYID_GL3 ( glCompressedTexImage1D
,
556 osgGlCompressedTexImage1D
,
557 _funcCompressedTexImage1D
,
559 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage1D
,
560 osgGlCompressedTexSubImage1D
,
561 _funcCompressedTexSubImage1D
,
564 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexImage2D
,
565 osgGlCompressedTexImage2D
,
566 _funcCompressedTexImage2D
,
568 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexSubImage2D
,
569 osgGlCompressedTexSubImage2D
,
570 _funcCompressedTexSubImage2D
,
572 OSGGETGLFUNCBYID_GL3 ( glCompressedTexImage3D
,
573 osgGlCompressedTexImage3D
,
574 _funcCompressedTexImage3D
,
576 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage3D
,
577 osgGlCompressedTexSubImage3D
,
578 _funcCompressedTexSubImage3D
,
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());
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
,
628 glTexParameterfv(paramtarget
,
629 GL_TEXTURE_BORDER_COLOR
,
630 const_cast<GLfloat
*>(
631 getBorderColor().getValuesRGBA()));
634 if(getCompareMode() != GL_NONE
&&
635 win
->hasExtOrVersion(_extShadow
, 0x0104))
637 glTexParameteri(paramtarget
,
638 GL_TEXTURE_COMPARE_MODE
,
640 glTexParameteri(paramtarget
,
641 GL_TEXTURE_COMPARE_FUNC
,
645 if(getDepthMode() != GL_LUMINANCE
&&
646 win
->hasExtOrVersion(_extDepthTexture
, 0x0104))
648 glTexParameteri(paramtarget
,
649 GL_DEPTH_TEXTURE_MODE
,
653 glErr("TextureObjChunk::initialize params");
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();
666 bool doScale
= getScale(); // scale the texture to 2^?
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"
686 // do we need mipmaps?
689 // do we have usable mipmaps ?
690 if(img
->getMipMapCount() == Int32(img
->calcMipmapLevelCount()) &&
691 osgIsPower2(width
) && osgIsPower2(height
) &&
695 UInt16 baseLevel
= 0;
696 Real32 skipLevels
= osgClamp(0.f
, getSkipMipMapLevels(), 1.f
);
698 if(img
->getMipMapCount() != 0)
701 UInt16(skipLevels
* (img
->getMipMapCount() - 1));
704 for(UInt16 i
= baseLevel
; i
< img
->getMipMapCount(); i
++)
707 img
->calcMipmapGeometry(i
, w
, h
, d
);
715 osgGlCompressedTexImage1D(
721 img
->calcMipmapLevelSize(i
),
722 img
->getData(i
, frame
, side
));
726 case GL_TEXTURE_1D_ARRAY
:
727 osgGlCompressedTexImage2D(
734 img
->calcMipmapLevelSize(i
),
735 img
->getData(i
, frame
, side
));
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(
750 img
->calcMipmapLevelSize(i
),
751 img
->getData(i
, frame
, side
));
754 case GL_TEXTURE_2D_ARRAY
:
755 case GL_TEXTURE_CUBE_MAP_ARRAY
:
756 osgGlCompressedTexImage3D(
764 img
->calcMipmapLevelSize(i
),
765 img
->getData(i
, frame
, side
));
768 SFATAL
<< "TextureObjChunk::initialize1: "
770 << imgtarget
<< "!!!" << std::endl
;
780 glTexImage1D(GL_TEXTURE_1D
,
787 img
->getData(i
, frame
, side
));
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
,
806 img
->getData(i
, frame
, side
));
809 case GL_TEXTURE_2D_ARRAY
:
810 case GL_TEXTURE_CUBE_MAP_ARRAY
:
811 osgGlTexImage3D(imgtarget
,
820 img
->getData(i
, frame
, side
));
823 SFATAL
<< "TextureObjChunk::initialize1: "
825 << imgtarget
<< "!!!" << std::endl
;
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
,
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
853 // Nope, try to use gluBuild?DMipmaps
856 // can we use it directly?
857 if(! osgIsPower2(width
) ||
858 ! osgIsPower2(height
) ||
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 "
872 UInt32 outw
= osgNextPower2(width
);
873 UInt32 outh
= osgNextPower2(height
);
875 data
= malloc(outw
* outh
* img
->getBpp());
878 // should we scale to next power of 2?
881 GLint res
= gluScaleImage(externalFormat
,
895 SWARNING
<< "TextureObjChunk::initialize: "
896 << "gluScaleImage failed: "
897 << gluErrorString(res
) << "("
909 // nope, just copy the image to the lower left part
913 memset(data
, 0, outw
* outh
* img
->getBpp());
915 UInt16 bpl
= width
* img
->getBpp();
917 const UInt8
* src
= img
->getData(0,
921 UInt8
* dest
= static_cast<UInt8
*>(data
);
923 for(UInt32 y
= 0; y
< height
; y
++)
925 memcpy(dest
, src
, bpl
);
928 dest
+= outw
* img
->getBpp();
937 data
= const_cast<void *>(
938 static_cast<const void *>(img
->getData(0,
949 gluBuild1DMipmaps(imgtarget
,
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
,
965 externalFormat
, type
, data
);
969 # ifdef GLU_VERSION_1_3
970 gluBuild3DMipmaps(imgtarget
, internalFormat
,
971 width
, height
, depth
,
972 externalFormat
, type
, data
);
974 FWARNING(("TextureObjChunk::initialize: 3d "
975 "textures supported, but GLU version "
976 "< 1.3, thus gluBuild3DMipmaps not "
981 SFATAL
<< "TextureObjChunk::initialize2: "
983 << imgtarget
<< "!!!" << std::endl
;
986 if(data
!= img
->getData(0, frame
, side
))
990 } // need to use gluBuildMipmaps?
991 } // got them from the image already?
994 // no mipmaps, or mipmapping failed?
997 // got here needing mipmaps?
998 if(needMipmaps
&& paramtarget
!= GL_NONE
) // turn them off
999 glTexParameteri(paramtarget
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
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
,
1008 (!osgIsPower2(width
) || !osgIsPower2(height
) ||
1009 !osgIsPower2(depth
)))
1011 // No, need to scale or cut
1014 // should we scale to next power of 2?
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 !!!"
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
);
1046 SWARNING
<< "TextureObjChunk::initialize: "
1047 << "gluScaleImage failed: "
1048 << gluErrorString(res
) << "("
1049 << res
<< ")!" << std::endl
;
1060 else // don't scale, just use ll corner
1069 osgGlCompressedTexImage1D(GL_TEXTURE_1D
, 0,
1071 osgNextPower2(width
),
1074 osgGlCompressedTexSubImage1D(GL_TEXTURE_1D
,
1077 img
->getFrameSize(),
1084 case GL_TEXTURE_1D_ARRAY
:
1085 osgGlCompressedTexImage2D(imgtarget
, 0,
1087 osgNextPower2(width
),
1088 osgNextPower2(height
),
1091 osgGlCompressedTexSubImage2D(imgtarget
, 0, 0, 0,
1094 img
->getFrameSize(),
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,
1107 osgNextPower2(width
),
1108 osgNextPower2(height
),
1111 osgGlCompressedTexSubImage2D(imgtarget
, 0, 0, 0,
1114 (img
->getSideCount() > 1) ? img
->getSideSize() :
1115 img
->getFrameSize(),
1120 case GL_TEXTURE_RECTANGLE_ARB
:
1121 osgGlCompressedTexImage2D(
1122 GL_TEXTURE_RECTANGLE_ARB
,
1126 img
->getFrameSize(),
1132 case GL_TEXTURE_2D_ARRAY
:
1133 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1134 osgGlCompressedTexImage3D(imgtarget
, 0,
1136 osgNextPower2(width
),
1137 osgNextPower2(height
),
1138 osgNextPower2(depth
),
1139 getBorderWidth(), 0,
1141 osgGlCompressedTexSubImage3D(imgtarget
,
1147 img
->getFrameSize(),
1153 SFATAL
<< "TextureObjChunk::initialize4: "
1154 << "unknown target "
1155 << imgtarget
<< "!!!" << std::endl
;
1164 glTexImage1D(GL_TEXTURE_1D
, 0, internalFormat
,
1165 osgNextPower2(width
),
1167 externalFormat
, type
,
1169 glTexSubImage1D(GL_TEXTURE_1D
, 0, 0, width
,
1170 externalFormat
, type
,
1171 img
->getData(0, frame
, side
));
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
),
1186 externalFormat
, type
,
1188 glTexSubImage2D(imgtarget
, 0, 0, 0, width
,
1190 externalFormat
, type
,
1191 img
->getData(0, frame
, side
));
1193 case GL_TEXTURE_RECTANGLE_ARB
:
1194 glTexImage2D( GL_TEXTURE_RECTANGLE_ARB
, 0,
1196 width
, height
, getBorderWidth(),
1197 externalFormat
, type
,
1198 img
->getData(0, frame
, side
));
1201 case GL_TEXTURE_2D_ARRAY
:
1202 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1203 osgGlTexImage3D(imgtarget
,
1206 osgNextPower2(width
),
1207 osgNextPower2(height
),
1208 osgNextPower2(depth
),
1210 externalFormat
, type
, NULL
);
1211 osgGlTexSubImage3D(imgtarget
, 0, 0, 0, 0,
1212 width
, height
, depth
,
1213 externalFormat
, type
,
1214 img
->getData(0, frame
, side
));
1217 SFATAL
<< "TextureObjChunk::initialize4: "
1218 << "unknown target "
1219 << imgtarget
<< "!!!" << std::endl
;
1220 } // switch imgtarget
1221 } // compressed data?
1226 else // can we use it directly?
1228 data
= const_cast<void *>(
1229 static_cast<const void *>(img
->getData(0,
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
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
1250 osgGlCompressedTexImage1D(GL_TEXTURE_1D
, 0,
1252 width
, getBorderWidth(),
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
,
1270 case GL_TEXTURE_RECTANGLE_ARB
:
1271 osgGlCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB
,
1279 case GL_TEXTURE_2D_ARRAY
:
1280 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1281 osgGlCompressedTexImage3D(imgtarget
, 0,
1283 width
, height
, depth
,
1288 SFATAL
<< "TextureObjChunk::initialize3: "
1289 << "unknown target "
1290 << imgtarget
<< "!!!" << std::endl
;
1299 glTexImage1D(GL_TEXTURE_1D
, 0, internalFormat
,
1300 width
, getBorderWidth(),
1301 externalFormat
, type
,
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
,
1318 case GL_TEXTURE_RECTANGLE_ARB
:
1319 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB
, 0,
1321 width
, height
, getBorderWidth(),
1322 externalFormat
, type
,
1326 case GL_TEXTURE_2D_ARRAY
:
1327 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1328 osgGlTexImage3D(imgtarget
, 0, internalFormat
,
1329 width
, height
, depth
,
1331 externalFormat
, type
,
1335 SFATAL
<< "TextureObjChunk::initialize3: "
1336 << "unknown target "
1337 << imgtarget
<< "!!!" << std::endl
;
1342 if(data
!= img
->getData(0, frame
, side
))
1346 glErr("TextureObjChunk::initialize image");
1349 glBindTexture(bindtarget
, 0);
1351 // Clear image data after upload to the graphics card.
1352 if (img
->getClearOnLoad())
1357 else if(mode
== Window::needrefresh
)
1359 // 3D texture functions
1360 OSGGETGLFUNCBYID_GL3( glTexSubImage3D
,
1366 // Compressed texture functions
1367 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage1D
,
1368 osgGlCompressedTexSubImage1D
,
1369 _funcCompressedTexSubImage1D
,
1372 OSGGETGLFUNCBYID_GL3_ES( glCompressedTexSubImage2D
,
1373 osgGlCompressedTexSubImage2D
,
1374 _funcCompressedTexSubImage2D
,
1376 OSGGETGLFUNCBYID_GL3 ( glCompressedTexSubImage3D
,
1377 osgGlCompressedTexSubImage3D
,
1378 _funcCompressedTexSubImage3D
,
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
)));
1393 if(! img
) // no image ?
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;
1424 if(w
!= UInt32(img
->getWidth()))
1425 glPixelStorei(GL_UNPACK_ROW_LENGTH
, img
->getWidth());
1427 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, ix
);
1429 glPixelStorei(GL_UNPACK_SKIP_ROWS
, iy
);
1430 if(has3DTex
&& iz
!= 0)
1431 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, iz
);
1440 osgGlCompressedTexSubImage1D(GL_TEXTURE_1D
, 0, ix
, w
,
1442 img
->getFrameSize(),
1449 case GL_TEXTURE_1D_ARRAY
:
1450 osgGlCompressedTexSubImage2D(imgtarget
, 0, ix
, iy
, w
, h
,
1452 img
->getFrameSize(),
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
,
1465 (img
->getSideCount() > 1) ? img
->getSideSize() :
1466 img
->getFrameSize(),
1471 case GL_TEXTURE_RECTANGLE_ARB
:
1472 osgGlCompressedTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB
,
1476 img
->getFrameSize(),
1482 case GL_TEXTURE_2D_ARRAY
:
1483 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1484 osgGlCompressedTexSubImage3D(imgtarget
, 0,
1488 img
->getFrameSize(),
1494 SFATAL
<< "TextureObjChunk::refresh: unknown target "
1495 << imgtarget
<< "!!!" << std::endl
;
1504 glTexSubImage1D(GL_TEXTURE_1D
, 0, ix
, w
,
1505 externalFormat
, type
,
1506 img
->getData( 0, getFrame(), side
) );
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
) );
1521 case GL_TEXTURE_RECTANGLE_ARB
:
1522 glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB
, 0,
1524 externalFormat
, type
,
1525 img
->getData( 0, getFrame(), side
) );
1528 case GL_TEXTURE_2D_ARRAY
:
1529 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1530 osgGlTexSubImage3D(imgtarget
, 0, ix
, iy
, iz
,
1532 externalFormat
, type
,
1533 img
->getData(0, getFrame(), side
));
1536 SFATAL
<< "TextureObjChunk::refresh: unknown target "
1537 << imgtarget
<< "!!!" << std::endl
;
1543 if(w
!= UInt32(img
->getWidth()))
1544 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
1546 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
1548 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
1549 if(has3DTex
&& iz
!= 0)
1550 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
1553 if(paramtarget
!= GL_NONE
)
1555 #if !defined(OSG_OGL_COREONLY) && !defined(OSG_OGL_ES2)
1556 glTexParameterf(paramtarget
, GL_TEXTURE_PRIORITY
,
1559 glTexParameteri(paramtarget
, GL_TEXTURE_MIN_FILTER
,
1561 glTexParameteri(paramtarget
, GL_TEXTURE_MAG_FILTER
,
1565 // unbind the texture
1566 glBindTexture(bindtarget
, 0);
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
,
1585 Window::GLObjectStatusE mode
,
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
);
1602 Image
*img
= getImage();
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
;
1620 ("TextureObjChunk::initialize: 3D textures not "
1621 "supported for this window!\n"));
1625 else if(img
->getHeight() > 1)
1627 target
= GL_TEXTURE_2D
;
1632 target
= GL_TEXTURE_1D
;
1637 handleTexture(win
, id
, target
, target
, target
, mode
, img
);
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
,
1651 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
,
1652 Window::initialize
, getImage(), 4);
1653 handleTexture(win
, id
,
1654 GL_TEXTURE_CUBE_MAP_ARB
,
1656 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
,
1657 Window::initialize
, getImage(), 3);
1658 handleTexture(win
, id
,
1659 GL_TEXTURE_CUBE_MAP_ARB
,
1661 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
,
1662 Window::initialize
, getImage(), 2);
1663 handleTexture(win
, id
,
1664 GL_TEXTURE_CUBE_MAP_ARB
,
1666 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
,
1667 Window::initialize
, getImage(), 1);
1668 handleTexture(win
, id
,
1669 GL_TEXTURE_CUBE_MAP_ARB
,
1671 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
,
1672 Window::initialize
, getImage(), 0);
1678 SWARNING
<< "TextureObjChunk(" << this << ")::handleGL: No image."
1684 SWARNING
<< "TextureObjChunk(" << this << "::handleGL: Illegal mode: "
1685 << mode
<< " for id " << id
<< std::endl
;
1691 /*! GL object handler
1694 void TextureObjChunk::handleDestroyGL(DrawEnv
*pEnv
,
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;
1712 SWARNING
<< "TextureObjChunk::handleDestroyGL: Illegal mode: "
1713 << mode
<< " for id " << id
<< std::endl
;
1718 void TextureObjChunk::activate(DrawEnv
*pEnv
, UInt32 idx
)
1721 fprintf(stderr
, "Activate %d\n", _uiChunkId
);
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
)
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
)
1750 if(idx
>= static_cast<UInt32
>(nteximages
))
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
));
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 ?
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
;
1785 FWARNING(("TextureObjChunk::activate: 3D textures not "
1786 "supported for this window!\n"));
1790 else if(img
->getHeight() > 1)
1792 target
= GL_TEXTURE_2D
;
1797 target
= GL_TEXTURE_1D
;
1804 target
= GL_TEXTURE_CUBE_MAP_ARB
;
1808 FDEBUG(("TextureObjChunk::activate - %d\n", getGLId()));
1811 // Update the texture statistics
1812 StatCollectorP pColl
= pEnv
->getStatCollector();
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
)
1833 if(idx
< static_cast<UInt32
>(ntexunits
))
1838 glErr("TextureObjChunk::activate");
1842 void TextureObjChunk::changeFrom(DrawEnv
*pEnv
,
1846 // change from me to me?
1847 // this assumes I haven't changed in the meantime.
1848 // is that a valid assumption?
1852 // If the old one is not a texture chunk, deactivate it and activate
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
);
1863 TextureObjChunk
*oldp
= dynamic_cast<TextureObjChunk
*>(old
);
1866 fprintf(stderr
, "Change %d %d\n", oldp
->_uiChunkId
, _uiChunkId
);
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
);
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
)
1898 ntexunits
= static_cast<UInt32
>(dummy
);
1901 if((dummy
= win
->getConstantValue(GL_MAX_TEXTURE_IMAGE_UNITS_ARB
)) ==
1902 Window::unknownConstant
1905 nteximages
= ntexunits
;
1909 nteximages
= static_cast<UInt32
>(dummy
);
1913 if((dummy
= win
->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB
)) ==
1914 Window::unknownConstant
1917 ntexcoords
= ntexunits
;
1921 ntexcoords
= static_cast<UInt32
>(dummy
);
1925 if(idx
>= nteximages
)
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
));
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
;
1947 FWARNING(("TextureObjChunk::changeFrom: 3D textures not "
1948 "supported for this window!\n"));
1949 oldp
->deactivate(pEnv
, idx
);
1953 else if(img
->getHeight() > 1)
1954 target
= GL_TEXTURE_2D
;
1957 target
= GL_TEXTURE_1D
;
1963 target
= GL_TEXTURE_CUBE_MAP_ARB
;
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
;
1980 FWARNING(("TextureObjChunk::changeFrom: 3D textures "
1981 "not supported for this window!\n"));
1982 oldp
->deactivate(pEnv
, idx
);
1986 else if(oldp
->getImage()->getHeight() > 1)
1988 oldtarget
= GL_TEXTURE_2D
;
1993 oldtarget
= GL_TEXTURE_1D
;
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();
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
);
2030 if(target
!= oldtarget
)
2036 glErr("TextureObjChunk::changeFrom");
2039 void TextureObjChunk::deactivate(DrawEnv
*pEnv
, UInt32 idx
)
2042 fprintf(stderr
, "Deactivate %d\n", _uiChunkId
);
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
)
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
)
2072 if(idx
>= static_cast<UInt32
>(nteximages
))
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
));
2082 Image
*img
= getImage();
2083 GLenum target
= getTarget();
2085 if(img
== NULL
|| ! img
->getDimension())
2088 glErr("TextureObjChunk::deactivate precheck");
2090 bool isActive
= false;
2093 Real32 ntexunits
= win
->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB
);
2095 if(ntexunits
== Window::unknownConstant
)
2098 if(idx
>= static_cast<UInt32
>(ntexunits
))
2099 return; // textures >= MTU are not enabled and don't have an env
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
;
2116 FWARNING(("TextureObjChunk::deactivate: 3D textures not "
2117 "supported for this window!\n"));
2121 else if(img
->getHeight() > 1)
2122 target
= GL_TEXTURE_2D
;
2125 target
= GL_TEXTURE_1D
;
2131 target
= GL_TEXTURE_CUBE_MAP_ARB
;
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();
2149 target
= getTarget();
2151 if(target
== GL_NONE
)
2153 if(img
->getDepth() > 1)
2155 if(pWindow
->hasExtOrVersion(_extTex3D
, 0x0102))
2157 target
= GL_TEXTURE_3D
;
2161 FWARNING(("TexturObjChunk::initialize: 3D textures not "
2162 "supported for this window!\n"));
2166 else if(img
->getHeight() > 1)
2168 target
= GL_TEXTURE_2D
;
2173 target
= GL_TEXTURE_1D
;
2182 void TextureObjChunk::determineFormats(
2183 GLenum
&internalFormat
, GLenum
&externalFormat
) const
2185 Image
*img
= getImage ();
2186 internalFormat
= getInternalFormat();
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)
2200 # if defined(GL_BGR)
2203 # if defined(GL_BGR_EXT)
2211 #if defined(GL_ARB_texture_float)
2213 internalFormat
= GL_RGB32F
;
2216 case GL_HALF_FLOAT_NV
:
2217 internalFormat
= GL_RGB16F
;
2222 internalFormat
= GL_RGB
;
2227 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
2230 # if defined(GL_BGRA)
2233 # if defined(GL_BGRA_EXT)
2241 #if defined(GL_ARB_texture_float)
2243 internalFormat
= GL_RGBA32F
;
2246 case GL_HALF_FLOAT_NV
:
2247 internalFormat
= GL_RGBA16F
;
2251 internalFormat
= GL_RGBA
;
2257 internalFormat
= GL_INTENSITY
;
2258 externalFormat
= GL_LUMINANCE
;
2262 internalFormat
= externalFormat
;
2269 externalFormat
= getExternalFormat();
2272 if(getExternalFormat() != GL_NONE
)
2273 externalFormat
= getExternalFormat();
2276 /*-------------------------- Comparison -----------------------------------*/
2278 Real32
TextureObjChunk::switchCost(StateChunk
*OSG_CHECK_ARG(chunk
))
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
);
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 ();
2312 bool TextureObjChunk::operator != (const StateChunk
&other
) const
2314 return ! (*this == other
);
2317 void TextureObjChunk::validate(DrawEnv
*pEnv
)
2319 pEnv
->getWindow()->validateGLObject(this->getGLId(),
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();
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)
2345 # if defined(GL_BGR)
2348 # if defined(GL_BGR_EXT)
2356 #if defined(GL_ARB_texture_float)
2358 internalFormat
= GL_RGB32F
;
2361 case GL_HALF_FLOAT_NV
:
2362 internalFormat
= GL_RGB16F
;
2367 internalFormat
= GL_RGB
;
2372 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
2375 # if defined(GL_BGRA)
2378 # if defined(GL_BGRA_EXT)
2386 #if defined(GL_ARB_texture_float)
2388 internalFormat
= GL_RGBA32F
;
2391 case GL_HALF_FLOAT_NV
:
2392 internalFormat
= GL_RGBA16F
;
2396 internalFormat
= GL_RGBA
;
2402 internalFormat
= GL_INTENSITY
;
2406 internalFormat
= externalFormat
;
2412 return internalFormat
;