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 <Graphic3d_TextureParams.hxx>
21 #include <TCollection_ExtendedString.hxx>
22 #include <Standard_Assert.hxx>
23 #include <Image_PixMap.hxx>
26 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture,OpenGl_Resource)
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 Handle(Graphic3d_TextureParams)& theParams)
55 myTextureId (NO_TEXTURE),
56 myTarget (GL_TEXTURE_2D),
60 myTextFormat (GL_RGBA),
61 myHasMipmaps (Standard_False),
65 if (myParams.IsNull())
67 myParams = new Graphic3d_TextureParams();
71 // =======================================================================
72 // function : ~OpenGl_Texture
74 // =======================================================================
75 OpenGl_Texture::~OpenGl_Texture()
80 // =======================================================================
81 // function : HasMipmaps
83 // =======================================================================
84 Standard_Boolean OpenGl_Texture::HasMipmaps() const
89 // =======================================================================
90 // function : GetParams
92 // =======================================================================
93 const Handle(Graphic3d_TextureParams)& OpenGl_Texture::GetParams() const
98 // =======================================================================
99 // function : SetParams
101 // =======================================================================
102 void OpenGl_Texture::SetParams (const Handle(Graphic3d_TextureParams)& theParams)
104 myParams = theParams;
107 // =======================================================================
110 // =======================================================================
111 bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& )
113 if (myTextureId == NO_TEXTURE)
115 glGenTextures (1, &myTextureId);
117 return myTextureId != NO_TEXTURE;
120 // =======================================================================
121 // function : Release
123 // =======================================================================
124 void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
126 if (myTextureId == NO_TEXTURE)
131 // application can not handle this case by exception - this is bug in code
132 Standard_ASSERT_RETURN (theGlCtx != NULL,
133 "OpenGl_Texture destroyed without GL context! Possible GPU memory leakage...",);
135 if (theGlCtx->IsValid())
137 glDeleteTextures (1, &myTextureId);
139 myTextureId = NO_TEXTURE;
140 mySizeX = mySizeY = mySizeZ = 0;
143 // =======================================================================
146 // =======================================================================
147 void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
148 const GLenum theTextureUnit) const
150 if (theCtx->core15fwd != NULL)
152 theCtx->core15fwd->glActiveTexture (theTextureUnit);
154 glBindTexture (myTarget, myTextureId);
157 // =======================================================================
160 // =======================================================================
161 void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
162 const GLenum theTextureUnit) const
164 if (theCtx->core15fwd != NULL)
166 theCtx->core15fwd->glActiveTexture (theTextureUnit);
168 glBindTexture (myTarget, NO_TEXTURE);
171 //=======================================================================
172 //function : GetDataFormat
174 //=======================================================================
175 bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
176 const Image_PixMap& theData,
177 GLint& theTextFormat,
178 GLenum& thePixelFormat,
181 theTextFormat = GL_RGBA8;
184 switch (theData.Format())
186 case Image_Format_GrayF:
188 if (theCtx->core11 == NULL)
190 theTextFormat = GL_R8; // GL_R32F
191 thePixelFormat = GL_RED;
195 theTextFormat = GL_LUMINANCE8;
196 thePixelFormat = GL_LUMINANCE;
198 theDataType = GL_FLOAT;
201 case Image_Format_AlphaF:
203 if (theCtx->core11 == NULL)
205 theTextFormat = GL_R8; // GL_R32F
206 thePixelFormat = GL_RED;
210 theTextFormat = GL_ALPHA8;
211 thePixelFormat = GL_ALPHA;
213 theDataType = GL_FLOAT;
216 case Image_Format_RGBAF:
218 theTextFormat = GL_RGBA8; // GL_RGBA32F
219 thePixelFormat = GL_RGBA;
220 theDataType = GL_FLOAT;
223 case Image_Format_BGRAF:
225 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
229 theTextFormat = GL_RGBA8; // GL_RGBA32F
230 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
231 theDataType = GL_FLOAT;
234 case Image_Format_RGBF:
236 theTextFormat = GL_RGB8; // GL_RGB32F
237 thePixelFormat = GL_RGB;
238 theDataType = GL_FLOAT;
241 case Image_Format_BGRF:
243 #if !defined(GL_ES_VERSION_2_0)
244 theTextFormat = GL_RGB8; // GL_RGB32F
245 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
246 theDataType = GL_FLOAT;
252 case Image_Format_RGBA:
254 theTextFormat = GL_RGBA8;
255 thePixelFormat = GL_RGBA;
256 theDataType = GL_UNSIGNED_BYTE;
259 case Image_Format_BGRA:
261 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
265 theTextFormat = GL_RGBA8;
266 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
267 theDataType = GL_UNSIGNED_BYTE;
270 case Image_Format_RGB32:
272 theTextFormat = GL_RGB8;
273 thePixelFormat = GL_RGBA;
274 theDataType = GL_UNSIGNED_BYTE;
277 case Image_Format_BGR32:
279 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
283 theTextFormat = GL_RGB8;
284 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
285 theDataType = GL_UNSIGNED_BYTE;
288 case Image_Format_RGB:
290 theTextFormat = GL_RGB8;
291 thePixelFormat = GL_RGB;
292 theDataType = GL_UNSIGNED_BYTE;
295 case Image_Format_BGR:
297 #if !defined(GL_ES_VERSION_2_0)
298 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
302 theTextFormat = GL_RGB8;
303 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
304 theDataType = GL_UNSIGNED_BYTE;
310 case Image_Format_Gray:
312 if (theCtx->core11 == NULL)
314 theTextFormat = GL_R8;
315 thePixelFormat = GL_RED;
319 theTextFormat = GL_LUMINANCE8;
320 thePixelFormat = GL_LUMINANCE;
322 theDataType = GL_UNSIGNED_BYTE;
325 case Image_Format_Alpha:
327 if (theCtx->core11 == NULL)
329 theTextFormat = GL_R8;
330 thePixelFormat = GL_RED;
334 theTextFormat = GL_ALPHA8;
335 thePixelFormat = GL_ALPHA;
337 theDataType = GL_UNSIGNED_BYTE;
340 case Image_Format_UNKNOWN:
348 // =======================================================================
351 // =======================================================================
352 bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
353 const Standard_Integer theTextFormat,
354 const GLenum thePixelFormat,
355 const GLenum theDataType,
356 const Standard_Integer theSizeX,
357 const Standard_Integer theSizeY,
358 const Graphic3d_TypeOfTexture theType,
359 const Image_PixMap* theImage)
361 #if !defined(GL_ES_VERSION_2_0)
362 const GLenum aTarget = theType == Graphic3d_TOT_1D
366 const GLenum aTarget = GL_TEXTURE_2D;
368 const Standard_Boolean toCreateMipMaps = (theType == Graphic3d_TOT_2D_MIPMAP);
369 const bool toPatchExisting = IsValid()
370 && myTextFormat == thePixelFormat
371 && myTarget == aTarget
372 && myHasMipmaps == toCreateMipMaps
373 && mySizeX == theSizeX
374 && (mySizeY == theSizeY || theType == Graphic3d_TOT_1D);
375 if (!Create (theCtx))
377 Release (theCtx.operator->());
381 if (theImage != NULL)
383 myIsAlpha = theImage->Format() == Image_Format_Alpha
384 || theImage->Format() == Image_Format_AlphaF;
388 myIsAlpha = thePixelFormat == GL_ALPHA;
391 myHasMipmaps = toCreateMipMaps;
392 myTextFormat = thePixelFormat;
393 #if !defined(GL_ES_VERSION_2_0)
394 const GLint anIntFormat = theTextFormat;
396 // ES does not support sized formats and format conversions - them detected from data type
397 const GLint anIntFormat = thePixelFormat;
398 (void) theTextFormat;
401 const GLsizei aMaxSize = theCtx->MaxTextureSize();
402 if (theSizeX > aMaxSize
403 || theSizeY > aMaxSize)
405 TCollection_ExtendedString aWarnMessage = TCollection_ExtendedString ("Error: Texture dimension - ")
406 + theSizeX + "x" + theSizeY + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")";
408 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
409 Release (theCtx.operator->());
412 #if !defined(GL_ES_VERSION_2_0)
413 else if (!theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW)
415 // Notice that formally general NPOT textures are required by OpenGL 2.0 specifications
416 // however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
417 // Trying to create NPOT textures on such hardware will not fail
418 // but driver will fall back into software rendering,
419 const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
420 const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
422 if (theSizeX != aWidthP2
423 || (theType != Graphic3d_TOT_1D && theSizeY != aHeightP2))
425 TCollection_ExtendedString aWarnMessage =
426 TCollection_ExtendedString ("Error: NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by hardware.";
428 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
430 Release (theCtx.operator->());
435 else if (!theCtx->IsGlGreaterEqual (3, 0) && theType == Graphic3d_TOT_2D_MIPMAP)
437 // Mipmap NPOT textures are not supported by OpenGL ES 2.0.
438 const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
439 const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
441 if (theSizeX != aWidthP2
442 || theSizeY != aHeightP2)
444 TCollection_ExtendedString aWarnMessage =
445 TCollection_ExtendedString ("Error: Mipmap NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by OpenGL ES 2.0";
447 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
449 Release (theCtx.operator->());
455 const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
456 const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
458 #if !defined(GL_ES_VERSION_2_0)
459 GLint aTestWidth = 0;
460 GLint aTestHeight = 0;
462 GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
464 // setup the alignment
465 OpenGl_UnpackAlignmentSentry anUnpackSentry;
466 (void)anUnpackSentry; // avoid compiler warning
468 if (aDataPtr != NULL)
470 const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
471 glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
473 #if !defined(GL_ES_VERSION_2_0)
474 // notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
475 const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
476 const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
477 glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
484 case Graphic3d_TOT_1D:
486 #if !defined(GL_ES_VERSION_2_0)
488 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
489 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
490 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
493 glTexSubImage1D (GL_TEXTURE_1D, 0, 0,
494 theSizeX, thePixelFormat, theDataType, aDataPtr);
499 // use proxy to check texture could be created or not
500 glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat,
502 thePixelFormat, theDataType, NULL);
503 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
506 // no memory or broken input parameters
508 Release (theCtx.operator->());
512 glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat,
514 thePixelFormat, theDataType, aDataPtr);
515 if (glGetError() != GL_NO_ERROR)
518 Release (theCtx.operator->());
528 Release (theCtx.operator->());
532 case Graphic3d_TOT_2D:
535 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter);
536 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
537 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
538 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
541 glTexSubImage2D (GL_TEXTURE_2D, 0,
544 thePixelFormat, theDataType, aDataPtr);
549 #if !defined(GL_ES_VERSION_2_0)
550 // use proxy to check texture could be created or not
551 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
552 theSizeX, theSizeY, 0,
553 thePixelFormat, theDataType, NULL);
554 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
555 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
556 if (aTestWidth == 0 || aTestHeight == 0)
558 // no memory or broken input parameters
560 Release (theCtx.operator->());
565 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
566 theSizeX, theSizeY, 0,
567 thePixelFormat, theDataType, aDataPtr);
568 if (glGetError() != GL_NO_ERROR)
571 Release (theCtx.operator->());
581 case Graphic3d_TOT_2D_MIPMAP:
583 GLenum aFilterMin = aFilter;
584 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
585 if (myParams->Filter() == Graphic3d_TOTF_BILINEAR)
587 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
589 else if (myParams->Filter() == Graphic3d_TOTF_TRILINEAR)
591 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
595 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
596 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
597 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
598 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
601 glTexSubImage2D (GL_TEXTURE_2D, 0,
604 thePixelFormat, theDataType, aDataPtr);
605 if (theCtx->arbFBO != NULL)
608 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
609 if (glGetError() != GL_NO_ERROR)
612 Release (theCtx.operator->());
621 #if !defined(GL_ES_VERSION_2_0)
622 // use proxy to check texture could be created or not
623 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
624 theSizeX, theSizeY, 0,
625 thePixelFormat, theDataType, NULL);
626 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
627 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
628 if (aTestWidth == 0 || aTestHeight == 0)
630 // no memory or broken input parameters
632 Release (theCtx.operator->());
637 // upload main picture
638 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
639 theSizeX, theSizeY, 0,
640 thePixelFormat, theDataType, theImage->Data());
641 if (glGetError() != GL_NO_ERROR)
644 Release (theCtx.operator->());
651 if (theCtx->arbFBO != NULL)
654 //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST);
655 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
657 if (glGetError() != GL_NO_ERROR)
660 Release (theCtx.operator->());
666 const TCollection_ExtendedString aWarnMessage ("Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing.");
668 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
671 Release (theCtx.operator->());
680 Release (theCtx.operator->());
684 // =======================================================================
687 // =======================================================================
688 bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
689 const Image_PixMap& theImage,
690 const Graphic3d_TypeOfTexture theType)
692 if (theImage.IsEmpty())
694 Release (theCtx.operator->());
701 if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
703 Release (theCtx.operator->());
708 aTextFormat, aPixelFormat, aDataType,
709 (Standard_Integer)theImage.SizeX(),
710 (Standard_Integer)theImage.SizeY(),
714 // =======================================================================
715 // function : Init2DMultisample
717 // =======================================================================
718 bool OpenGl_Texture::Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
719 const GLsizei theNbSamples,
720 const GLint theTextFormat,
721 const GLsizei theSizeX,
722 const GLsizei theSizeY)
725 || theNbSamples > theCtx->MaxMsaaSamples()
731 const GLsizei aNbSamples = OpenGl_Context::GetPowerOfTwo (theNbSamples, theCtx->MaxMsaaSamples());
732 myTarget = GL_TEXTURE_2D_MULTISAMPLE;
733 if(theSizeX > theCtx->MaxTextureSize()
734 || theSizeY > theCtx->MaxTextureSize())
740 //myTextFormat = theTextFormat;
741 #if !defined(GL_ES_VERSION_2_0)
742 if (theCtx->Functions()->glTexStorage2DMultisample != NULL)
744 theCtx->Functions()->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
748 theCtx->Functions()->glTexImage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
751 theCtx->Functions() ->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
753 if (theCtx->core11fwd->glGetError() != GL_NO_ERROR)
766 // =======================================================================
767 // function : InitRectangle
769 // =======================================================================
770 bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
771 const Standard_Integer theSizeX,
772 const Standard_Integer theSizeY,
773 const OpenGl_TextureFormat& theFormat)
775 if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (3, 0))
780 #if !defined(GL_ES_VERSION_2_0)
781 myTarget = GL_TEXTURE_RECTANGLE;
783 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
784 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
785 const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
786 const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
789 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
790 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
791 glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
792 glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
794 const GLint anIntFormat = theFormat.Internal();
795 myTextFormat = theFormat.Format();
797 glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE,
807 GLint aTestSizeX = 0;
808 GLint aTestSizeY = 0;
810 glGetTexLevelParameteriv (
811 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
812 glGetTexLevelParameteriv (
813 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
815 if (aTestSizeX == 0 || aTestSizeY == 0)
821 glTexImage2D (myTarget,
831 if (glGetError() != GL_NO_ERROR)
850 // =======================================================================
853 // =======================================================================
854 bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
855 const GLint theTextFormat,
856 const GLenum thePixelFormat,
857 const GLenum theDataType,
858 const Standard_Integer theSizeX,
859 const Standard_Integer theSizeY,
860 const Standard_Integer theSizeZ,
861 const void* thePixels)
863 if (theCtx->Functions()->glTexImage3D == NULL)
865 TCollection_ExtendedString aMsg ("Error: three-dimensional textures are not supported by hardware.");
867 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
870 GL_DEBUG_SEVERITY_HIGH,
881 myTarget = GL_TEXTURE_3D;
883 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
884 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
885 const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ);
889 if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
891 TCollection_ExtendedString aMsg ("Error: floating-point textures are not supported by hardware.");
893 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
896 GL_DEBUG_SEVERITY_HIGH,
899 Release (theCtx.operator->());
904 const GLint anIntFormat = theTextFormat;
906 #if !defined (GL_ES_VERSION_2_0)
907 theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D,
918 GLint aTestSizeX = 0;
919 GLint aTestSizeY = 0;
920 GLint aTestSizeZ = 0;
922 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
923 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
924 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ);
926 if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
929 Release (theCtx.operator->());
934 const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
935 const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
937 glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
938 glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
939 glTexParameteri (myTarget, GL_TEXTURE_WRAP_R, aWrapMode);
941 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
942 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
944 theCtx->Functions()->glTexImage3D (myTarget,
955 if (glGetError() != GL_NO_ERROR)
958 Release (theCtx.operator->());