1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <OpenGl_Texture.hxx>
17 #include <OpenGl_ArbFBO.hxx>
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_GlCore32.hxx>
20 #include <OpenGl_Sampler.hxx>
21 #include <Graphic3d_TextureParams.hxx>
22 #include <TCollection_ExtendedString.hxx>
23 #include <Standard_Assert.hxx>
24 #include <Image_PixMap.hxx>
26 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
28 //! Simple class to reset unpack alignment settings
29 struct OpenGl_UnpackAlignmentSentry
32 //! Reset unpack alignment settings to safe values
35 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
36 #if !defined(GL_ES_VERSION_2_0)
37 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
41 ~OpenGl_UnpackAlignmentSentry()
48 // =======================================================================
49 // function : OpenGl_Texture
51 // =======================================================================
52 OpenGl_Texture::OpenGl_Texture (const TCollection_AsciiString& theResourceId,
53 const Handle(Graphic3d_TextureParams)& theParams)
54 : OpenGl_NamedResource (theResourceId),
55 mySampler (new OpenGl_Sampler (theParams)),
57 myTextureId (NO_TEXTURE),
58 myTarget (GL_TEXTURE_2D),
62 myTextFormat (GL_RGBA),
63 mySizedFormat(GL_RGBA8),
65 myHasMipmaps (Standard_False),
71 // =======================================================================
72 // function : ~OpenGl_Texture
74 // =======================================================================
75 OpenGl_Texture::~OpenGl_Texture()
80 // =======================================================================
83 // =======================================================================
84 bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& theCtx)
86 if (myTextureId != NO_TEXTURE)
91 theCtx->core11fwd->glGenTextures (1, &myTextureId);
92 if (myTextureId == NO_TEXTURE)
97 //mySampler->Create (theCtx); // do not create sampler object by default
101 // =======================================================================
102 // function : Release
104 // =======================================================================
105 void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
107 mySampler->Release (theGlCtx);
108 if (myTextureId == NO_TEXTURE)
113 // application can not handle this case by exception - this is bug in code
114 Standard_ASSERT_RETURN (theGlCtx != NULL,
115 "OpenGl_Texture destroyed without GL context! Possible GPU memory leakage...",);
117 if (theGlCtx->IsValid())
119 glDeleteTextures (1, &myTextureId);
121 myTextureId = NO_TEXTURE;
122 mySizeX = mySizeY = mySizeZ = 0;
125 // =======================================================================
126 // function : applyDefaultSamplerParams
128 // =======================================================================
129 void OpenGl_Texture::applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx)
131 OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), NULL, myTarget, myHasMipmaps);
132 if (mySampler->IsValid() && !mySampler->IsImmutable())
134 OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), mySampler.get(), myTarget, myHasMipmaps);
138 // =======================================================================
141 // =======================================================================
142 void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
143 const Graphic3d_TextureUnit theTextureUnit) const
145 if (theCtx->core15fwd != NULL)
147 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
149 mySampler->Bind (theCtx, theTextureUnit);
150 glBindTexture (myTarget, myTextureId);
153 // =======================================================================
156 // =======================================================================
157 void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
158 const Graphic3d_TextureUnit theTextureUnit) const
160 if (theCtx->core15fwd != NULL)
162 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
164 mySampler->Unbind (theCtx, theTextureUnit);
165 glBindTexture (myTarget, NO_TEXTURE);
168 //=======================================================================
169 //function : InitSamplerObject
171 //=======================================================================
172 bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx)
174 return myTextureId != NO_TEXTURE
175 && mySampler->Init (theCtx, *this);
178 //=======================================================================
179 //function : GetDataFormat
181 //=======================================================================
182 bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
183 const Image_PixMap& theData,
184 GLint& theTextFormat,
185 GLenum& thePixelFormat,
188 theTextFormat = GL_RGBA8;
191 switch (theData.Format())
193 case Image_Format_GrayF:
195 if (theCtx->core11 == NULL)
197 theTextFormat = GL_R8; // GL_R32F
198 thePixelFormat = GL_RED;
202 #if !defined(GL_ES_VERSION_2_0)
203 theTextFormat = GL_LUMINANCE8;
205 theTextFormat = GL_LUMINANCE;
207 thePixelFormat = GL_LUMINANCE;
209 theDataType = GL_FLOAT;
212 case Image_Format_AlphaF:
214 if (theCtx->core11 == NULL)
216 theTextFormat = GL_R8; // GL_R32F
217 thePixelFormat = GL_RED;
221 #if !defined(GL_ES_VERSION_2_0)
222 theTextFormat = GL_ALPHA8;
224 theTextFormat = GL_ALPHA;
226 thePixelFormat = GL_ALPHA;
228 theDataType = GL_FLOAT;
231 case Image_Format_RGBAF:
233 theTextFormat = GL_RGBA8; // GL_RGBA32F
234 thePixelFormat = GL_RGBA;
235 theDataType = GL_FLOAT;
238 case Image_Format_BGRAF:
240 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
244 theTextFormat = GL_RGBA8; // GL_RGBA32F
245 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
246 theDataType = GL_FLOAT;
249 case Image_Format_RGBF:
251 theTextFormat = GL_RGB8; // GL_RGB32F
252 thePixelFormat = GL_RGB;
253 theDataType = GL_FLOAT;
256 case Image_Format_BGRF:
258 #if !defined(GL_ES_VERSION_2_0)
259 theTextFormat = GL_RGB8; // GL_RGB32F
260 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
261 theDataType = GL_FLOAT;
267 case Image_Format_RGBA:
269 theTextFormat = GL_RGBA8;
270 thePixelFormat = GL_RGBA;
271 theDataType = GL_UNSIGNED_BYTE;
274 case Image_Format_BGRA:
276 #if !defined(GL_ES_VERSION_2_0)
277 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
281 theTextFormat = GL_RGBA8;
283 if (!theCtx->extBgra)
287 theTextFormat = GL_BGRA_EXT;
289 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
290 theDataType = GL_UNSIGNED_BYTE;
293 case Image_Format_RGB32:
295 #if !defined(GL_ES_VERSION_2_0)
296 // ask driver to convert data to RGB8 to save memory
297 theTextFormat = GL_RGB8;
299 // conversion is not supported
300 theTextFormat = GL_RGBA8;
302 thePixelFormat = GL_RGBA;
303 theDataType = GL_UNSIGNED_BYTE;
306 case Image_Format_BGR32:
308 #if !defined(GL_ES_VERSION_2_0)
309 if (!theCtx->IsGlGreaterEqual(1, 2) && !theCtx->extBgra)
313 theTextFormat = GL_RGB8;
315 if (!theCtx->extBgra)
319 theTextFormat = GL_BGRA_EXT;
321 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
322 theDataType = GL_UNSIGNED_BYTE;
325 case Image_Format_RGB:
327 theTextFormat = GL_RGB8;
328 thePixelFormat = GL_RGB;
329 theDataType = GL_UNSIGNED_BYTE;
332 case Image_Format_BGR:
334 #if !defined(GL_ES_VERSION_2_0)
335 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
339 theTextFormat = GL_RGB8;
340 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
341 theDataType = GL_UNSIGNED_BYTE;
347 case Image_Format_Gray:
349 if (theCtx->core11 == NULL)
351 theTextFormat = GL_R8;
352 thePixelFormat = GL_RED;
356 #if !defined(GL_ES_VERSION_2_0)
357 theTextFormat = GL_LUMINANCE8;
359 theTextFormat = GL_LUMINANCE;
361 thePixelFormat = GL_LUMINANCE;
363 theDataType = GL_UNSIGNED_BYTE;
366 case Image_Format_Alpha:
368 if (theCtx->core11 == NULL)
370 theTextFormat = GL_R8;
371 thePixelFormat = GL_RED;
375 #if !defined(GL_ES_VERSION_2_0)
376 theTextFormat = GL_ALPHA8;
378 theTextFormat = GL_ALPHA;
380 thePixelFormat = GL_ALPHA;
382 theDataType = GL_UNSIGNED_BYTE;
385 case Image_Format_UNKNOWN:
393 // =======================================================================
396 // =======================================================================
397 bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
398 const Standard_Integer theTextFormat,
399 const GLenum thePixelFormat,
400 const GLenum theDataType,
401 const Standard_Integer theSizeX,
402 const Standard_Integer theSizeY,
403 const Graphic3d_TypeOfTexture theType,
404 const Image_PixMap* theImage)
406 #if !defined(GL_ES_VERSION_2_0)
407 const GLenum aTarget = theType == Graphic3d_TOT_1D
411 const GLenum aTarget = GL_TEXTURE_2D;
413 const Standard_Boolean toCreateMipMaps = (theType == Graphic3d_TOT_2D_MIPMAP);
414 const bool toPatchExisting = IsValid()
415 && myTextFormat == thePixelFormat
416 && myTarget == aTarget
417 && myHasMipmaps == toCreateMipMaps
418 && mySizeX == theSizeX
419 && (mySizeY == theSizeY || theType == Graphic3d_TOT_1D);
420 if (!Create (theCtx))
422 Release (theCtx.operator->());
426 if (theImage != NULL)
428 myIsAlpha = theImage->Format() == Image_Format_Alpha
429 || theImage->Format() == Image_Format_AlphaF;
433 myIsAlpha = thePixelFormat == GL_ALPHA;
436 myHasMipmaps = toCreateMipMaps;
437 myTextFormat = thePixelFormat;
438 mySizedFormat = theTextFormat;
440 #if !defined(GL_ES_VERSION_2_0)
441 const GLint anIntFormat = theTextFormat;
443 // ES 2.0 does not support sized formats and format conversions - them detected from data type
444 const GLint anIntFormat = theCtx->IsGlGreaterEqual (3, 0) ? theTextFormat : thePixelFormat;
447 if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
449 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
450 "Error: floating-point textures are not supported by hardware.");
451 Release (theCtx.operator->());
455 const GLsizei aMaxSize = theCtx->MaxTextureSize();
456 if (theSizeX > aMaxSize
457 || theSizeY > aMaxSize)
459 TCollection_ExtendedString aWarnMessage = TCollection_ExtendedString ("Error: Texture dimension - ")
460 + theSizeX + "x" + theSizeY + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")";
462 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
463 Release (theCtx.operator->());
466 #if !defined(GL_ES_VERSION_2_0)
467 else if (!theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW)
469 // Notice that formally general NPOT textures are required by OpenGL 2.0 specifications
470 // however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
471 // Trying to create NPOT textures on such hardware will not fail
472 // but driver will fall back into software rendering,
473 const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
474 const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
476 if (theSizeX != aWidthP2
477 || (theType != Graphic3d_TOT_1D && theSizeY != aHeightP2))
479 TCollection_ExtendedString aWarnMessage =
480 TCollection_ExtendedString ("Error: NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by hardware.";
482 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
484 Release (theCtx.operator->());
489 else if (!theCtx->IsGlGreaterEqual (3, 0) && theType == Graphic3d_TOT_2D_MIPMAP)
491 // Mipmap NPOT textures are not supported by OpenGL ES 2.0.
492 const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
493 const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
495 if (theSizeX != aWidthP2
496 || theSizeY != aHeightP2)
498 TCollection_ExtendedString aWarnMessage =
499 TCollection_ExtendedString ("Error: Mipmap NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by OpenGL ES 2.0";
501 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
503 Release (theCtx.operator->());
509 #if !defined(GL_ES_VERSION_2_0)
510 GLint aTestWidth = 0;
511 GLint aTestHeight = 0;
513 GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
515 // setup the alignment
516 OpenGl_UnpackAlignmentSentry anUnpackSentry;
517 (void)anUnpackSentry; // avoid compiler warning
519 if (aDataPtr != NULL)
521 const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
522 glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
524 #if !defined(GL_ES_VERSION_2_0)
525 // notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
526 const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
527 const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
528 glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
535 case Graphic3d_TOT_1D:
537 #if !defined(GL_ES_VERSION_2_0)
539 applyDefaultSamplerParams (theCtx);
542 glTexSubImage1D (GL_TEXTURE_1D, 0, 0,
543 theSizeX, thePixelFormat, theDataType, aDataPtr);
548 // use proxy to check texture could be created or not
549 glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat,
551 thePixelFormat, theDataType, NULL);
552 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
553 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
556 // no memory or broken input parameters
558 Release (theCtx.operator->());
562 glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat,
564 thePixelFormat, theDataType, aDataPtr);
565 if (glGetError() != GL_NO_ERROR)
568 Release (theCtx.operator->());
578 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
579 "Error: 1D textures are not supported by hardware.");
580 Release (theCtx.operator->());
584 case Graphic3d_TOT_2D:
587 applyDefaultSamplerParams (theCtx);
590 glTexSubImage2D (GL_TEXTURE_2D, 0,
593 thePixelFormat, theDataType, aDataPtr);
598 #if !defined(GL_ES_VERSION_2_0)
599 // use proxy to check texture could be created or not
600 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
601 theSizeX, theSizeY, 0,
602 thePixelFormat, theDataType, NULL);
603 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
604 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
605 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
606 if (aTestWidth == 0 || aTestHeight == 0)
608 // no memory or broken input parameters
610 Release (theCtx.operator->());
615 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
616 theSizeX, theSizeY, 0,
617 thePixelFormat, theDataType, aDataPtr);
618 const GLenum anErr = glGetError();
619 if (anErr != GL_NO_ERROR)
621 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
622 TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
623 + " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
624 + " can not be created with error " + int(anErr) + ".");
626 Release (theCtx.operator->());
636 case Graphic3d_TOT_2D_MIPMAP:
639 applyDefaultSamplerParams (theCtx);
642 glTexSubImage2D (GL_TEXTURE_2D, 0,
645 thePixelFormat, theDataType, aDataPtr);
646 if (theCtx->arbFBO != NULL)
649 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
650 if (glGetError() != GL_NO_ERROR)
653 Release (theCtx.operator->());
662 #if !defined(GL_ES_VERSION_2_0)
663 // use proxy to check texture could be created or not
664 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
665 theSizeX, theSizeY, 0,
666 thePixelFormat, theDataType, NULL);
667 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
668 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
669 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
670 if (aTestWidth == 0 || aTestHeight == 0)
672 // no memory or broken input parameters
674 Release (theCtx.operator->());
679 // upload main picture
680 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
681 theSizeX, theSizeY, 0,
682 thePixelFormat, theDataType, theImage->Data());
683 const GLenum aTexImgErr = glGetError();
684 if (aTexImgErr != GL_NO_ERROR)
686 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
687 TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
688 + " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
689 + " can not be created with error " + int(aTexImgErr) + ".");
691 Release (theCtx.operator->());
698 if (theCtx->arbFBO != NULL)
701 //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST);
702 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
704 if (glGetError() != GL_NO_ERROR)
707 Release (theCtx.operator->());
713 const TCollection_ExtendedString aWarnMessage ("Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing.");
715 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
718 Release (theCtx.operator->());
727 Release (theCtx.operator->());
731 // =======================================================================
734 // =======================================================================
735 bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
736 const Image_PixMap& theImage,
737 const Graphic3d_TypeOfTexture theType)
739 if (theImage.IsEmpty())
741 Release (theCtx.operator->());
748 if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
750 Release (theCtx.operator->());
755 aTextFormat, aPixelFormat, aDataType,
756 (Standard_Integer)theImage.SizeX(),
757 (Standard_Integer)theImage.SizeY(),
761 // =======================================================================
762 // function : Init2DMultisample
764 // =======================================================================
765 bool OpenGl_Texture::Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
766 const GLsizei theNbSamples,
767 const GLint theTextFormat,
768 const GLsizei theSizeX,
769 const GLsizei theSizeY)
772 || theNbSamples > theCtx->MaxMsaaSamples()
778 myNbSamples = OpenGl_Context::GetPowerOfTwo (theNbSamples, theCtx->MaxMsaaSamples());
779 myTarget = GL_TEXTURE_2D_MULTISAMPLE;
780 myHasMipmaps = false;
781 if(theSizeX > theCtx->MaxTextureSize()
782 || theSizeY > theCtx->MaxTextureSize())
788 //myTextFormat = theTextFormat;
789 mySizedFormat = theTextFormat;
790 #if !defined(GL_ES_VERSION_2_0)
791 if (theCtx->Functions()->glTexStorage2DMultisample != NULL)
793 theCtx->Functions()->glTexStorage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
797 theCtx->Functions()->glTexImage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
800 theCtx->Functions() ->glTexStorage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
802 if (theCtx->core11fwd->glGetError() != GL_NO_ERROR)
815 // =======================================================================
816 // function : InitRectangle
818 // =======================================================================
819 bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
820 const Standard_Integer theSizeX,
821 const Standard_Integer theSizeY,
822 const OpenGl_TextureFormat& theFormat)
824 if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (3, 0))
829 #if !defined(GL_ES_VERSION_2_0)
830 myTarget = GL_TEXTURE_RECTANGLE;
832 myHasMipmaps = false;
834 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
835 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
838 applyDefaultSamplerParams (theCtx);
840 myTextFormat = theFormat.Format();
841 mySizedFormat = theFormat.Internal();
843 glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, mySizedFormat,
845 myTextFormat, GL_FLOAT, NULL);
847 GLint aTestSizeX = 0;
848 GLint aTestSizeY = 0;
850 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
851 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
852 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
854 if (aTestSizeX == 0 || aTestSizeY == 0)
860 glTexImage2D (myTarget, 0, mySizedFormat,
862 myTextFormat, GL_FLOAT, NULL);
864 if (glGetError() != GL_NO_ERROR)
883 // =======================================================================
886 // =======================================================================
887 bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
888 const GLint theTextFormat,
889 const GLenum thePixelFormat,
890 const GLenum theDataType,
891 const Standard_Integer theSizeX,
892 const Standard_Integer theSizeY,
893 const Standard_Integer theSizeZ,
894 const void* thePixels)
896 if (theCtx->Functions()->glTexImage3D == NULL)
898 TCollection_ExtendedString aMsg ("Error: three-dimensional textures are not supported by hardware.");
900 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
903 GL_DEBUG_SEVERITY_HIGH,
914 myTarget = GL_TEXTURE_3D;
916 myHasMipmaps = false;
918 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
919 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
920 const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ);
924 if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
926 TCollection_ExtendedString aMsg ("Error: floating-point textures are not supported by hardware.");
928 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
931 GL_DEBUG_SEVERITY_HIGH,
934 Release (theCtx.operator->());
939 mySizedFormat = theTextFormat;
941 #if !defined (GL_ES_VERSION_2_0)
942 theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, mySizedFormat,
943 aSizeX, aSizeY, aSizeZ, 0,
944 thePixelFormat, theDataType, NULL);
946 GLint aTestSizeX = 0;
947 GLint aTestSizeY = 0;
948 GLint aTestSizeZ = 0;
950 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
951 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
952 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ);
953 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
955 if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
958 Release (theCtx.operator->());
963 applyDefaultSamplerParams (theCtx);
964 theCtx->Functions()->glTexImage3D (myTarget, 0, mySizedFormat,
965 aSizeX, aSizeY, aSizeZ, 0,
966 thePixelFormat, theDataType, thePixels);
968 if (glGetError() != GL_NO_ERROR)
971 Release (theCtx.operator->());
983 // =======================================================================
984 // function : PixelSizeOfPixelFormat
986 // =======================================================================
987 Standard_Size OpenGl_Texture::PixelSizeOfPixelFormat (Standard_Integer theInternalFormat)
989 switch(theInternalFormat)
991 // RED variations (GL_RED, OpenGL 3.0+)
993 case GL_R8: return 1;
994 case GL_R16: return 2;
995 case GL_R16F: return 2;
996 case GL_R32F: return 4;
998 case GL_RGB: return 3;
999 case GL_RGB8: return 3;
1000 case GL_RGB16: return 6;
1001 case GL_RGB16F: return 6;
1002 case GL_RGB32F: return 12;
1004 case GL_RGBA: return 4;
1005 case GL_RGBA8: return 4;
1006 case GL_RGB10_A2: return 4;
1007 case GL_RGBA12: return 6;
1008 case GL_RGBA16: return 8;
1009 case GL_RGBA16F: return 8;
1010 case GL_RGBA32F: return 16;
1012 case GL_BGRA_EXT: return 4;
1013 // ALPHA variations (deprecated)
1015 case GL_ALPHA8: return 1;
1016 case GL_ALPHA16: return 2;
1017 case GL_LUMINANCE: return 1;
1018 case GL_LUMINANCE_ALPHA: return 2;
1020 case GL_DEPTH24_STENCIL8: return 4;
1021 case GL_DEPTH32F_STENCIL8: return 8;
1022 case GL_DEPTH_COMPONENT16: return 2;
1023 case GL_DEPTH_COMPONENT24: return 3;
1024 case GL_DEPTH_COMPONENT32F: return 4;
1029 // =======================================================================
1030 // function : EstimatedDataSize
1032 // =======================================================================
1033 Standard_Size OpenGl_Texture::EstimatedDataSize() const
1040 Standard_Size aSize = PixelSizeOfPixelFormat (mySizedFormat) * mySizeX * myNbSamples;
1043 aSize *= Standard_Size(mySizeY);
1047 aSize *= Standard_Size(mySizeZ);
1051 aSize = aSize + aSize / 3;