From 633084b80933b05fe384fc581ed2e7f7d06c0fe7 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 2 Mar 2022 15:21:22 +0300 Subject: [PATCH] 0032862: Visualization, Graphic3d_TextureMap - add 3D texture definition Image_PixMap has been extended to support definition of 3D bitmap (as an array of 2D slices). Graphic3d_TypeOfTexture enumeration values have been renamed to include full enum prefix. Added Graphic3d_TypeOfTexture_3D redirecting to GL_TEXTURE_3D. OpenGl_Texture::Init() has been extended to allow initialization of 3D texture. Graphic3d_Texture2Dmanual merged into Graphic3d_Texture2D and marked as deprecated alias. Graphic3d_TOT_2D_MIPMAP has been deprecated in favor of dedicated Graphic3d_TextureRoot::SetMipMaps(). Added Graphic3d_Texture3D class. vtexture - added argument -3d for uploading 3D texture. --- samples/OCCTOverview/code/Sample2D_Image.cxx | 6 +- src/AIS/AIS_TexturedShape.cxx | 8 +- src/AIS/AIS_TexturedShape.hxx | 4 +- src/AIS/AIS_XRTrackedDevice.cxx | 4 +- src/D3DHost/D3DHost_FrameBuffer.cxx | 2 +- src/Graphic3d/FILES | 3 +- src/Graphic3d/Graphic3d_CubeMap.cxx | 37 ++ src/Graphic3d/Graphic3d_CubeMap.hxx | 23 +- src/Graphic3d/Graphic3d_MediaTexture.cxx | 2 +- src/Graphic3d/Graphic3d_Texture1Dmanual.cxx | 10 +- src/Graphic3d/Graphic3d_Texture1Dmanual.hxx | 36 +- src/Graphic3d/Graphic3d_Texture1Dsegment.cxx | 6 +- src/Graphic3d/Graphic3d_Texture2D.cxx | 49 +++ src/Graphic3d/Graphic3d_Texture2D.hxx | 19 +- src/Graphic3d/Graphic3d_Texture2Dmanual.cxx | 58 --- src/Graphic3d/Graphic3d_Texture2Dmanual.hxx | 25 +- src/Graphic3d/Graphic3d_Texture2Dplane.cxx | 15 +- src/Graphic3d/Graphic3d_Texture3D.cxx | 127 +++++++ src/Graphic3d/Graphic3d_Texture3D.hxx | 51 +++ src/Graphic3d/Graphic3d_TextureEnv.cxx | 9 +- src/Graphic3d/Graphic3d_TextureRoot.cxx | 10 +- src/Graphic3d/Graphic3d_TextureRoot.hxx | 8 +- src/Graphic3d/Graphic3d_TypeOfTexture.hxx | 24 +- src/Image/Image_PixMap.cxx | 361 ++++++++++-------- src/Image/Image_PixMap.hxx | 350 +++++++++++++----- src/Image/Image_PixMapData.hxx | 120 ++++-- src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx | 8 +- src/OpenGl/OpenGl_AspectsSprite.cxx | 4 +- src/OpenGl/OpenGl_Context.cxx | 4 +- src/OpenGl/OpenGl_Font.cxx | 2 +- src/OpenGl/OpenGl_FrameBuffer.cxx | 6 +- src/OpenGl/OpenGl_PBREnvironment.cxx | 6 +- src/OpenGl/OpenGl_Sampler.cxx | 12 +- src/OpenGl/OpenGl_Texture.cxx | 362 +++++++++++-------- src/OpenGl/OpenGl_Texture.hxx | 39 +- src/OpenGl/OpenGl_TileSampler.cxx | 2 +- src/OpenGl/OpenGl_View.cxx | 8 +- src/OpenGl/OpenGl_View_Raytrace.cxx | 4 +- src/QABugs/QABugs_1.cxx | 2 +- src/V3d/V3d_View.cxx | 2 +- src/ViewerTest/ViewerTest.cxx | 74 ++-- src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 10 + src/ViewerTest/ViewerTest_ViewerCommands.cxx | 8 +- src/XCAFPrs/XCAFPrs_Texture.cxx | 4 +- src/XCAFPrs/XCAFPrs_Texture.hxx | 4 +- tests/opengl/data/textures/cubemap_jpg | 2 - tests/opengl/data/textures/texture_3d | 60 +++ 47 files changed, 1327 insertions(+), 663 deletions(-) delete mode 100644 src/Graphic3d/Graphic3d_Texture2Dmanual.cxx create mode 100644 src/Graphic3d/Graphic3d_Texture3D.cxx create mode 100644 src/Graphic3d/Graphic3d_Texture3D.hxx create mode 100644 tests/opengl/data/textures/texture_3d diff --git a/samples/OCCTOverview/code/Sample2D_Image.cxx b/samples/OCCTOverview/code/Sample2D_Image.cxx index 3e833ee206..e86f849365 100644 --- a/samples/OCCTOverview/code/Sample2D_Image.cxx +++ b/samples/OCCTOverview/code/Sample2D_Image.cxx @@ -26,9 +26,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include @@ -81,7 +79,7 @@ void Sample2D_Image::SetContext (const Handle(AIS_InteractiveContext)& theContex this->Set(TopoDS_Shape(myFace)); myDrawer->SetShadingAspect(new Prs3d_ShadingAspect()); - Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(myFilename); + Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D (myFilename); aTexture->DisableModulate(); myDrawer->ShadingAspect()->Aspect()->SetTextureMap (aTexture); myDrawer->ShadingAspect()->Aspect()->SetTextureMapOn(); diff --git a/src/AIS/AIS_TexturedShape.cxx b/src/AIS/AIS_TexturedShape.cxx index 46e2dc6aa0..1cb792082f 100644 --- a/src/AIS/AIS_TexturedShape.cxx +++ b/src/AIS/AIS_TexturedShape.cxx @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -278,17 +278,17 @@ void AIS_TexturedShape::updateAttributes (const Handle(Prs3d_Presentation)& theP TCollection_AsciiString aTextureDesc; if (!myTexturePixMap.IsNull()) { - myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap); + myTexture = new Graphic3d_Texture2D (myTexturePixMap); aTextureDesc = " (custom image)"; } else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN) { - myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture); + myTexture = new Graphic3d_Texture2D (myPredefTexture); aTextureDesc = TCollection_AsciiString(" (predefined texture ") + myTexture->GetId() + ")"; } else { - myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString()); + myTexture = new Graphic3d_Texture2D (myTextureFile.ToCString()); aTextureDesc = TCollection_AsciiString(" (") + myTextureFile + ")"; } diff --git a/src/AIS/AIS_TexturedShape.hxx b/src/AIS/AIS_TexturedShape.hxx index 270470f3a1..c814e3d475 100644 --- a/src/AIS/AIS_TexturedShape.hxx +++ b/src/AIS/AIS_TexturedShape.hxx @@ -26,7 +26,7 @@ #include class Graphic3d_AspectFillArea3d; -class Graphic3d_Texture2Dmanual; +class Graphic3d_Texture2D; //! This class allows to map textures on shapes. //! Presentations modes AIS_WireFrame (0) and AIS_Shaded (1) behave in the same manner as in AIS_Shape, @@ -184,7 +184,7 @@ protected: //! @name overridden methods protected: //! @name presentation fields - Handle(Graphic3d_Texture2Dmanual) myTexture; + Handle(Graphic3d_Texture2D) myTexture; Handle(Graphic3d_AspectFillArea3d) myAspect; protected: //! @name texture source fields diff --git a/src/AIS/AIS_XRTrackedDevice.cxx b/src/AIS/AIS_XRTrackedDevice.cxx index af435d50b6..e64ec1d582 100644 --- a/src/AIS/AIS_XRTrackedDevice.cxx +++ b/src/AIS/AIS_XRTrackedDevice.cxx @@ -23,14 +23,14 @@ #include //! Texture holder. -class AIS_XRTrackedDevice::XRTexture : public Graphic3d_Texture2Dmanual +class AIS_XRTrackedDevice::XRTexture : public Graphic3d_Texture2D { public: //! Constructor. XRTexture (const Handle(Image_Texture)& theImageSource, const Graphic3d_TextureUnit theUnit = Graphic3d_TextureUnit_BaseColor) - : Graphic3d_Texture2Dmanual (""), myImageSource (theImageSource) + : Graphic3d_Texture2D (""), myImageSource (theImageSource) { if (!theImageSource->TextureId().IsEmpty()) { diff --git a/src/D3DHost/D3DHost_FrameBuffer.cxx b/src/D3DHost/D3DHost_FrameBuffer.cxx index 209f57b04d..60aef01396 100644 --- a/src/D3DHost/D3DHost_FrameBuffer.cxx +++ b/src/D3DHost/D3DHost_FrameBuffer.cxx @@ -195,7 +195,7 @@ Standard_Boolean D3DHost_FrameBuffer::InitD3dInterop (const Handle(OpenGl_Contex const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theCtx, myDepthFormat); if (aDepthFormat.IsValid() - && !myDepthStencilTexture->Init (theCtx, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D)) + && !myDepthStencilTexture->Init (theCtx, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D)) { Release (theCtx.get()); theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index 71ca2e7dff..ec1f20b4df 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -154,10 +154,11 @@ Graphic3d_Texture1Dsegment.cxx Graphic3d_Texture1Dsegment.hxx Graphic3d_Texture2D.cxx Graphic3d_Texture2D.hxx -Graphic3d_Texture2Dmanual.cxx Graphic3d_Texture2Dmanual.hxx Graphic3d_Texture2Dplane.cxx Graphic3d_Texture2Dplane.hxx +Graphic3d_Texture3D.cxx +Graphic3d_Texture3D.hxx Graphic3d_TextureEnv.cxx Graphic3d_TextureEnv.hxx Graphic3d_TextureMap.cxx diff --git a/src/Graphic3d/Graphic3d_CubeMap.cxx b/src/Graphic3d/Graphic3d_CubeMap.cxx index f4c95aa738..4d2abb1b84 100644 --- a/src/Graphic3d/Graphic3d_CubeMap.cxx +++ b/src/Graphic3d/Graphic3d_CubeMap.cxx @@ -15,3 +15,40 @@ #include IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMap, Graphic3d_TextureMap) + +// ======================================================================= +// function : Graphic3d_CubeMap +// purpose : +// ======================================================================= +Graphic3d_CubeMap::Graphic3d_CubeMap (const TCollection_AsciiString& theFileName, + Standard_Boolean theToGenerateMipmaps) +: Graphic3d_TextureMap (theFileName, Graphic3d_TypeOfTexture_CUBEMAP), + myCurrentSide (Graphic3d_CMS_POS_X), + myEndIsReached (false), + myZIsInverted (false) +{ + myHasMipmaps = theToGenerateMipmaps; +} + +// ======================================================================= +// function : Graphic3d_CubeMap +// purpose : +// ======================================================================= +Graphic3d_CubeMap::Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap, + Standard_Boolean theToGenerateMipmaps) +: Graphic3d_TextureMap (thePixmap, Graphic3d_TypeOfTexture_CUBEMAP), + myCurrentSide (Graphic3d_CMS_POS_X), + myEndIsReached (false), + myZIsInverted (false) +{ + myHasMipmaps = theToGenerateMipmaps; +} + +// ======================================================================= +// function : ~Graphic3d_CubeMap +// purpose : +// ======================================================================= +Graphic3d_CubeMap::~Graphic3d_CubeMap() +{ + // +} diff --git a/src/Graphic3d/Graphic3d_CubeMap.hxx b/src/Graphic3d/Graphic3d_CubeMap.hxx index 52473ee244..0566c97c84 100644 --- a/src/Graphic3d/Graphic3d_CubeMap.hxx +++ b/src/Graphic3d/Graphic3d_CubeMap.hxx @@ -26,24 +26,12 @@ class Graphic3d_CubeMap : public Graphic3d_TextureMap public: //! Constructor defining loading cubemap from file. - Graphic3d_CubeMap (const TCollection_AsciiString& theFileName, - Standard_Boolean theToGenerateMipmaps = Standard_False) : - Graphic3d_TextureMap (theFileName, Graphic3d_TOT_CUBEMAP), - myCurrentSide (Graphic3d_CMS_POS_X), - myEndIsReached (false), - myZIsInverted (false), - myHasMipmaps (theToGenerateMipmaps) - {} + Standard_EXPORT Graphic3d_CubeMap (const TCollection_AsciiString& theFileName, + Standard_Boolean theToGenerateMipmaps = Standard_False); //! Constructor defining direct cubemap initialization from PixMap. - Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)(), - Standard_Boolean theToGenerateMipmaps = Standard_False) : - Graphic3d_TextureMap (thePixmap, Graphic3d_TOT_CUBEMAP), - myCurrentSide (Graphic3d_CMS_POS_X), - myEndIsReached (false), - myZIsInverted (false), - myHasMipmaps (theToGenerateMipmaps) - {} + Standard_EXPORT Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)(), + Standard_Boolean theToGenerateMipmaps = Standard_False); //! Returns whether the iterator has reached the end (true if it hasn't). Standard_Boolean More() const { return !myEndIsReached; } @@ -100,14 +88,13 @@ public: } //! Empty destructor. - ~Graphic3d_CubeMap() {} + Standard_EXPORT virtual ~Graphic3d_CubeMap(); protected: Graphic3d_CubeMapSide myCurrentSide; //!< Iterator state Standard_Boolean myEndIsReached; //!< Indicates whether end of iteration has been reached or hasn't Standard_Boolean myZIsInverted; //!< Indicates whether Z axis is inverted that allows to synchronize vertical flip of cubemap - Standard_Boolean myHasMipmaps; //!< Indicates whether mipmaps of cubemap will be generated or not }; diff --git a/src/Graphic3d/Graphic3d_MediaTexture.cxx b/src/Graphic3d/Graphic3d_MediaTexture.cxx index 15dde8ee76..1683203ea2 100644 --- a/src/Graphic3d/Graphic3d_MediaTexture.cxx +++ b/src/Graphic3d/Graphic3d_MediaTexture.cxx @@ -42,7 +42,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MediaTexture, Graphic3d_Texture2D) // ================================================================ Graphic3d_MediaTexture::Graphic3d_MediaTexture (const Handle(Standard_HMutex)& theMutex, Standard_Integer thePlane) -: Graphic3d_Texture2D ("", Graphic3d_TOT_2D), +: Graphic3d_Texture2D ("", Graphic3d_TypeOfTexture_2D), myMutex (theMutex), myPlane (thePlane) { diff --git a/src/Graphic3d/Graphic3d_Texture1Dmanual.cxx b/src/Graphic3d/Graphic3d_Texture1Dmanual.cxx index c7992d5ef4..aa73878ef0 100644 --- a/src/Graphic3d/Graphic3d_Texture1Dmanual.cxx +++ b/src/Graphic3d/Graphic3d_Texture1Dmanual.cxx @@ -14,10 +14,8 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include -#include -#include + #include IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture1Dmanual,Graphic3d_Texture1D) @@ -27,7 +25,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture1Dmanual,Graphic3d_Texture1D) // purpose : // ======================================================================= Graphic3d_Texture1Dmanual::Graphic3d_Texture1Dmanual (const TCollection_AsciiString& theFileName) -: Graphic3d_Texture1D (theFileName, Graphic3d_TOT_1D) +: Graphic3d_Texture1D (theFileName, Graphic3d_TypeOfTexture_1D) { // } @@ -37,7 +35,7 @@ Graphic3d_Texture1Dmanual::Graphic3d_Texture1Dmanual (const TCollection_AsciiStr // purpose : // ======================================================================= Graphic3d_Texture1Dmanual::Graphic3d_Texture1Dmanual (const Graphic3d_NameOfTexture1D theNOT) -: Graphic3d_Texture1D (theNOT, Graphic3d_TOT_1D) +: Graphic3d_Texture1D (theNOT, Graphic3d_TypeOfTexture_1D) { // } @@ -47,7 +45,7 @@ Graphic3d_Texture1Dmanual::Graphic3d_Texture1Dmanual (const Graphic3d_NameOfText // purpose : // ======================================================================= Graphic3d_Texture1Dmanual::Graphic3d_Texture1Dmanual (const Handle(Image_PixMap)& thePixMap) -: Graphic3d_Texture1D (thePixMap, Graphic3d_TOT_1D) +: Graphic3d_Texture1D (thePixMap, Graphic3d_TypeOfTexture_1D) { // } diff --git a/src/Graphic3d/Graphic3d_Texture1Dmanual.hxx b/src/Graphic3d/Graphic3d_Texture1Dmanual.hxx index dacc01948e..835bd91132 100644 --- a/src/Graphic3d/Graphic3d_Texture1Dmanual.hxx +++ b/src/Graphic3d/Graphic3d_Texture1Dmanual.hxx @@ -17,55 +17,27 @@ #ifndef _Graphic3d_Texture1Dmanual_HeaderFile #define _Graphic3d_Texture1Dmanual_HeaderFile -#include -#include - #include #include -class TCollection_AsciiString; - -class Graphic3d_Texture1Dmanual; DEFINE_STANDARD_HANDLE(Graphic3d_Texture1Dmanual, Graphic3d_Texture1D) //! This class provides the implementation of a manual 1D texture. -//! you MUST provides texture coordinates on your facets if you want to see your texture. +//! you MUST provide texture coordinates on your facets if you want to see your texture. class Graphic3d_Texture1Dmanual : public Graphic3d_Texture1D { - + DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture1Dmanual, Graphic3d_Texture1D) public: - //! Creates a texture from the file FileName. Standard_EXPORT Graphic3d_Texture1Dmanual(const TCollection_AsciiString& theFileName); - + //! Create a texture from a predefined texture name set. Standard_EXPORT Graphic3d_Texture1Dmanual(const Graphic3d_NameOfTexture1D theNOT); - + //! Creates a texture from the pixmap. Standard_EXPORT Graphic3d_Texture1Dmanual(const Handle(Image_PixMap)& thePixMap); - - - - DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture1Dmanual,Graphic3d_Texture1D) - -protected: - - - - -private: - - - - }; - - - - - - #endif // _Graphic3d_Texture1Dmanual_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Texture1Dsegment.cxx b/src/Graphic3d/Graphic3d_Texture1Dsegment.cxx index 41e134f867..89c6aa9e82 100644 --- a/src/Graphic3d/Graphic3d_Texture1Dsegment.cxx +++ b/src/Graphic3d/Graphic3d_Texture1Dsegment.cxx @@ -28,7 +28,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture1Dsegment,Graphic3d_Texture1D) // purpose : // ======================================================================= Graphic3d_Texture1Dsegment::Graphic3d_Texture1Dsegment (const TCollection_AsciiString& theFileName) -: Graphic3d_Texture1D (theFileName, Graphic3d_TOT_1D), +: Graphic3d_Texture1D (theFileName, Graphic3d_TypeOfTexture_1D), myX1 (0.0f), myY1 (0.0f), myZ1 (0.0f), @@ -47,7 +47,7 @@ Graphic3d_Texture1Dsegment::Graphic3d_Texture1Dsegment (const TCollection_AsciiS // purpose : // ======================================================================= Graphic3d_Texture1Dsegment::Graphic3d_Texture1Dsegment (const Graphic3d_NameOfTexture1D theNOT) -: Graphic3d_Texture1D (theNOT, Graphic3d_TOT_1D), +: Graphic3d_Texture1D (theNOT, Graphic3d_TypeOfTexture_1D), myX1 (0.0f), myY1 (0.0f), myZ1 (0.0f), @@ -66,7 +66,7 @@ Graphic3d_Texture1Dsegment::Graphic3d_Texture1Dsegment (const Graphic3d_NameOfTe // purpose : // ======================================================================= Graphic3d_Texture1Dsegment::Graphic3d_Texture1Dsegment (const Handle(Image_PixMap)& thePixMap) -: Graphic3d_Texture1D (thePixMap, Graphic3d_TOT_1D), +: Graphic3d_Texture1D (thePixMap, Graphic3d_TypeOfTexture_1D), myX1 (0.0f), myY1 (0.0f), myZ1 (0.0f), diff --git a/src/Graphic3d/Graphic3d_Texture2D.cxx b/src/Graphic3d/Graphic3d_Texture2D.cxx index be3a4944d8..bee71e8d42 100644 --- a/src/Graphic3d/Graphic3d_Texture2D.cxx +++ b/src/Graphic3d/Graphic3d_Texture2D.cxx @@ -16,6 +16,7 @@ #include +#include #include IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture2D,Graphic3d_TextureMap) @@ -46,6 +47,20 @@ static const char *NameOfTexture2d_to_FileName[] = "2d_chess.rgba" }; +// ======================================================================= +// function : Graphic3d_Texture2D +// purpose : +// ======================================================================= +Graphic3d_Texture2D::Graphic3d_Texture2D (const TCollection_AsciiString& theFileName) +: Graphic3d_TextureMap (theFileName, Graphic3d_TypeOfTexture_2D), + myName (Graphic3d_NOT_2D_UNKNOWN) +{ + myHasMipmaps = true; + myParams->SetModulate (true); + myParams->SetRepeat (true); + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); +} + // ======================================================================= // function : Graphic3d_Texture2D // purpose : @@ -55,6 +70,25 @@ Graphic3d_Texture2D::Graphic3d_Texture2D (const TCollection_AsciiString& theFile : Graphic3d_TextureMap (theFileName, theType), myName (Graphic3d_NOT_2D_UNKNOWN) { + // +} + +// ======================================================================= +// function : Graphic3d_Texture2D +// purpose : +// ======================================================================= +Graphic3d_Texture2D::Graphic3d_Texture2D (const Graphic3d_NameOfTexture2D theNOT) +: Graphic3d_TextureMap (NameOfTexture2d_to_FileName[theNOT], Graphic3d_TypeOfTexture_2D), + myName (theNOT) +{ + myPath.SetTrek (Graphic3d_TextureRoot::TexturesFolder()); + myTexId = TCollection_AsciiString ("Graphic3d_Texture2D_") + + NameOfTexture2d_to_FileName[theNOT]; + + myHasMipmaps = true; + myParams->SetModulate (true); + myParams->SetRepeat (true); + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); } // ======================================================================= @@ -71,6 +105,20 @@ Graphic3d_Texture2D::Graphic3d_Texture2D (const Graphic3d_NameOfTexture2D theNOT + NameOfTexture2d_to_FileName[theNOT]; } +// ======================================================================= +// function : Graphic3d_Texture2D +// purpose : +// ======================================================================= +Graphic3d_Texture2D::Graphic3d_Texture2D (const Handle(Image_PixMap)& thePixMap) +: Graphic3d_TextureMap (thePixMap, Graphic3d_TypeOfTexture_2D), + myName (Graphic3d_NOT_2D_UNKNOWN) +{ + myHasMipmaps = true; + myParams->SetModulate (true); + myParams->SetRepeat (true); + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); +} + // ======================================================================= // function : Graphic3d_Texture2D // purpose : @@ -80,6 +128,7 @@ Graphic3d_Texture2D::Graphic3d_Texture2D (const Handle(Image_PixMap)& thePixM : Graphic3d_TextureMap (thePixMap, theType), myName (Graphic3d_NOT_2D_UNKNOWN) { + // } // ======================================================================= diff --git a/src/Graphic3d/Graphic3d_Texture2D.hxx b/src/Graphic3d/Graphic3d_Texture2D.hxx index 1a64bfcaed..7a9f84db90 100644 --- a/src/Graphic3d/Graphic3d_Texture2D.hxx +++ b/src/Graphic3d/Graphic3d_Texture2D.hxx @@ -34,6 +34,18 @@ public: public: + //! Creates a texture from a file. + //! MipMaps levels will be automatically generated if needed. + Standard_EXPORT Graphic3d_Texture2D (const TCollection_AsciiString& theFileName); + + //! Creates a texture from a predefined texture name set. + //! MipMaps levels will be automatically generated if needed. + Standard_EXPORT Graphic3d_Texture2D (const Graphic3d_NameOfTexture2D theNOT); + + //! Creates a texture from the pixmap. + //! MipMaps levels will be automatically generated if needed. + Standard_EXPORT Graphic3d_Texture2D (const Handle(Image_PixMap)& thePixMap); + //! Returns the name of the predefined textures or NOT_2D_UNKNOWN //! when the name is given as a filename. Standard_EXPORT Graphic3d_NameOfTexture2D Name() const; @@ -42,13 +54,6 @@ public: //! Note that this method does not invalidate already uploaded resources - consider calling ::UpdateRevision() if needed. Standard_EXPORT void SetImage (const Handle(Image_PixMap)& thePixMap); - //! Return true if mip-maps should be used. - Standard_Boolean HasMipMaps() const { return myType == Graphic3d_TOT_2D_MIPMAP; } - - //! Set if mip-maps should be used (generated if needed). - //! Note that this method should be called before loading / using the texture. - void SetMipMaps (const Standard_Boolean theToUse) { myType = theToUse ? Graphic3d_TOT_2D_MIPMAP : Graphic3d_TOT_2D; } - protected: Standard_EXPORT Graphic3d_Texture2D(const TCollection_AsciiString& theFileName, const Graphic3d_TypeOfTexture theType); diff --git a/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx b/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx deleted file mode 100644 index d15d21bbd5..0000000000 --- a/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx +++ /dev/null @@ -1,58 +0,0 @@ -// Created on: 1997-07-28 -// Created by: Pierre CHALAMET -// Copyright (c) 1997-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture2Dmanual,Graphic3d_Texture2D) - -// ======================================================================= -// function : Graphic3d_Texture2Dmanual -// purpose : -// ======================================================================= -Graphic3d_Texture2Dmanual::Graphic3d_Texture2Dmanual (const TCollection_AsciiString& theFileName) -: Graphic3d_Texture2D (theFileName, Graphic3d_TOT_2D_MIPMAP) -{ - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); -} - -// ======================================================================= -// function : Graphic3d_Texture2Dmanual -// purpose : -// ======================================================================= -Graphic3d_Texture2Dmanual::Graphic3d_Texture2Dmanual (const Graphic3d_NameOfTexture2D theNOT) -: Graphic3d_Texture2D (theNOT, Graphic3d_TOT_2D_MIPMAP) -{ - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); -} - -// ======================================================================= -// function : Graphic3d_Texture2Dmanual -// purpose : -// ======================================================================= -Graphic3d_Texture2Dmanual::Graphic3d_Texture2Dmanual (const Handle(Image_PixMap)& thePixMap) -: Graphic3d_Texture2D (thePixMap, Graphic3d_TOT_2D_MIPMAP) -{ - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); -} diff --git a/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx b/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx index 4389c23dec..76c00d226e 100644 --- a/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx +++ b/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx @@ -20,28 +20,7 @@ #include #include -//! This class defined a manual texture 2D -//! facets MUST define texture coordinate -//! if you want to see somethings on. -class Graphic3d_Texture2Dmanual : public Graphic3d_Texture2D -{ - DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture2Dmanual,Graphic3d_Texture2D) -public: - - //! Creates a texture from a file. - //! MipMaps levels will be automatically generated if needed. - Standard_EXPORT Graphic3d_Texture2Dmanual(const TCollection_AsciiString& theFileName); - - //! Creates a texture from a predefined texture name set. - //! MipMaps levels will be automatically generated if needed. - Standard_EXPORT Graphic3d_Texture2Dmanual(const Graphic3d_NameOfTexture2D theNOT); - - //! Creates a texture from the pixmap. - //! MipMaps levels will be automatically generated if needed. - Standard_EXPORT Graphic3d_Texture2Dmanual(const Handle(Image_PixMap)& thePixMap); - -}; - -DEFINE_STANDARD_HANDLE(Graphic3d_Texture2Dmanual, Graphic3d_Texture2D) +Standard_DEPRECATED ("Deprecated alias to Graphic3d_Texture2D") +typedef Graphic3d_Texture2D Graphic3d_Texture2Dmanual; #endif // _Graphic3d_Texture2Dmanual_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Texture2Dplane.cxx b/src/Graphic3d/Graphic3d_Texture2Dplane.cxx index 9e599a8dee..075ed4429a 100644 --- a/src/Graphic3d/Graphic3d_Texture2Dplane.cxx +++ b/src/Graphic3d/Graphic3d_Texture2Dplane.cxx @@ -28,11 +28,8 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture2Dplane,Graphic3d_Texture2D) // purpose : // ======================================================================= Graphic3d_Texture2Dplane::Graphic3d_Texture2Dplane (const TCollection_AsciiString& theFileName) -: Graphic3d_Texture2D (theFileName, Graphic3d_TOT_2D_MIPMAP) +: Graphic3d_Texture2D (theFileName) { - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); myParams->SetGenMode (Graphic3d_TOTM_OBJECT, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f), Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); @@ -43,11 +40,8 @@ Graphic3d_Texture2Dplane::Graphic3d_Texture2Dplane (const TCollection_AsciiStrin // purpose : // ======================================================================= Graphic3d_Texture2Dplane::Graphic3d_Texture2Dplane (const Graphic3d_NameOfTexture2D theNOT) -: Graphic3d_Texture2D (theNOT, Graphic3d_TOT_2D_MIPMAP) +: Graphic3d_Texture2D (theNOT) { - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); myParams->SetGenMode (Graphic3d_TOTM_OBJECT, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f), Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); @@ -58,11 +52,8 @@ Graphic3d_Texture2Dplane::Graphic3d_Texture2Dplane (const Graphic3d_NameOfTextur // purpose : // ======================================================================= Graphic3d_Texture2Dplane::Graphic3d_Texture2Dplane (const Handle(Image_PixMap)& thePixMap) -: Graphic3d_Texture2D (thePixMap, Graphic3d_TOT_2D_MIPMAP) +: Graphic3d_Texture2D (thePixMap) { - myParams->SetModulate (Standard_True); - myParams->SetRepeat (Standard_True); - myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); myParams->SetGenMode (Graphic3d_TOTM_OBJECT, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f), Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); diff --git a/src/Graphic3d/Graphic3d_Texture3D.cxx b/src/Graphic3d/Graphic3d_Texture3D.cxx new file mode 100644 index 0000000000..f74849b164 --- /dev/null +++ b/src/Graphic3d/Graphic3d_Texture3D.cxx @@ -0,0 +1,127 @@ +// Copyright (c) 2022 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture3D, Graphic3d_TextureMap) + +// ======================================================================= +// function : Graphic3d_Texture3D +// purpose : +// ======================================================================= +Graphic3d_Texture3D::Graphic3d_Texture3D (const TCollection_AsciiString& theFileName) +: Graphic3d_TextureMap (theFileName, Graphic3d_TypeOfTexture_3D) +{ + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); +} + +// ======================================================================= +// function : Graphic3d_Texture3D +// purpose : +// ======================================================================= +Graphic3d_Texture3D::Graphic3d_Texture3D (const Handle(Image_PixMap)& thePixMap) +: Graphic3d_TextureMap (thePixMap, Graphic3d_TypeOfTexture_3D) +{ + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); +} + +// ======================================================================= +// function : Graphic3d_Texture3D +// purpose : +// ======================================================================= +Graphic3d_Texture3D::Graphic3d_Texture3D (const NCollection_Array1& theFiles) +: Graphic3d_TextureMap ("", Graphic3d_TypeOfTexture_3D) +{ + myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); + myPaths.Resize (theFiles.Lower(), theFiles.Upper(), false); + myPaths.Assign (theFiles); +} + +// ======================================================================= +// function : ~Graphic3d_Texture3D +// purpose : +// ======================================================================= +Graphic3d_Texture3D::~Graphic3d_Texture3D() +{ + // +} + +// ======================================================================= +// function : SetImage +// purpose : +// ======================================================================= +void Graphic3d_Texture3D::SetImage (const Handle(Image_PixMap)& thePixMap) +{ + myPixMap = thePixMap; + myPath = OSD_Path(); + + NCollection_Array1 anArr; + myPaths.Move (anArr); +} + +// ======================================================================= +// function : GetImage +// purpose : +// ======================================================================= +Handle(Image_PixMap) Graphic3d_Texture3D::GetImage (const Handle(Image_SupportedFormats)& theSupported) +{ + if (myPaths.IsEmpty() + || !myPixMap.IsNull()) + { + return base_type::GetImage (theSupported); + } + + Handle(Image_PixMap) anImage3D; + const Standard_Integer aNbSlices = myPaths.Length(); + for (Standard_Integer aSlice = 0; aSlice < aNbSlices; ++aSlice) + { + const TCollection_AsciiString& aSlicePath = myPaths[myPaths.Lower() + aSlice]; + Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap(); + if (!anImage->Load (aSlicePath)) + { + Message::SendFail() << "Graphic3d_Texture3D::GetImage() failed to load slice " << aSlice << " from '" << aSlicePath << "'"; + return Handle(Image_PixMap)(); + } + + convertToCompatible (theSupported, anImage); + if (anImage3D.IsNull()) + { + myIsTopDown = anImage->IsTopDown(); + anImage3D = new Image_PixMap(); + anImage3D->SetTopDown (myIsTopDown); + if (!anImage3D->InitTrash3D (anImage->Format(), + NCollection_Vec3 (anImage->SizeX(), anImage->SizeY(), aNbSlices), + anImage->SizeRowBytes())) + { + Message::SendFail() << "Graphic3d_Texture3D::GetImage() failed to allocate 3D image " << (int )anImage->SizeX() << "x" << (int )anImage->SizeY() << "x" << aNbSlices; + return Handle(Image_PixMap)(); + } + } + if (anImage->Format() != anImage3D->Format() + || anImage->SizeX() != anImage3D->SizeX() + || anImage->SizeY() != anImage3D->SizeY() + || anImage->SizeRowBytes() != anImage3D->SizeRowBytes()) + { + Message::SendFail() << "Graphic3d_Texture3D::GetImage() slice " << aSlice << " from '" << aSlicePath << "' have different dimensions"; + return Handle(Image_PixMap)(); + } + + memcpy (anImage3D->ChangeSlice (aSlice), anImage->Data(), anImage->SizeBytes()); + } + + return anImage3D; +} diff --git a/src/Graphic3d/Graphic3d_Texture3D.hxx b/src/Graphic3d/Graphic3d_Texture3D.hxx new file mode 100644 index 0000000000..51cb02eaa1 --- /dev/null +++ b/src/Graphic3d/Graphic3d_Texture3D.hxx @@ -0,0 +1,51 @@ +// Copyright (c) 2022 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_Texture3D_HeaderFile +#define _Graphic3d_Texture3D_HeaderFile + +#include +#include + +//! This abstract class for managing 3D textures. +class Graphic3d_Texture3D : public Graphic3d_TextureMap +{ + DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture3D, Graphic3d_TextureMap) +public: + + //! Creates a texture from a file. + Standard_EXPORT Graphic3d_Texture3D (const TCollection_AsciiString& theFileName); + + //! Creates a texture from the pixmap. + Standard_EXPORT Graphic3d_Texture3D (const Handle(Image_PixMap)& thePixMap); + + //! Creates a texture from a file. + Standard_EXPORT Graphic3d_Texture3D (const NCollection_Array1& theFiles); + + //! Destructor. + Standard_EXPORT virtual ~Graphic3d_Texture3D(); + + //! Assign new image to the texture. + //! Note that this method does not invalidate already uploaded resources - consider calling ::UpdateRevision() if needed. + Standard_EXPORT void SetImage (const Handle(Image_PixMap)& thePixMap); + + //! Load and return image. + Standard_EXPORT virtual Handle(Image_PixMap) GetImage (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE; + +protected: + + NCollection_Array1 myPaths; + +}; + +#endif // _Graphic3d_Texture3D_HeaderFile diff --git a/src/Graphic3d/Graphic3d_TextureEnv.cxx b/src/Graphic3d/Graphic3d_TextureEnv.cxx index c11f14197b..e2ac2025d5 100644 --- a/src/Graphic3d/Graphic3d_TextureEnv.cxx +++ b/src/Graphic3d/Graphic3d_TextureEnv.cxx @@ -42,9 +42,10 @@ static const char *NameOfTextureEnv_to_FileName[] = // purpose : // ======================================================================= Graphic3d_TextureEnv::Graphic3d_TextureEnv (const TCollection_AsciiString& theFileName) -: Graphic3d_TextureRoot (theFileName, Graphic3d_TOT_2D_MIPMAP), +: Graphic3d_TextureRoot (theFileName, Graphic3d_TypeOfTexture_2D), myName (Graphic3d_NOT_ENV_UNKNOWN) { + myHasMipmaps = true; myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); myParams->SetGenMode (Graphic3d_TOTM_SPHERE, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f), @@ -56,9 +57,10 @@ Graphic3d_TextureEnv::Graphic3d_TextureEnv (const TCollection_AsciiString& theFi // purpose : // ======================================================================= Graphic3d_TextureEnv::Graphic3d_TextureEnv (const Graphic3d_NameOfTextureEnv theNOT) -: Graphic3d_TextureRoot (NameOfTextureEnv_to_FileName[theNOT], Graphic3d_TOT_2D_MIPMAP), +: Graphic3d_TextureRoot (NameOfTextureEnv_to_FileName[theNOT], Graphic3d_TypeOfTexture_2D), myName (theNOT) { + myHasMipmaps = true; myPath.SetTrek (Graphic3d_TextureRoot::TexturesFolder()); myTexId = TCollection_AsciiString ("Graphic3d_TextureEnv_") + NameOfTextureEnv_to_FileName[theNOT]; @@ -74,9 +76,10 @@ Graphic3d_TextureEnv::Graphic3d_TextureEnv (const Graphic3d_NameOfTextureEnv the // purpose : // ======================================================================= Graphic3d_TextureEnv::Graphic3d_TextureEnv (const Handle(Image_PixMap)& thePixMap) -: Graphic3d_TextureRoot (thePixMap, Graphic3d_TOT_2D_MIPMAP), +: Graphic3d_TextureRoot (thePixMap, Graphic3d_TypeOfTexture_2D), myName (Graphic3d_NOT_ENV_UNKNOWN) { + myHasMipmaps = true; myParams->SetFilter (Graphic3d_TOTF_TRILINEAR); myParams->SetGenMode (Graphic3d_TOTM_SPHERE, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f), diff --git a/src/Graphic3d/Graphic3d_TextureRoot.cxx b/src/Graphic3d/Graphic3d_TextureRoot.cxx index a89f32dabe..027a5ebe4e 100644 --- a/src/Graphic3d/Graphic3d_TextureRoot.cxx +++ b/src/Graphic3d/Graphic3d_TextureRoot.cxx @@ -92,9 +92,10 @@ Graphic3d_TextureRoot::Graphic3d_TextureRoot (const TCollection_AsciiString& the : myParams (new Graphic3d_TextureParams()), myPath (theFileName), myRevision (0), - myType (theType), + myType (theType == Graphic3d_TOT_2D_MIPMAP ? Graphic3d_TypeOfTexture_2D : theType), myIsColorMap (true), - myIsTopDown (true) + myIsTopDown (true), + myHasMipmaps (theType == Graphic3d_TOT_2D_MIPMAP) { generateId(); } @@ -108,9 +109,10 @@ Graphic3d_TextureRoot::Graphic3d_TextureRoot (const Handle(Image_PixMap)& theP : myParams (new Graphic3d_TextureParams()), myPixMap (thePixMap), myRevision (0), - myType (theType), + myType (theType == Graphic3d_TOT_2D_MIPMAP ? Graphic3d_TypeOfTexture_2D : theType), myIsColorMap (true), - myIsTopDown (true) + myIsTopDown (true), + myHasMipmaps (theType == Graphic3d_TOT_2D_MIPMAP) { generateId(); } diff --git a/src/Graphic3d/Graphic3d_TextureRoot.hxx b/src/Graphic3d/Graphic3d_TextureRoot.hxx index fb155c4268..82d8e791e2 100644 --- a/src/Graphic3d/Graphic3d_TextureRoot.hxx +++ b/src/Graphic3d/Graphic3d_TextureRoot.hxx @@ -113,6 +113,12 @@ public: //! Set flag indicating color nature of values within the texture. void SetColorMap (Standard_Boolean theIsColor) { myIsColorMap = theIsColor; } + //! Returns whether mipmaps should be generated or not. + Standard_Boolean HasMipmaps() const { return myHasMipmaps; } + + //! Sets whether to generate mipmaps or not. + void SetMipmapsGeneration (Standard_Boolean theToGenerateMipmaps) { myHasMipmaps = theToGenerateMipmaps; } + //! Returns whether row's memory layout is top-down. Standard_Boolean IsTopDown() const { return myIsTopDown; } @@ -148,7 +154,7 @@ protected: Graphic3d_TypeOfTexture myType; //!< texture type Standard_Boolean myIsColorMap; //!< flag indicating color nature of values within the texture Standard_Boolean myIsTopDown; //!< Stores rows's memory layout - + Standard_Boolean myHasMipmaps; //!< Indicates whether mipmaps should be generated or not }; diff --git a/src/Graphic3d/Graphic3d_TypeOfTexture.hxx b/src/Graphic3d/Graphic3d_TypeOfTexture.hxx index c457e94de8..180004ac30 100644 --- a/src/Graphic3d/Graphic3d_TypeOfTexture.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfTexture.hxx @@ -20,10 +20,26 @@ //! Type of the texture file format. enum Graphic3d_TypeOfTexture { -Graphic3d_TOT_1D, -Graphic3d_TOT_2D, -Graphic3d_TOT_2D_MIPMAP, -Graphic3d_TOT_CUBEMAP + //! 1D texture (array). + //! Note that this texture type might be unsupported by graphics API (emulated by 2D texture with 1 pixel height). + Graphic3d_TypeOfTexture_1D, + + //! 2D texture (image plane). + Graphic3d_TypeOfTexture_2D, + + //! 3D texture (a set of image planes). + Graphic3d_TypeOfTexture_3D, + + //! Cubemap texture (6 image planes defining cube sides). + Graphic3d_TypeOfTexture_CUBEMAP, + + //! Obsolete type - Graphic3d_TextureRoot::SetMipmapsGeneration() should be used instead. + Graphic3d_TOT_2D_MIPMAP, + + // old aliases + Graphic3d_TOT_1D = Graphic3d_TypeOfTexture_1D, + Graphic3d_TOT_2D = Graphic3d_TypeOfTexture_2D, + Graphic3d_TOT_CUBEMAP = Graphic3d_TypeOfTexture_CUBEMAP }; #endif // _Graphic3d_TypeOfTexture_HeaderFile diff --git a/src/Image/Image_PixMap.cxx b/src/Image/Image_PixMap.cxx index d1ddea2237..c99971aefa 100644 --- a/src/Image/Image_PixMap.cxx +++ b/src/Image/Image_PixMap.cxx @@ -73,7 +73,8 @@ namespace }; } -IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(Image_PixMapData, NCollection_Buffer) +IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient) // ======================================================================= // function : DefaultAllocator @@ -152,6 +153,31 @@ void Image_PixMap::SetFormat (Image_Format thePixelFormat) myImgFormat = thePixelFormat; } +// ======================================================================= +// function : InitWrapper3D +// purpose : +// ======================================================================= +bool Image_PixMap::InitWrapper3D (Image_Format thePixelFormat, + Standard_Byte* theDataPtr, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes) +{ + Clear(); + myImgFormat = thePixelFormat; + if (theSizeXYZ.x() == 0 + || theSizeXYZ.y() == 0 + || theSizeXYZ.z() == 0 + || theDataPtr == nullptr) + { + return false; + } + + Handle(NCollection_BaseAllocator) anEmptyAlloc; + myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat), + theSizeXYZ, theSizeRowBytes, theDataPtr); + return true; +} + // ======================================================================= // function : InitWrapper // purpose : @@ -161,18 +187,32 @@ bool Image_PixMap::InitWrapper (Image_Format thePixelFormat, const Standard_Size theSizeX, const Standard_Size theSizeY, const Standard_Size theSizeRowBytes) +{ + return InitWrapper3D (thePixelFormat, theDataPtr, NCollection_Vec3 (theSizeX, theSizeY, 1), theSizeRowBytes); +} + +// ======================================================================= +// function : InitTrash3D +// purpose : +// ======================================================================= +bool Image_PixMap::InitTrash3D (Image_Format thePixelFormat, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes) { Clear(); myImgFormat = thePixelFormat; - if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL)) + if (theSizeXYZ.x() == 0 + || theSizeXYZ.y() == 0 + || theSizeXYZ.z() == 0) { return false; } - Handle(NCollection_BaseAllocator) anEmptyAlloc; - myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (thePixelFormat), - theSizeX, theSizeY, theSizeRowBytes, theDataPtr); - return true; + // use argument only if it greater + const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeXYZ.x() * SizePixelBytes (thePixelFormat)); + myData.Init (DefaultAllocator(), Image_PixMap::SizePixelBytes (thePixelFormat), + theSizeXYZ, aSizeRowBytes, NULL); + return !myData.IsEmpty(); } // ======================================================================= @@ -184,33 +224,31 @@ bool Image_PixMap::InitTrash (Image_Format thePixelFormat, const Standard_Size theSizeY, const Standard_Size theSizeRowBytes) { - Clear(); - myImgFormat = thePixelFormat; - if ((theSizeX == 0) || (theSizeY == 0)) - { - return false; - } - - // use argument only if it greater - const Standard_Size aSizeRowBytes = std::max (theSizeRowBytes, theSizeX * SizePixelBytes (thePixelFormat)); - myData.Init (DefaultAllocator(), Image_PixMap::SizePixelBytes (thePixelFormat), - theSizeX, theSizeY, aSizeRowBytes, NULL); - return !myData.IsEmpty(); + return InitTrash3D (thePixelFormat, NCollection_Vec3 (theSizeX, theSizeY, 1), theSizeRowBytes); } // ======================================================================= -// function : InitZero +// function : InitZero3D // purpose : // ======================================================================= -bool Image_PixMap::InitZero (Image_Format thePixelFormat, - const Standard_Size theSizeX, - const Standard_Size theSizeY, - const Standard_Size theSizeRowBytes, - const Standard_Byte theValue) +bool Image_PixMap::InitZero3D (Image_Format thePixelFormat, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes, + const Standard_Byte theValue) { - if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes)) + if (theSizeXYZ.z() > 1) { - return false; + if (!InitTrash3D (thePixelFormat, theSizeXYZ, theSizeRowBytes)) + { + return false; + } + } + else + { + if (!InitTrash (thePixelFormat, theSizeXYZ.x(), theSizeXYZ.y(), theSizeRowBytes)) + { + return false; + } } memset (myData.ChangeData(), (int )theValue, SizeBytes()); return true; @@ -227,12 +265,24 @@ bool Image_PixMap::InitCopy (const Image_PixMap& theCopy) // self-copying disallowed return false; } - if (InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes())) + + if (theCopy.SizeZ() > 1) { - memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes()); - return true; + if (!InitTrash3D (theCopy.myImgFormat, theCopy.SizeXYZ(), theCopy.SizeRowBytes())) + { + return false; + } } - return false; + else + { + if (!InitTrash (theCopy.myImgFormat, theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes())) + { + return false; + } + } + + memcpy (myData.ChangeData(), theCopy.myData.Data(), theCopy.SizeBytes()); + return true; } // ======================================================================= @@ -243,80 +293,73 @@ void Image_PixMap::Clear() { Handle(NCollection_BaseAllocator) anEmptyAlloc; myData.Init (anEmptyAlloc, Image_PixMap::SizePixelBytes (myImgFormat), - 0, 0, 0, NULL); + NCollection_Vec3 (0), 0, nullptr); } // ======================================================================= -// function : PixelColor +// function : ColorFromRawPixel // purpose : // ======================================================================= -Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, - const Standard_Integer theY, - const Standard_Boolean theToLinearize) const +Quantity_ColorRGBA Image_PixMap::ColorFromRawPixel (const Standard_Byte* theRawValue, + const Image_Format theFormat, + const Standard_Boolean theToLinearize) { - if (IsEmpty() - || theX < 0 || (Standard_Size )theX >= SizeX() - || theY < 0 || (Standard_Size )theY >= SizeY()) - { - return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent - } - - switch (myImgFormat) + switch (theFormat) { case Image_Format_GrayF: { - const Standard_ShortReal& aPixel = Value (theY, theX); + const Standard_ShortReal& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel, aPixel, aPixel, 1.0f)); // opaque } case Image_Format_AlphaF: { - const Standard_ShortReal& aPixel = Value (theY, theX); + const Standard_ShortReal& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (1.0f, 1.0f, 1.0f, aPixel)); } case Image_Format_RGF: { - const Image_ColorRGF& aPixel = Value (theY, theX); + const Image_ColorRGF& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel.r(), aPixel.g(), 0.0f, 1.0f)); } case Image_Format_RGBAF: { - const Image_ColorRGBAF& aPixel = Value (theY, theX); + const Image_ColorRGBAF& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a())); } case Image_Format_BGRAF: { - const Image_ColorBGRAF& aPixel = Value (theY, theX); + const Image_ColorBGRAF& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel.r(), aPixel.g(), aPixel.b(), aPixel.a())); } case Image_Format_RGBF: { - const Image_ColorRGBF& aPixel = Value (theY, theX); + const Image_ColorRGBF& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque } case Image_Format_BGRF: { - const Image_ColorBGRF& aPixel = Value (theY, theX); + const Image_ColorBGRF& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (aPixel.r(), aPixel.g(), aPixel.b(), 1.0f)); // opaque } case Image_Format_GrayF_half: { - const uint16_t& aPixel = Value (theY, theX); + const uint16_t& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (ConvertFromHalfFloat (aPixel), 0.0f, 0.0f, 1.0f)); } case Image_Format_RGF_half: { - const NCollection_Vec2& aPixel = Value> (theY, theX); + const NCollection_Vec2& aPixel = *reinterpret_cast*> (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (ConvertFromHalfFloat (aPixel.x()), ConvertFromHalfFloat (aPixel.y()), 0.0f, 1.0f)); } case Image_Format_RGBAF_half: { - const NCollection_Vec4& aPixel = Value> (theY, theX); + const NCollection_Vec4& aPixel = *reinterpret_cast*> (theRawValue); return Quantity_ColorRGBA (NCollection_Vec4 (ConvertFromHalfFloat (aPixel.r()), ConvertFromHalfFloat (aPixel.g()), ConvertFromHalfFloat (aPixel.b()), ConvertFromHalfFloat (aPixel.a()))); } case Image_Format_RGBA: { - const Image_ColorRGBA& aPixel = Value (theY, theX); + const Image_ColorRGBA& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -326,7 +369,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_BGRA: { - const Image_ColorBGRA& aPixel = Value (theY, theX); + const Image_ColorBGRA& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -336,7 +379,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_RGB32: { - const Image_ColorRGB32& aPixel = Value (theY, theX); + const Image_ColorRGB32& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -345,7 +388,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_BGR32: { - const Image_ColorBGR32& aPixel = Value (theY, theX); + const Image_ColorBGR32& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -354,7 +397,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_RGB: { - const Image_ColorRGB& aPixel = Value (theY, theX); + const Image_ColorRGB& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -363,7 +406,7 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_BGR: { - const Image_ColorBGR& aPixel = Value (theY, theX); + const Image_ColorBGR& aPixel = *reinterpret_cast (theRawValue); return theToLinearize ? Quantity_ColorRGBA (Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.r()) / 255.0f), Quantity_Color::Convert_sRGB_To_LinearRGB (float(aPixel.g()) / 255.0f), @@ -372,18 +415,18 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } case Image_Format_Gray: { - const Standard_Byte& aPixel = Value (theY, theX); + const Standard_Byte& aPixel = *reinterpret_cast (theRawValue); const float anIntensity = float(aPixel) / 255.0f; return Quantity_ColorRGBA (anIntensity, anIntensity, anIntensity, 1.0f); // opaque } case Image_Format_Alpha: { - const Standard_Byte& aPixel = Value (theY, theX); + const Standard_Byte& aPixel = *reinterpret_cast (theRawValue); return Quantity_ColorRGBA (1.0f, 1.0f, 1.0f, float(aPixel) / 255.0f); } case Image_Format_Gray16: { - const uint16_t& aPixel = Value (theY, theX); + const uint16_t& aPixel = *reinterpret_cast (theRawValue); const float anIntensity = float(aPixel) / 65535.0f; return Quantity_ColorRGBA (anIntensity, anIntensity, anIntensity, 1.0f); // opaque } @@ -398,44 +441,37 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX, } // ======================================================================= -// function : SetPixelColor +// function : ColorToRawPixel // purpose : // ======================================================================= -void Image_PixMap::SetPixelColor (const Standard_Integer theX, - const Standard_Integer theY, - const Quantity_ColorRGBA& theColor, - const Standard_Boolean theToDeLinearize) +void Image_PixMap::ColorToRawPixel (Standard_Byte* theRawValue, + const Image_Format theFormat, + const Quantity_ColorRGBA& theColor, + const Standard_Boolean theToDeLinearize) { - if (IsEmpty() - || theX < 0 || Standard_Size(theX) >= SizeX() - || theY < 0 || Standard_Size(theY) >= SizeY()) - { - return; - } - const NCollection_Vec4& aColor = theColor; - switch (myImgFormat) + switch (theFormat) { case Image_Format_GrayF: { - ChangeValue (theY, theX) = aColor.r(); + *reinterpret_cast (theRawValue) = aColor.r(); return; } case Image_Format_AlphaF: { - ChangeValue (theY, theX) = aColor.a(); + *reinterpret_cast (theRawValue) = aColor.a(); return; } case Image_Format_RGF: { - Image_ColorRGF& aPixel = ChangeValue (theY, theX); + Image_ColorRGF& aPixel = *reinterpret_cast (theRawValue); aPixel.r() = aColor.r(); aPixel.g() = aColor.g(); return; } case Image_Format_RGBAF: { - Image_ColorRGBAF& aPixel = ChangeValue (theY, theX); + Image_ColorRGBAF& aPixel = *reinterpret_cast (theRawValue); aPixel.r() = aColor.r(); aPixel.g() = aColor.g(); aPixel.b() = aColor.b(); @@ -444,7 +480,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_BGRAF: { - Image_ColorBGRAF& aPixel = ChangeValue (theY, theX); + Image_ColorBGRAF& aPixel = *reinterpret_cast (theRawValue); aPixel.r() = aColor.r(); aPixel.g() = aColor.g(); aPixel.b() = aColor.b(); @@ -453,7 +489,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_RGBF: { - Image_ColorRGBF& aPixel = ChangeValue (theY, theX); + Image_ColorRGBF& aPixel = *reinterpret_cast (theRawValue); aPixel.r() = aColor.r(); aPixel.g() = aColor.g(); aPixel.b() = aColor.b(); @@ -461,7 +497,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_BGRF: { - Image_ColorBGRF& aPixel = ChangeValue (theY, theX); + Image_ColorBGRF& aPixel = *reinterpret_cast (theRawValue); aPixel.r() = aColor.r(); aPixel.g() = aColor.g(); aPixel.b() = aColor.b(); @@ -469,20 +505,20 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_GrayF_half: { - uint16_t& aPixel = ChangeValue (theY, theX); + uint16_t& aPixel = *reinterpret_cast (theRawValue); aPixel = ConvertToHalfFloat (aColor.r()); return; } case Image_Format_RGF_half: { - NCollection_Vec2& aPixel = ChangeValue> (theY, theX); + NCollection_Vec2& aPixel = *reinterpret_cast*> (theRawValue); aPixel.x() = ConvertToHalfFloat (aColor.r()); aPixel.y() = ConvertToHalfFloat (aColor.g()); return; } case Image_Format_RGBAF_half: { - NCollection_Vec4& aPixel = ChangeValue> (theY, theX); + NCollection_Vec4& aPixel = *reinterpret_cast*> (theRawValue); aPixel.r() = ConvertToHalfFloat (aColor.r()); aPixel.g() = ConvertToHalfFloat (aColor.g()); aPixel.b() = ConvertToHalfFloat (aColor.b()); @@ -491,7 +527,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_RGBA: { - Image_ColorRGBA& aPixel = ChangeValue (theY, theX); + Image_ColorRGBA& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -509,7 +545,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_BGRA: { - Image_ColorBGRA& aPixel = ChangeValue (theY, theX); + Image_ColorBGRA& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -527,7 +563,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_RGB32: { - Image_ColorRGB32& aPixel = ChangeValue (theY, theX); + Image_ColorRGB32& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -545,7 +581,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_BGR32: { - Image_ColorBGR32& aPixel = ChangeValue (theY, theX); + Image_ColorBGR32& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -563,7 +599,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_RGB: { - Image_ColorRGB& aPixel = ChangeValue (theY, theX); + Image_ColorRGB& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -580,7 +616,7 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_BGR: { - Image_ColorBGR& aPixel = ChangeValue (theY, theX); + Image_ColorBGR& aPixel = *reinterpret_cast (theRawValue); if (theToDeLinearize) { aPixel.r() = Standard_Byte(Quantity_Color::Convert_LinearRGB_To_sRGB (aColor.r()) * 255.0f); @@ -597,17 +633,17 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX, } case Image_Format_Gray: { - ChangeValue (theY, theX) = Standard_Byte(aColor.r() * 255.0f); + *reinterpret_cast(theRawValue) = Standard_Byte(aColor.r() * 255.0f); return; } case Image_Format_Alpha: { - ChangeValue (theY, theX) = Standard_Byte(aColor.a() * 255.0f); + *reinterpret_cast(theRawValue) = Standard_Byte(aColor.a() * 255.0f); return; } case Image_Format_Gray16: { - ChangeValue (theY, theX) = uint16_t(aColor.r() * 65535.0f); + *reinterpret_cast(theRawValue) = uint16_t(aColor.r() * 65535.0f); return; } case Image_Format_UNKNOWN: @@ -632,18 +668,21 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage) { const bool toResetAlpha = theImage.Format() == Image_Format_BGR32 || theImage.Format() == Image_Format_RGB32; - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - Image_ColorRGBA& aPixel = theImage.ChangeValue (aRow, aCol); - Image_ColorBGRA aPixelCopy = theImage.Value (aRow, aCol); - aPixel.r() = aPixelCopy.r(); - aPixel.g() = aPixelCopy.g(); - aPixel.b() = aPixelCopy.b(); - if (toResetAlpha) + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) { - aPixel.a() = 255; + Image_ColorRGBA& aPixel = theImage.ChangeValueXYZ (aCol, aRow, aSlice); + Image_ColorBGRA aPixelCopy = theImage.ValueXYZ (aCol, aRow, aSlice); + aPixel.r() = aPixelCopy.r(); + aPixel.g() = aPixelCopy.g(); + aPixel.b() = aPixelCopy.b(); + if (toResetAlpha) + { + aPixel.a() = 255; + } } } } @@ -652,15 +691,18 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage) case Image_Format_BGR: case Image_Format_RGB: { - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - Image_ColorRGB& aPixel = theImage.ChangeValue (aRow, aCol); - Image_ColorBGR aPixelCopy = theImage.Value (aRow, aCol); - aPixel.r() = aPixelCopy.r(); - aPixel.g() = aPixelCopy.g(); - aPixel.b() = aPixelCopy.b(); + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + { + Image_ColorRGB& aPixel = theImage.ChangeValueXYZ (aCol, aRow, aSlice); + Image_ColorBGR aPixelCopy = theImage.ValueXYZ (aCol, aRow, aSlice); + aPixel.r() = aPixelCopy.r(); + aPixel.g() = aPixelCopy.g(); + aPixel.b() = aPixelCopy.b(); + } } } return true; @@ -670,15 +712,18 @@ bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage) case Image_Format_BGRAF: case Image_Format_RGBAF: { - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - Image_ColorRGBF& aPixel = theImage.ChangeValue (aRow, aCol); - Image_ColorBGRF aPixelCopy = theImage.Value (aRow, aCol); - aPixel.r() = aPixelCopy.r(); - aPixel.g() = aPixelCopy.g(); - aPixel.b() = aPixelCopy.b(); + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + { + Image_ColorRGBF& aPixel = theImage.ChangeValueXYZ (aCol, aRow, aSlice); + Image_ColorBGRF aPixelCopy = theImage.ValueXYZ (aCol, aRow, aSlice); + aPixel.r() = aPixelCopy.r(); + aPixel.g() = aPixelCopy.g(); + aPixel.b() = aPixelCopy.b(); + } } } return true; @@ -698,14 +743,17 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage) case Image_Format_Gray: case Image_Format_Alpha: { - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - unsigned char& aPixel = theImage.ChangeValue (aRow, aCol); - if (aPixel != 0) + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) { - aPixel = 255; + uint8_t& aPixel = theImage.ChangeValueXYZ (aCol, aRow, aSlice); + if (aPixel != 0) + { + aPixel = 255; + } } } } @@ -713,14 +761,17 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage) } case Image_Format_Gray16: { - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - uint16_t& aPixel = theImage.ChangeValue (aRow, aCol); - if (aPixel != 0) + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) { - aPixel = 65535; + uint16_t& aPixel = theImage.ChangeValueXYZ (aCol, aRow, aSlice); + if (aPixel != 0) + { + aPixel = 65535; + } } } } @@ -733,17 +784,20 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage) case Image_Format_RGBA: case Image_Format_BGRA: { - const NCollection_Vec3 aWhite24 (255, 255, 255); - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + const NCollection_Vec3 aWhite24 (255, 255, 255); + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - NCollection_Vec3& aPixel = theImage.ChangeValue< NCollection_Vec3 > (aRow, aCol); - if (aPixel[0] != 0 - || aPixel[1] != 0 - || aPixel[2] != 0) + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) { - aPixel = aWhite24; + NCollection_Vec3& aPixel = theImage.ChangeValueXYZ< NCollection_Vec3 > (aCol, aRow, aSlice); + if (aPixel[0] != 0 + || aPixel[1] != 0 + || aPixel[2] != 0) + { + aPixel = aWhite24; + } } } } @@ -752,17 +806,21 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage) default: { const Quantity_ColorRGBA aWhiteRgba (1.0f, 1.0f, 1.0f, 1.0f); - for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) + for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow) { - const Quantity_ColorRGBA aPixelRgba = theImage.PixelColor (Standard_Integer(aCol), Standard_Integer(aRow)); - const NCollection_Vec4& aPixel = aPixelRgba; - if (aPixel[0] != 0.0f - || aPixel[1] != 0.0f - || aPixel[2] != 0.0f) + for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol) { - theImage.SetPixelColor (int(aCol), int(aRow), aWhiteRgba); + Standard_Byte* aRawPixel = theImage.ChangeRawValueXYZ (aCol, aRow, aSlice); + const Quantity_ColorRGBA aPixelRgba = ColorFromRawPixel (aRawPixel, theImage.Format()); + const NCollection_Vec4& aPixel = aPixelRgba; + if (aPixel[0] != 0.0f + || aPixel[1] != 0.0f + || aPixel[2] != 0.0f) + { + ColorToRawPixel (aRawPixel, theImage.Format(), aWhiteRgba); + } } } } @@ -772,7 +830,7 @@ void Image_PixMap::ToBlackWhite (Image_PixMap& theImage) } // ======================================================================= -// function : InitCopy +// function : FlipY // purpose : // ======================================================================= bool Image_PixMap::FlipY (Image_PixMap& theImage) @@ -793,13 +851,16 @@ bool Image_PixMap::FlipY (Image_PixMap& theImage) // for odd height middle row should be left as is Standard_Size aNbRowsHalf = theImage.SizeY() / 2; - for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB) + for (Standard_Size aSlice = 0; aSlice < theImage.SizeZ(); ++aSlice) { - Standard_Byte* aTop = theImage.ChangeRow (aRowT); - Standard_Byte* aBot = theImage.ChangeRow (aRowB); - memcpy (aTmp.ChangeData(), aTop, aRowSize); - memcpy (aTop, aBot, aRowSize); - memcpy (aBot, aTmp.Data(), aRowSize); + for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB) + { + Standard_Byte* aTop = theImage.ChangeSliceRow (aSlice, aRowT); + Standard_Byte* aBot = theImage.ChangeSliceRow (aSlice, aRowB); + memcpy (aTmp.ChangeData(), aTop, aRowSize); + memcpy (aTop, aBot, aRowSize); + memcpy (aBot, aTmp.Data(), aRowSize); + } } return true; } diff --git a/src/Image/Image_PixMap.hxx b/src/Image/Image_PixMap.hxx index 46e0dd2f7b..b4bef537b0 100644 --- a/src/Image/Image_PixMap.hxx +++ b/src/Image/Image_PixMap.hxx @@ -35,6 +35,9 @@ public: return !aUnion.myChar[0]; } + //! Return bytes reserved for one pixel (may include extra bytes for alignment). + Standard_EXPORT static Standard_Size SizePixelBytes (const Image_Format thePixelFormat); + //! Auxiliary method for swapping bytes between RGB and BGR formats. //! This method modifies the image data but does not change pixel format! //! Method will fail if pixel format is not one of the following: @@ -60,6 +63,25 @@ public: //! Return string representation of compressed pixel format. Standard_EXPORT static Standard_CString ImageFormatToString (Image_CompressedFormat theFormat); + //! Convert raw pixel value into Quantity_ColorRGBA. This function is relatively slow. + //! @param[in] theRawValue pointer to pixel definition + //! @param[in] theFormat pixel format + //! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized + //! @return the pixel color + Standard_EXPORT static Quantity_ColorRGBA ColorFromRawPixel (const Standard_Byte* theRawValue, + const Image_Format theFormat, + const Standard_Boolean theToLinearize = false); + + //! Set raw pixel value from Quantity_ColorRGBA. This function is relatively slow. + //! @param[out] theRawValue pointer to pixel definition to modify + //! @param[in] theFormat pixel format + //! @param[in] theColor color value to convert from + //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB) + Standard_EXPORT static void ColorToRawPixel (Standard_Byte* theRawValue, + const Image_Format theFormat, + const Quantity_ColorRGBA& theColor, + const Standard_Boolean theToDeLinearize = false); + public: // high-level API //! Return pixel format. @@ -71,18 +93,30 @@ public: // high-level API //! (e.g. ImgGray and ImgAlpha). Standard_EXPORT void SetFormat (const Image_Format thePixelFormat); - //! Return image width in pixels + //! Return image width in pixels. Standard_Size Width() const { return myData.SizeX; } - //! Return image height in pixels + //! Return image height in pixels. Standard_Size Height() const { return myData.SizeY; } - //! Return image width in pixels + //! Return image depth in pixels. + Standard_Size Depth() const { return myData.SizeZ; } + + //! Return image width in pixels. Standard_Size SizeX() const { return myData.SizeX; } - //! Return image height in pixels + //! Return image height in pixels. Standard_Size SizeY() const { return myData.SizeY; } + //! Return image depth in pixels. + Standard_Size SizeZ() const { return myData.SizeZ; } + + //! Return image width x height x depth in pixels. + NCollection_Vec3 SizeXYZ() const + { + return NCollection_Vec3 (myData.SizeX, myData.SizeY, myData.SizeZ); + } + //! Return width / height. Standard_Real Ratio() const { @@ -100,38 +134,60 @@ public: // high-level API //! Returns the pixel color. This function is relatively slow. //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue(). - //! @param theX [in] column index from left - //! @param theY [in] row index from top - //! @param theToLinearize [in] when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized + //! @param[in] theX column index from left, starting from 0 + //! @param[in] theY row index from top, starting from 0 + //! @param[in] theToLinearize when TRUE, the color stored in non-linear color space (e.g. Image_Format_RGB) will be linearized //! @return the pixel color - Standard_EXPORT Quantity_ColorRGBA PixelColor (const Standard_Integer theX, - const Standard_Integer theY, - const Standard_Boolean theToLinearize = Standard_False) const; + Quantity_ColorRGBA PixelColor (Standard_Integer theX, + Standard_Integer theY, + Standard_Boolean theToLinearize = false) const + { + if (IsEmpty() + || theX < 0 || (Standard_Size )theX >= SizeX() + || theY < 0 || (Standard_Size )theY >= SizeY()) + { + return Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 0.0f); // transparent + } + + const Standard_Byte* aRawPixel = RawValueXY (theX, theY); + return ColorFromRawPixel (aRawPixel, myImgFormat, theToLinearize); + } //! Sets the pixel color. This function is relatively slow. //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue(). - //! @param theX [in] column index from left - //! @param theY [in] row index from top - //! @param theColor [in] color to store - //! @param theToDeLinearize [in] when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB) + //! @param[in] theX column index from left + //! @param[in] theY row index from top + //! @param[in] theColor color to store + //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB) void SetPixelColor (const Standard_Integer theX, const Standard_Integer theY, const Quantity_Color& theColor, - const Standard_Boolean theToDeLinearize = Standard_False) + const Standard_Boolean theToDeLinearize = false) { SetPixelColor (theX, theY, Quantity_ColorRGBA (theColor, 1.0f), theToDeLinearize); } //! Sets the pixel color. This function is relatively slow. //! Beware that this method takes coordinates in opposite order in contrast to ::Value() and ::ChangeValue(). - //! @param theX [in] column index from left - //! @param theY [in] row index from top - //! @param theColor [in] color to store - //! @param theToDeLinearize [in] when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB) - Standard_EXPORT void SetPixelColor (const Standard_Integer theX, - const Standard_Integer theY, - const Quantity_ColorRGBA& theColor, - const Standard_Boolean theToDeLinearize = Standard_False); + //! @param[in] theX column index from left + //! @param[in] theY row index from top + //! @param[in] theColor color to store + //! @param[in] theToDeLinearize when TRUE, the gamma correction will be applied for storing in non-linear color space (e.g. Image_Format_RGB) + void SetPixelColor (const Standard_Integer theX, + const Standard_Integer theY, + const Quantity_ColorRGBA& theColor, + const Standard_Boolean theToDeLinearize = false) + { + if (IsEmpty() + || theX < 0 || Standard_Size(theX) >= SizeX() + || theY < 0 || Standard_Size(theY) >= SizeY()) + { + return; + } + + Standard_Byte* aRawPixel = ChangeRawValueXY (theX, theY); + ColorToRawPixel (aRawPixel, myImgFormat, theColor, theToDeLinearize); + } //! Initialize image plane as wrapper over alien data. //! Data will not be copied! Notice that caller should ensure @@ -156,15 +212,42 @@ public: // high-level API //! Initialize image plane with required dimensions. //! Buffer will be zeroed (black color for most formats). - Standard_EXPORT bool InitZero (Image_Format thePixelFormat, - const Standard_Size theSizeX, - const Standard_Size theSizeY, - const Standard_Size theSizeRowBytes = 0, - const Standard_Byte theValue = 0); + bool InitZero (Image_Format thePixelFormat, + const Standard_Size theSizeX, + const Standard_Size theSizeY, + const Standard_Size theSizeRowBytes = 0, + const Standard_Byte theValue = 0) + { + return InitZero3D (thePixelFormat, NCollection_Vec3 (theSizeX, theSizeY, 1), theSizeRowBytes, theValue); + } //! Method correctly deallocate internal buffer. Standard_EXPORT virtual void Clear(); +public: + + //! Initialize 2D/3D image as wrapper over alien data. + //! Data will not be copied! Notice that caller should ensure + //! that data pointer will not be released during this wrapper lifetime. + //! You may call InitCopy() to perform data copying. + Standard_EXPORT virtual bool InitWrapper3D (Image_Format thePixelFormat, + Standard_Byte* theDataPtr, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes = 0); + + //! Initialize 2D/3D image with required dimensions. + //! Memory will be left uninitialized (performance trick). + Standard_EXPORT virtual bool InitTrash3D (Image_Format thePixelFormat, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes = 0); + + //! Initialize 2D/3D image with required dimensions. + //! Buffer will be zeroed (black color for most formats). + Standard_EXPORT bool InitZero3D (Image_Format thePixelFormat, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes = 0, + const Standard_Byte theValue = 0); + public: //! @name low-level API for batch-processing (pixels reading / comparison / modification) //! Returns TRUE if image data is stored from Top to the Down. @@ -176,105 +259,106 @@ public: //! @name low-level API for batch-processing (pixels reading / compariso //! convert input row-index to apply this flag! //! You should use this flag only if interconnect with alien APIs and buffers. //! @return true if image data is top-down - inline bool IsTopDown() const - { - return myData.TopToDown == 1; - } + bool IsTopDown() const { return myData.TopToDown == 1; } //! Setup scanlines order in memory - top-down or bottom-up. //! Drawers should explicitly specify this value if current state IsTopDown() was ignored! //! @param theIsTopDown top-down flag - inline void SetTopDown (const bool theIsTopDown) - { - myData.SetTopDown (theIsTopDown); - } + void SetTopDown (const bool theIsTopDown) { myData.SetTopDown (theIsTopDown); } //! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise. //! @return scanline increment for Top->Down iteration - inline Standard_Size TopDownInc() const + Standard_Size TopDownInc() const { return myData.TopToDown; } + + //! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.). + const Standard_Byte* Data() const { return myData.Data(); } + + //! Return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.). + Standard_Byte* ChangeData() { return myData.ChangeData(); } + + //! Return data pointer to requested row (first column). + //! Indexation starts from 0. + const Standard_Byte* Row (Standard_Size theRow) const { return myData.Row (theRow); } + + //! Return data pointer to requested row (first column). + //! Indexation starts from 0. + Standard_Byte* ChangeRow (Standard_Size theRow) { return myData.ChangeRow (theRow); } + + //! Return data pointer to requested 2D slice. + //! Indexation starts from 0. + const Standard_Byte* Slice (Standard_Size theSlice) const { return myData.Slice (theSlice); } + + //! Return data pointer to requested 2D slice. + //! Indexation starts from 0. + Standard_Byte* ChangeSlice (Standard_Size theSlice) { return myData.ChangeSlice (theSlice); } + + //! Return data pointer to requested row (first column). + //! Indexation starts from 0. + const Standard_Byte* SliceRow (Standard_Size theSlice, + Standard_Size theRow) const { - return myData.TopToDown; + return myData.SliceRow (theSlice, theRow); } - //! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.). - inline const Standard_Byte* Data() const + //! Return data pointer to requested row (first column). + //! Indexation starts from 0. + Standard_Byte* ChangeSliceRow (Standard_Size theSlice, + Standard_Size theRow) { - return myData.Data(); + return myData.ChangeSliceRow (theSlice, theRow); } - //! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.). - inline Standard_Byte* ChangeData() - { - return myData.ChangeData(); - } + //! Return bytes reserved for one pixel (may include extra bytes for alignment). + Standard_Size SizePixelBytes() const { return myData.SizeBPP; } - //! @return data pointer to requested row (first column). - inline const Standard_Byte* Row (const Standard_Size theRow) const - { - return myData.Row (theRow); - } - - //! @return data pointer to requested row (first column). - inline Standard_Byte* ChangeRow (const Standard_Size theRow) - { - return myData.ChangeRow (theRow); - } - - //! @return bytes reserved for one pixel (may include extra bytes for alignment). - inline Standard_Size SizePixelBytes() const - { - return myData.SizeBPP; - } - - //! @return bytes reserved for one pixel (may include extra bytes for alignment). - Standard_EXPORT static Standard_Size SizePixelBytes (const Image_Format thePixelFormat); - - //! @return bytes reserved per row. + //! Return bytes reserved per row. //! Could be larger than needed to store packed row (extra bytes for alignment etc.). - inline Standard_Size SizeRowBytes() const - { - return myData.SizeRowBytes; - } + Standard_Size SizeRowBytes() const { return myData.SizeRowBytes; } - //! @return the extra bytes in the row. - inline Standard_Size RowExtraBytes() const + //! Return the extra bytes in the row. + Standard_Size RowExtraBytes() const { return SizeRowBytes() - SizeX() * SizePixelBytes(); } //! Compute the maximal row alignment for current row size. //! @return maximal row alignment in bytes (up to 16 bytes). - inline Standard_Size MaxRowAligmentBytes() const - { - return myData.MaxRowAligmentBytes(); - } + Standard_Size MaxRowAligmentBytes() const { return myData.MaxRowAligmentBytes(); } - //! @return buffer size - inline Standard_Size SizeBytes() const - { - return myData.Size(); - } + //! Return number of bytes per 2D slice. + Standard_Size SizeSliceBytes() const { return myData.SizeSliceBytes; } + + //! Return buffer size + Standard_Size SizeBytes() const { return myData.Size(); } + +public: //! Access image pixel with specified color type. + //! Indexation starts from 0. //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next. template - inline const ColorType_t& Value (const Standard_Size theRow, - const Standard_Size theCol) const + const ColorType_t& Value (Standard_Size theRow, + Standard_Size theCol) const { return *reinterpret_cast(myData.Value (theRow, theCol)); } //! Access image pixel with specified color type. + //! Indexation starts from 0. //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next. template - inline ColorType_t& ChangeValue (const Standard_Size theRow, - const Standard_Size theCol) + ColorType_t& ChangeValue (Standard_Size theRow, + Standard_Size theCol) { return *reinterpret_cast(myData.ChangeValue (theRow, theCol)); } //! Access image pixel as raw data pointer. + //! Indexation starts from 0. //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next. const Standard_Byte* RawValue (Standard_Size theRow, Standard_Size theCol) const { @@ -282,13 +366,105 @@ public: //! @name low-level API for batch-processing (pixels reading / compariso } //! Access image pixel as raw data pointer. + //! Indexation starts from 0. //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in the decreasing majority following memory layout - e.g. row first, column next. Standard_Byte* ChangeRawValue (Standard_Size theRow, Standard_Size theCol) { return myData.ChangeValue (theRow, theCol); } + //! Access image pixel with specified color type. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y order. + template + const ColorType_t& ValueXY (Standard_Size theX, + Standard_Size theY) const + { + return *reinterpret_cast(myData.ValueXY (theX, theY)); + } + + //! Access image pixel with specified color type. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y order. + template + ColorType_t& ChangeValueXY (Standard_Size theX, + Standard_Size theY) + { + return *reinterpret_cast(myData.ChangeValueXY (theX, theY)); + } + + //! Access image pixel as raw data pointer. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y order. + const Standard_Byte* RawValueXY (Standard_Size theX, + Standard_Size theY) const + { + return myData.ValueXY (theX, theY); + } + + //! Access image pixel as raw data pointer. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y order. + Standard_Byte* ChangeRawValueXY (Standard_Size theX, + Standard_Size theY) + { + return myData.ChangeValueXY (theX, theY); + } + +public: + + //! Access image pixel with specified color type. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y, Z order. + template + const ColorType_t& ValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) const + { + return *reinterpret_cast(myData.ValueXYZ (theX, theY, theZ)); + } + + //! Access image pixel with specified color type. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y, Z order. + template + ColorType_t& ChangeValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) + { + return *reinterpret_cast(myData.ChangeValueXYZ (theX, theY, theZ)); + } + + //! Access image pixel as raw data pointer. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y, Z order. + const Standard_Byte* RawValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) const + { + return myData.ValueXYZ (theX, theY, theZ); + } + + //! Access image pixel as raw data pointer. + //! Indexation starts from 0. + //! This method does not perform any type checks - use on own risk (check Format() before)! + //! WARNING: Input parameters are defined in traditional X, Y, Z order. + Standard_Byte* ChangeRawValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) + { + return myData.ChangeValueXYZ (theX, theY, theZ); + } + public: //! Convert 16-bit half-float value into 32-bit float (simple conversion). diff --git a/src/Image/Image_PixMapData.hxx b/src/Image/Image_PixMapData.hxx index b9050be1ed..fb78060a73 100644 --- a/src/Image/Image_PixMapData.hxx +++ b/src/Image/Image_PixMapData.hxx @@ -18,6 +18,7 @@ #include #include +#include //! Structure to manage image buffer. class Image_PixMapData : public NCollection_Buffer @@ -31,7 +32,9 @@ public: SizeBPP (0), SizeX (0), SizeY (0), + SizeZ (0), SizeRowBytes (0), + SizeSliceBytes (0), TopToDown (Standard_Size(-1)) { // @@ -44,16 +47,28 @@ public: const Standard_Size theSizeY, const Standard_Size theSizeRowBytes, Standard_Byte* theDataPtr) + { + return Init (theAlloc, theSizeBPP, NCollection_Vec3 (theSizeX, theSizeY, 1), theSizeRowBytes, theDataPtr); + } + + //! Initializer. + bool Init (const Handle(NCollection_BaseAllocator)& theAlloc, + const Standard_Size theSizeBPP, + const NCollection_Vec3& theSizeXYZ, + const Standard_Size theSizeRowBytes, + Standard_Byte* theDataPtr) { SetAllocator (theAlloc); // will free old data as well myData = theDataPtr; myTopRowPtr = NULL; SizeBPP = theSizeBPP; - SizeX = theSizeX; - SizeY = theSizeY; - SizeRowBytes = theSizeRowBytes != 0 ? theSizeRowBytes : (theSizeX * theSizeBPP); - mySize = SizeRowBytes * SizeY; + SizeX = theSizeXYZ.x(); + SizeY = theSizeXYZ.y(); + SizeZ = theSizeXYZ.z(); + SizeRowBytes = theSizeRowBytes != 0 ? theSizeRowBytes : (SizeX * theSizeBPP); + SizeSliceBytes = SizeRowBytes * SizeY; + mySize = SizeSliceBytes * SizeZ; if (myData == NULL) { Allocate (mySize); @@ -71,35 +86,93 @@ public: } } - //! @return data pointer to requested row (first column). - inline const Standard_Byte* Row (const Standard_Size theRow) const + //! Return data pointer to requested row (first column). + const Standard_Byte* Row (const Standard_Size theRow) const { return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown); } - //! @return data pointer to requested row (first column). - inline Standard_Byte* ChangeRow (const Standard_Size theRow) + //! Return data pointer to requested row (first column). + Standard_Byte* ChangeRow (const Standard_Size theRow) { return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown); } - //! @return data pointer to requested position. - inline const Standard_Byte* Value (const Standard_Size theRow, - const Standard_Size theCol) const + //! Return data pointer to requested position. + const Standard_Byte* Value (const Standard_Size theRow, + const Standard_Size theCol) const { return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + SizeBPP * theCol; } - //! @return data pointer to requested position. - inline Standard_Byte* ChangeValue (const Standard_Size theRow, - const Standard_Size theCol) + //! Return data pointer to requested position. + Standard_Byte* ChangeValue (Standard_Size theRow, + Standard_Size theCol) { return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + SizeBPP * theCol; } + //! Return data pointer to requested position. + const Standard_Byte* ValueXY (Standard_Size theX, + Standard_Size theY) const + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX; + } + + //! Return data pointer to requested position. + Standard_Byte* ChangeValueXY (Standard_Size theX, + Standard_Size theY) + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX; + } + +public: + + //! Return data pointer to requested 2D slice. + const Standard_Byte* Slice (Standard_Size theSlice) const + { + return myData + ptrdiff_t(SizeSliceBytes * theSlice); + } + + //! Return data pointer to requested 2D slice. + Standard_Byte* ChangeSlice (Standard_Size theSlice) + { + return myData + ptrdiff_t(SizeSliceBytes * theSlice); + } + + //! Return data pointer to requested row (first column). + const Standard_Byte* SliceRow (Standard_Size theSlice, + Standard_Size theRow) const + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + ptrdiff_t(SizeSliceBytes * theSlice); + } + + //! Return data pointer to requested row (first column). + Standard_Byte* ChangeSliceRow (Standard_Size theSlice, + Standard_Size theRow) + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theRow * TopToDown) + ptrdiff_t(SizeSliceBytes * theSlice); + } + + //! Return data pointer to requested position. + const Standard_Byte* ValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) const + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX + ptrdiff_t(SizeSliceBytes * theZ); + } + + //! Return data pointer to requested position. + Standard_Byte* ChangeValueXYZ (Standard_Size theX, + Standard_Size theY, + Standard_Size theZ) + { + return myTopRowPtr + ptrdiff_t(SizeRowBytes * theY * TopToDown) + SizeBPP * theX + ptrdiff_t(SizeSliceBytes * theZ); + } + //! Compute the maximal row alignment for current row size. //! @return maximal row alignment in bytes (up to 16 bytes). - inline Standard_Size MaxRowAligmentBytes() const + Standard_Size MaxRowAligmentBytes() const { Standard_Size anAlignment = 2; for (; anAlignment <= 16; anAlignment <<= 1) @@ -115,7 +188,7 @@ public: //! Setup scanlines order in memory - top-down or bottom-up. //! Drawers should explicitly specify this value if current state IsTopDown() was ignored! //! @param theIsTopDown top-down flag - inline void SetTopDown (const bool theIsTopDown) + void SetTopDown (const bool theIsTopDown) { TopToDown = (theIsTopDown ? 1 : Standard_Size(-1)); myTopRowPtr = ((TopToDown == 1 || myData == NULL) @@ -128,16 +201,17 @@ protected: public: - Standard_Size SizeBPP; //!< bytes per pixel - Standard_Size SizeX; //!< width in pixels - Standard_Size SizeY; //!< height in pixels - Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX) - Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down - + Standard_Size SizeBPP; //!< bytes per pixel + Standard_Size SizeX; //!< width in pixels + Standard_Size SizeY; //!< height in pixels + Standard_Size SizeZ; //!< depth in pixels + Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX) + Standard_Size SizeSliceBytes; //!< number of bytes per 2D slice + Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down public: - DEFINE_STANDARD_RTTI_INLINE(Image_PixMapData,NCollection_Buffer) // Type definition + DEFINE_STANDARD_RTTIEXT(Image_PixMapData, NCollection_Buffer) }; diff --git a/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx b/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx index 328a32d0c7..6fdac7b109 100644 --- a/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx +++ b/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx @@ -70,9 +70,10 @@ class MeshVS_ImageTexture2D : public Graphic3d_Texture2D { public: - MeshVS_ImageTexture2D (const Handle(Image_PixMap)& theImg) : Graphic3d_Texture2D (theImg, Graphic3d_TOT_2D) + MeshVS_ImageTexture2D (const Handle(Image_PixMap)& theImg) + : Graphic3d_Texture2D (theImg, Graphic3d_TypeOfTexture_2D) { - myParams->SetModulate (Standard_True); + myParams->SetModulate (true); myParams->SetFilter (Graphic3d_TOTF_BILINEAR); } @@ -81,9 +82,6 @@ public: DEFINE_STANDARD_RTTI_INLINE(MeshVS_ImageTexture2D,Graphic3d_Texture2D) }; -DEFINE_STANDARD_HANDLE (MeshVS_ImageTexture2D, Graphic3d_Texture2D) - - //================================================================ // Function : getNearestPow2 // Purpose : Returns the nearest power of two greater than the diff --git a/src/OpenGl/OpenGl_AspectsSprite.cxx b/src/OpenGl/OpenGl_AspectsSprite.cxx index bf9a21df3e..fe9309b44f 100644 --- a/src/OpenGl/OpenGl_AspectsSprite.cxx +++ b/src/OpenGl/OpenGl_AspectsSprite.cxx @@ -261,13 +261,13 @@ void OpenGl_AspectsSprite::build (const Handle(OpenGl_Context)& theCtx, if (!hadAlreadyRGBA) { - aSprite->Init (theCtx, *anImage, Graphic3d_TOT_2D, true); + aSprite->Init (theCtx, *anImage, Graphic3d_TypeOfTexture_2D, true); } if (!hadAlreadyAlpha) { if (Handle(Image_PixMap) anImageA = aSprite->GetFormat() != GL_ALPHA ? aNewMarkerImage->GetImageAlpha() : Handle(Image_PixMap)()) { - aSpriteA->Init (theCtx, *anImageA, Graphic3d_TOT_2D, true); + aSpriteA->Init (theCtx, *anImageA, Graphic3d_TypeOfTexture_2D, true); } } } diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 645f672655..d501804256 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -2136,13 +2136,13 @@ Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_Text myTextureRgbaWhite = new OpenGl_Texture(); Image_PixMap anImage; anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )0); - if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage)) + if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create(), Graphic3d_Vec2i (2, 2), Graphic3d_TypeOfTexture_2D, &anImage)) { PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, "Error: unable to create unit mock PBR texture map."); } anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )255); - if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage)) + if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create(), Graphic3d_Vec2i (2, 2), Graphic3d_TypeOfTexture_2D, &anImage)) { PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, "Error: unable to create normal mock PBR texture map."); diff --git a/src/OpenGl/OpenGl_Font.cxx b/src/OpenGl/OpenGl_Font.cxx index 384c4754a6..2a9b759f44 100755 --- a/src/OpenGl/OpenGl_Font.cxx +++ b/src/OpenGl/OpenGl_Font.cxx @@ -147,7 +147,7 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx) Image_PixMap aBlackImg; if (!aBlackImg.InitZero (Image_Format_Alpha, Standard_Size(aTextureSizeX), Standard_Size(aTextureSizeY)) - || !aTexture->Init (theCtx, aBlackImg, Graphic3d_TOT_2D, true)) // myTextureFormat + || !aTexture->Init (theCtx, aBlackImg, Graphic3d_TypeOfTexture_2D, true)) // myTextureFormat { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, TCollection_AsciiString ("New texture initialization of size ") diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index ca907ab854..066118c772 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -277,7 +277,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo const GLint aColorFormat = myColorFormats (aColorBufferIdx); const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, aColorFormat); if (!aFormat.IsValid() - || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D)) + || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D)) { Release (theGlContext.get()); return Standard_False; @@ -415,7 +415,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo const GLint aColorFormat = myColorFormats (aColorBufferIdx); const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, aColorFormat); if (!aFormat.IsValid() - || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D)) + || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D)) { Release (theGlContext.operator->()); return Standard_False; @@ -426,7 +426,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo // instead of just trying to create such texture const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat); if (aDepthFormat.IsValid() - && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D)) + && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D)) { theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, "Warning! Depth textures are not supported by hardware!"); diff --git a/src/OpenGl/OpenGl_PBREnvironment.cxx b/src/OpenGl/OpenGl_PBREnvironment.cxx index 80da3218dd..13c6d407c7 100644 --- a/src/OpenGl/OpenGl_PBREnvironment.cxx +++ b/src/OpenGl/OpenGl_PBREnvironment.cxx @@ -290,7 +290,7 @@ bool OpenGl_PBREnvironment::initTextures (const Handle(OpenGl_Context)& theCtx) // NVIDIA's driver didn't work properly with 3 channel texture for diffuse SH coefficients so that alpha channel has been added if (!myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Init (theCtx, OpenGl_TextureFormat::FindFormat (theCtx, Image_Format_RGBAF, false), - Graphic3d_Vec2i (9, 1), Graphic3d_TOT_2D)) + Graphic3d_Vec2i (9, 1), Graphic3d_TypeOfTexture_2D)) { Message::SendFail() << "OpenGl_PBREnvironment, DiffuseSH texture creation failed"; return false; @@ -305,7 +305,7 @@ bool OpenGl_PBREnvironment::initTextures (const Handle(OpenGl_Context)& theCtx) if (!myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseFallback].Init (theCtx, OpenGl_TextureFormat::FindFormat (theCtx, Image_Format_RGBA, false), - Graphic3d_Vec2i (10, 4), Graphic3d_TOT_2D)) + Graphic3d_Vec2i (10, 4), Graphic3d_TypeOfTexture_2D)) { Message::SendFail() << "OpenGl_PBREnvironment, DiffuseFallback texture creation failed"; return false; @@ -432,7 +432,7 @@ bool OpenGl_PBREnvironment::processDiffIBLMap (const Handle(OpenGl_Context)& the { if (!myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Init (theCtx, OpenGl_TextureFormat::FindFormat (theCtx, Image_Format_RGBAF, false), - Graphic3d_Vec2i (9, 1), Graphic3d_TOT_2D, &anImageF)) + Graphic3d_Vec2i (9, 1), Graphic3d_TypeOfTexture_2D, &anImageF)) { Message::SendFail() << "OpenGl_PBREnvironment, DiffuseSH texture update failed"; return false; diff --git a/src/OpenGl/OpenGl_Sampler.cxx b/src/OpenGl/OpenGl_Sampler.cxx index 45fe965044..40075fa429 100644 --- a/src/OpenGl/OpenGl_Sampler.cxx +++ b/src/OpenGl/OpenGl_Sampler.cxx @@ -378,7 +378,11 @@ void OpenGl_Sampler::applyGlobalTextureParams (const Handle(OpenGl_Context)& the theCtx->core11fwd->glEnable (GL_TEXTURE_2D); break; } - default: break; + case GL_TEXTURE_3D: + default: + { + break; + } } } @@ -428,6 +432,10 @@ void OpenGl_Sampler::resetGlobalTextureParams (const Handle(OpenGl_Context)& the theCtx->core11fwd->glDisable (GL_TEXTURE_2D); break; } - default: break; + case GL_TEXTURE_3D: + default: + { + break; + } } } diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 655e02001a..19e1359115 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -69,12 +69,6 @@ static Standard_Integer computeUpperMipMapLevel (Standard_Integer theSize) } } -//! Compute the upper mipmap level for complete mipmap set (e.g. till the 1x1 level). -static Standard_Integer computeUpperMipMapLevel (Standard_Integer theSizeX, Standard_Integer theSizeY) -{ - return computeUpperMipMapLevel (Max (theSizeX, theSizeY)); -} - //! Compute size of the smallest defined mipmap level (for verbose messages). static Graphic3d_Vec2i computeSmallestMipMapSize (const Graphic3d_Vec2i& theBaseSize, Standard_Integer theMaxLevel) { @@ -105,9 +99,6 @@ OpenGl_Texture::OpenGl_Texture (const TCollection_AsciiString& theResourceId, myRevision (0), myTextureId (NO_TEXTURE), myTarget (GL_TEXTURE_2D), - mySizeX (0), - mySizeY (0), - mySizeZ (0), myTextFormat (GL_RGBA), mySizedFormat(GL_RGBA8), myNbSamples (1), @@ -169,7 +160,7 @@ void OpenGl_Texture::Release (OpenGl_Context* theGlCtx) theGlCtx->core11fwd->glDeleteTextures (1, &myTextureId); } myTextureId = NO_TEXTURE; - mySizeX = mySizeY = mySizeZ = 0; + mySize.SetValues (0, 0, 0); } // ======================================================================= @@ -231,12 +222,13 @@ bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx) // ======================================================================= bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, const OpenGl_TextureFormat& theFormat, - const Graphic3d_Vec2i& theSizeXY, + const Graphic3d_Vec3i& theSizeXYZ, const Graphic3d_TypeOfTexture theType, const Image_PixMap* theImage) { - if (theSizeXY.x() < 1 - || theSizeXY.y() < 1) + if (theSizeXYZ.x() < 1 + || theSizeXYZ.y() < 1 + || theSizeXYZ.z() < 1) { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, TCollection_AsciiString ("Error: texture of 0 size cannot be created [") + myResourceId +"]"); @@ -244,16 +236,39 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - const GLenum aTarget = (theType == Graphic3d_TOT_1D - && theCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES) - ? GL_TEXTURE_1D - : GL_TEXTURE_2D; + GLenum aTarget = GL_TEXTURE_2D; + switch (theType) + { + case Graphic3d_TypeOfTexture_1D: + { + aTarget = theCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES + ? GL_TEXTURE_1D + : GL_TEXTURE_2D; + break; + } + case Graphic3d_TypeOfTexture_2D: + case Graphic3d_TOT_2D_MIPMAP: + { + aTarget = GL_TEXTURE_2D; + break; + } + case Graphic3d_TypeOfTexture_3D: + { + aTarget = GL_TEXTURE_3D; + break; + } + case Graphic3d_TypeOfTexture_CUBEMAP: + { + aTarget = GL_TEXTURE_CUBE_MAP; + break; + } + } const bool toPatchExisting = IsValid() && myTextFormat == theFormat.PixelFormat() && myTarget == aTarget - && HasMipmaps() == (theType == Graphic3d_TOT_2D_MIPMAP) - && mySizeX == theSizeXY.x() - && (mySizeY == theSizeXY.y() || theType == Graphic3d_TOT_1D); + && mySize.x() == theSizeXYZ.x() + && (mySize.y() == theSizeXYZ.y() || theType == Graphic3d_TypeOfTexture_1D) + && mySize.z() == theSizeXYZ.z(); if (!Create (theCtx)) { Release (theCtx.get()); @@ -271,9 +286,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, myIsAlpha = theFormat.PixelFormat() == GL_ALPHA; } - myMaxMipLevel = theType == Graphic3d_TOT_2D_MIPMAP && theCtx->arbFBO != NULL - ? computeUpperMipMapLevel (theSizeXY.x(), theSizeXY.y()) - : 0; + myMaxMipLevel = 0; myTextFormat = theFormat.PixelFormat(); mySizedFormat = theFormat.InternalFormat(); myNbSamples = 1; @@ -293,12 +306,12 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - const GLsizei aMaxSize = theCtx->MaxTextureSize(); - if (theSizeXY.x() > aMaxSize - || theSizeXY.y() > aMaxSize) + const Standard_Integer aMaxSize = theCtx->MaxTextureSize(); + if (theSizeXYZ.maxComp() > aMaxSize) { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Error: Texture dimension - ") + theSizeXY.x() + "x" + theSizeXY.y() + TCollection_AsciiString ("Error: Texture dimension - ") + theSizeXYZ.x() + "x" + theSizeXYZ.y() + + (theSizeXYZ.z() > 1 ? TCollection_AsciiString ("x") + theSizeXYZ.z() : TCollection_AsciiString()) + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")" + " [" + myResourceId +"]"); Release (theCtx.get()); @@ -312,34 +325,18 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, // however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT! // Trying to create NPOT textures on such hardware will not fail // but driver will fall back into software rendering, - const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.x(), aMaxSize); - const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.y(), aMaxSize); - if (theSizeXY.x() != aWidthP2 - || (theType != Graphic3d_TOT_1D && theSizeXY.y() != aHeightP2)) + const Graphic3d_Vec2i aSizeP2 (OpenGl_Context::GetPowerOfTwo (theSizeXYZ.x(), aMaxSize), + OpenGl_Context::GetPowerOfTwo (theSizeXYZ.y(), aMaxSize)); + if (theSizeXYZ.x() != aSizeP2.x() + || (theType != Graphic3d_TypeOfTexture_1D && theSizeXYZ.y() != aSizeP2.y())) { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Error: NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")" + TCollection_AsciiString ("Error: NPOT Textures (") + theSizeXYZ.x() + "x" + theSizeXYZ.y() + ")" " are not supported by hardware [" + myResourceId +"]"); Release (theCtx.get()); return false; } } - else if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES - && !theCtx->IsGlGreaterEqual (3, 0) - && theType == Graphic3d_TOT_2D_MIPMAP) - { - // Mipmap NPOT textures are not supported by OpenGL ES 2.0. - const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.x(), aMaxSize); - const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.y(), aMaxSize); - if (theSizeXY.x() != aWidthP2 - || theSizeXY.y() != aHeightP2) - { - theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Warning: Mipmap NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")" - " are not supported by OpenGL ES 2.0 [" + myResourceId +"]"); - myMaxMipLevel = 0; - } - } GLint aTestWidth = 0, aTestHeight = 0; GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL; @@ -370,7 +367,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, myTarget = aTarget; switch (theType) { - case Graphic3d_TOT_1D: + case Graphic3d_TypeOfTexture_1D: { if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) { @@ -385,14 +382,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, if (toPatchExisting) { theCtx->core11fwd->glTexSubImage1D (GL_TEXTURE_1D, 0, 0, - theSizeXY.x(), theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); - Unbind (theCtx); - return true; + theSizeXYZ.x(), theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); + break; } // use proxy to check texture could be created or not theCtx->core11fwd->glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat, - theSizeXY.x(), 0, + theSizeXYZ.x(), 0, theFormat.PixelFormat(), theFormat.DataType(), NULL); theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &aTestWidth); theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat); @@ -405,7 +401,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, } theCtx->core11fwd->glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat, - theSizeXY.x(), 0, + theSizeXYZ.x(), 0, theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); if (theCtx->core11fwd->glGetError() != GL_NO_ERROR) { @@ -414,13 +410,10 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = theSizeXY.x(); - mySizeY = 1; - - Unbind (theCtx); - return true; + mySize.SetValues (theSizeXYZ.x(), 1, 1); + break; } - case Graphic3d_TOT_2D: + case Graphic3d_TypeOfTexture_2D: case Graphic3d_TOT_2D_MIPMAP: { Bind (theCtx); @@ -429,28 +422,16 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, { theCtx->core11fwd->glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, - theSizeXY.x(), theSizeXY.y(), + theSizeXYZ.x(), theSizeXYZ.y(), theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); - - if (myMaxMipLevel > 0) - { - // generate mipmaps - theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D); - if (theCtx->core11fwd->glGetError() != GL_NO_ERROR) - { - myMaxMipLevel = 0; - } - } - - Unbind (theCtx); - return true; + break; } if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGL) { // use proxy to check texture could be created or not theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat, - theSizeXY.x(), theSizeXY.y(), 0, + theSizeXYZ.x(), theSizeXYZ.y(), 0, theFormat.PixelFormat(), theFormat.DataType(), NULL); theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth); theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight); @@ -465,13 +446,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, } theCtx->core11fwd->glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat, - theSizeXY.x(), theSizeXY.y(), 0, + theSizeXYZ.x(), theSizeXYZ.y(), 0, theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); GLenum anErr = theCtx->core11fwd->glGetError(); if (anErr != GL_NO_ERROR) { theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Error: 2D texture ") + theSizeXY.x() + "x" + theSizeXY.y() + TCollection_AsciiString ("Error: 2D texture ") + theSizeXYZ.x() + "x" + theSizeXYZ.y() + " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat) + " PF: " + OpenGl_TextureFormat::FormatFormat (theFormat.PixelFormat()) + " DT: " + OpenGl_TextureFormat::FormatDataType (theFormat.DataType()) @@ -482,38 +463,63 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = theSizeXY.x(); - mySizeY = theSizeXY.y(); - - if (myMaxMipLevel > 0) + mySize.SetValues (theSizeXYZ.xy(), 1); + break; + } + case Graphic3d_TypeOfTexture_3D: + { + if (theCtx->Functions()->glTexImage3D == nullptr) { - // generate mipmaps - //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST); - theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D); - anErr = theCtx->core11fwd->glGetError(); - if (anErr != GL_NO_ERROR) + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, + "Error: three-dimensional textures are not supported by hardware."); + Unbind (theCtx); + Release (theCtx.get()); + return false; + } + + Bind (theCtx); + applyDefaultSamplerParams (theCtx); + if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGL) + { + theCtx->Functions()->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, anIntFormat, + theSizeXYZ.x(), theSizeXYZ.y(), theSizeXYZ.z(), 0, + theFormat.PixelFormat(), theFormat.DataType(), nullptr); + + NCollection_Vec3 aTestSizeXYZ; + theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeXYZ.x()); + theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeXYZ.y()); + theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeXYZ.z()); + theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat); + if (aTestSizeXYZ.x() == 0 || aTestSizeXYZ.y() == 0 || aTestSizeXYZ.z() == 0) { - myMaxMipLevel = 0; - if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES - && (theFormat.InternalFormat() == GL_RGB8 - || theFormat.InternalFormat() == GL_SRGB8)) - { - theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Warning: generating mipmaps requires color-renderable format, while giving ") - + OpenGl_TextureFormat::FormatFormat (anIntFormat) + " [" + myResourceId +"]"); - } - else - { - theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Warning: generating mipmaps has failed [") + myResourceId +"]"); - } + Unbind (theCtx); + Release (theCtx.get()); + return false; } } - Unbind (theCtx); - return true; + theCtx->Functions()->glTexImage3D (GL_TEXTURE_3D, 0, anIntFormat, + theSizeXYZ.x(), theSizeXYZ.y(), theSizeXYZ.z(), 0, + theFormat.PixelFormat(), theFormat.DataType(), aDataPtr); + GLenum anErr = theCtx->core11fwd->glGetError(); + if (anErr != GL_NO_ERROR) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, + TCollection_AsciiString ("Error: 3D texture ") + theSizeXYZ.x() + "x" + theSizeXYZ.y() + "x" + theSizeXYZ.z() + + " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat) + + " PF: " + OpenGl_TextureFormat::FormatFormat (theFormat.PixelFormat()) + + " DT: " + OpenGl_TextureFormat::FormatDataType (theFormat.DataType()) + + " can not be created with error " + OpenGl_Context::FormatGlError (anErr) + + " [" + myResourceId +"]"); + Unbind (theCtx); + Release (theCtx.get()); + return false; + } + + mySize = theSizeXYZ; + break; } - case Graphic3d_TOT_CUBEMAP: + case Graphic3d_TypeOfTexture_CUBEMAP: { Unbind (theCtx); Release (theCtx.get()); @@ -521,8 +527,82 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, } } - Release (theCtx.get()); - return false; + Unbind (theCtx); + return true; +} + +// ======================================================================= +// function : GenerateMipmaps +// purpose : +// ======================================================================= +bool OpenGl_Texture::GenerateMipmaps (const Handle(OpenGl_Context)& theCtx) +{ + if (theCtx->arbFBO == nullptr + || !IsValid()) + { + return false; + } + + myMaxMipLevel = computeUpperMipMapLevel (mySize.maxComp()); + + const Standard_Integer aMaxSize = theCtx->MaxTextureSize(); + if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES + && !theCtx->IsGlGreaterEqual (3, 0)) + { + // Mipmap NPOT textures are not supported by OpenGL ES 2.0. + const Graphic3d_Vec2i aSizeP2 (OpenGl_Context::GetPowerOfTwo (mySize.x(), aMaxSize), + OpenGl_Context::GetPowerOfTwo (mySize.y(), aMaxSize)); + if (mySize.xy() != aSizeP2) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, + TCollection_AsciiString ("Warning: Mipmap NPOT Textures (") + mySize.x() + "x" + mySize.y() + ")" + " are not supported by OpenGL ES 2.0 [" + myResourceId +"]"); + myMaxMipLevel = 0; + } + } + + if (myMaxMipLevel <= 0) + { + return false; + } + + //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST); + Bind (theCtx); + if (theCtx->HasTextureBaseLevel() + && !mySampler->isValidSampler()) + { + const Standard_Integer aMaxLevel = Min (myMaxMipLevel, mySampler->Parameters()->MaxLevel()); + mySampler->SetParameter (theCtx, myTarget, GL_TEXTURE_MAX_LEVEL, aMaxLevel); + } + theCtx->arbFBO->glGenerateMipmap (myTarget); + GLenum anErr = theCtx->core11fwd->glGetError(); + if (anErr != GL_NO_ERROR) + { + myMaxMipLevel = 0; + if (theCtx->HasTextureBaseLevel() + && !mySampler->isValidSampler()) + { + mySampler->SetParameter (theCtx, myTarget, GL_TEXTURE_MAX_LEVEL, 0); + } + + if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES + && (mySizedFormat == GL_RGB8 + || mySizedFormat == GL_SRGB8)) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, + TCollection_AsciiString ("Warning: generating mipmaps requires color-renderable format, while giving ") + + OpenGl_TextureFormat::FormatFormat (mySizedFormat) + " [" + myResourceId +"]"); + } + else + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, + TCollection_AsciiString ("Warning: generating mipmaps has failed [") + myResourceId +"]"); + } + } + + applyDefaultSamplerParams (theCtx); + Unbind (theCtx); + return true; } // ======================================================================= @@ -550,16 +630,15 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - return Init (theCtx, aFormat, Graphic3d_Vec2i ((Standard_Integer)theImage.SizeX(), (Standard_Integer)theImage.SizeY()), - theType, &theImage); + return Init (theCtx, aFormat, Graphic3d_Vec3i (theImage.SizeXYZ()), theType, &theImage); } // ======================================================================= // function : Init // purpose : // ======================================================================= -bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, - const Handle(Graphic3d_TextureMap)& theTextureMap) +bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, + const Handle(Graphic3d_TextureRoot)& theTextureMap) { if (theTextureMap.IsNull()) { @@ -568,7 +647,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, switch (theTextureMap->Type()) { - case Graphic3d_TOT_CUBEMAP: + case Graphic3d_TypeOfTexture_CUBEMAP: { return InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap), 0, Image_Format_RGB, false, theTextureMap->IsColorMap()); @@ -589,7 +668,15 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, { return false; } - return Init (theCtx, *anImage, theTextureMap->Type(), theTextureMap->IsColorMap()); + if (!Init (theCtx, *anImage, theTextureMap->Type(), theTextureMap->IsColorMap())) + { + return false; + } + if (theTextureMap->HasMipmaps()) + { + GenerateMipmaps (theCtx); + } + return true; } } } @@ -641,23 +728,22 @@ bool OpenGl_Texture::InitCompressed (const Handle(OpenGl_Context)& theCtx, myTextFormat = aFormat.Format(); mySizedFormat = aFormat.Internal(); myIsTopDown = theImage.IsTopDown(); - mySizeX = theImage.SizeX(); - mySizeY = theImage.SizeY(); + mySize.SetValues (theImage.SizeX(), theImage.SizeY(), 1); myMaxMipLevel = Max (theImage.MipMaps().Size() - 1, 0); if (myMaxMipLevel > 0 && !theImage.IsCompleteMipMapSet()) { - const Graphic3d_Vec2i aMipSize = computeSmallestMipMapSize (Graphic3d_Vec2i (mySizeX, mySizeY), myMaxMipLevel); + const Graphic3d_Vec2i aMipSize = computeSmallestMipMapSize (mySize.xy(), myMaxMipLevel); if (!theCtx->HasTextureBaseLevel()) { myMaxMipLevel = 0; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0, GL_DEBUG_SEVERITY_MEDIUM, - TCollection_AsciiString ("Warning: compressed 2D texture ") + myResourceId + " " + mySizeX + "x" + mySizeY + TCollection_AsciiString ("Warning: compressed 2D texture ") + myResourceId + " " + mySize.x() + "x" + mySize.y() + " has smallest mipmap " + aMipSize.x() + "x" + aMipSize.y() + "; mipmaps will be ignored"); } else { - Message::SendTrace (TCollection_AsciiString ("Warning: compressed 2D texture ") + myResourceId + " " + mySizeX + "x" + mySizeY + Message::SendTrace (TCollection_AsciiString ("Warning: compressed 2D texture ") + myResourceId + " " + mySize.x() + "x" + mySize.y() + " has smallest mipmap " + aMipSize.x() + "x" + aMipSize.y()); } } @@ -762,8 +848,7 @@ bool OpenGl_Texture::Init2DMultisample (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = theSizeX; - mySizeY = theSizeY; + mySize.SetValues (theSizeX, theSizeY, 1); Unbind (theCtx); return true; @@ -824,8 +909,7 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = aSizeX; - mySizeY = aSizeY; + mySize.SetValues (aSizeX, aSizeY, 1); Unbind (theCtx); return true; } @@ -912,9 +996,7 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = aSizeXYZ.x(); - mySizeY = aSizeXYZ.y(); - mySizeZ = aSizeXYZ.z(); + mySize = aSizeXYZ; Unbind (theCtx); return true; @@ -940,6 +1022,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, Handle(Image_PixMap) anImage; Handle(Image_CompressedPixMap) aCompImage; OpenGl_TextureFormat aFormat; + myMaxMipLevel = 0; if (!theCubeMap.IsNull()) { theCubeMap->Reset(); @@ -997,15 +1080,10 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, theSize = anImage->SizeX(); theFormat = anImage->Format(); theToGenMipmap = theCubeMap->HasMipmaps(); - myMaxMipLevel = theToGenMipmap ? computeUpperMipMapLevel ((Standard_Integer )theSize) : 0; } myIsTopDown = theCubeMap->IsTopDown(); } - else - { - myMaxMipLevel = theToGenMipmap ? computeUpperMipMapLevel ((Standard_Integer )theSize) : 0; - } if (!aFormat.IsValid()) { @@ -1036,8 +1114,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, myTarget = GL_TEXTURE_CUBE_MAP; myNbSamples = 1; - mySizeX = (GLsizei )theSize; - mySizeY = (GLsizei )theSize; + mySize.SetValues ((GLsizei )theSize, (GLsizei )theSize, 1); myTextFormat = aFormat.Format(); mySizedFormat = aFormat.Internal(); @@ -1069,7 +1146,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, } if (!aCompImage.IsNull()) { - Graphic3d_Vec2i aMipSizeXY (mySizeX, mySizeY); + Graphic3d_Vec2i aMipSizeXY = mySize.xy(); aData = aCompImage->FaceData()->Data(); for (Standard_Integer aMipIter = 0; aMipIter <= myMaxMipLevel; ++aMipIter) { @@ -1167,16 +1244,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, if (theToGenMipmap && theCtx->arbFBO != NULL) { - theCtx->arbFBO->glGenerateMipmap (myTarget); - const GLenum anErr = theCtx->core11fwd->glGetError(); - if (anErr != GL_NO_ERROR) - { - theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, - TCollection_AsciiString ("Unable to generate mipmap of cubemap with format ") - + OpenGl_TextureFormat::FormatFormat (anIntFormat) - + ", error " + OpenGl_Context::FormatGlError (anErr)); - myMaxMipLevel = 0; - } + GenerateMipmaps (theCtx); } Unbind (theCtx.get()); @@ -1250,14 +1318,14 @@ Standard_Size OpenGl_Texture::EstimatedDataSize() const return 0; } - Standard_Size aSize = PixelSizeOfPixelFormat (mySizedFormat) * mySizeX * myNbSamples; - if (mySizeY != 0) + Standard_Size aSize = PixelSizeOfPixelFormat (mySizedFormat) * mySize.x() * myNbSamples; + if (mySize.y() != 0) { - aSize *= Standard_Size(mySizeY); + aSize *= Standard_Size(mySize.y()); } - if (mySizeZ != 0) + if (mySize.z() != 0) { - aSize *= Standard_Size(mySizeZ); + aSize *= Standard_Size(mySize.z()); } if (myTarget == GL_TEXTURE_CUBE_MAP) { @@ -1294,7 +1362,7 @@ bool OpenGl_Texture::ImageDump (Image_PixMap& theImage, } GLenum aTarget = myTarget; - Graphic3d_Vec2i aSize (mySizeX, mySizeY); + Graphic3d_Vec2i aSize = mySize.xy(); if (myTarget == GL_TEXTURE_CUBE_MAP) { aTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + theCubeSide; diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 17aa05ab22..dee0ddd0f2 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -53,11 +53,17 @@ public: //! @return target to which the texture is bound (GL_TEXTURE_1D, GL_TEXTURE_2D) unsigned int GetTarget() const { return myTarget; } - //! @return texture width (0 LOD) - GLsizei SizeX() const { return mySizeX; } + //! Return texture dimensions (0 LOD) + const Graphic3d_Vec3i& Size() const { return mySize; } - //! @return texture height (0 LOD) - GLsizei SizeY() const { return mySizeY; } + //! Return texture width (0 LOD) + Standard_Integer SizeX() const { return mySize.x(); } + + //! Return texture height (0 LOD) + Standard_Integer SizeY() const { return mySize.y(); } + + //! Return texture depth (0 LOD) + Standard_Integer SizeZ() const { return mySize.z(); } //! @return texture ID unsigned int TextureId() const { return myTextureId; } @@ -140,15 +146,30 @@ public: //! Notice that texture will be unbound after this call. Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx, const OpenGl_TextureFormat& theFormat, - const Graphic3d_Vec2i& theSizeXY, + const Graphic3d_Vec3i& theSizeXYZ, const Graphic3d_TypeOfTexture theType, const Image_PixMap* theImage = NULL); + //! Initialize the 2D texture with specified format, size and texture type. + //! If theImage is empty the texture data will contain trash. + //! Notice that texture will be unbound after this call. + bool Init (const Handle(OpenGl_Context)& theCtx, + const OpenGl_TextureFormat& theFormat, + const Graphic3d_Vec2i& theSizeXY, + const Graphic3d_TypeOfTexture theType, + const Image_PixMap* theImage = NULL) + { + return Init (theCtx, theFormat, Graphic3d_Vec3i (theSizeXY, 1), theType, theImage); + } + //! Initialize the texture with Graphic3d_TextureMap. //! It is an universal way to initialize. //! Suitable initialization method will be chosen. - Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx, - const Handle(Graphic3d_TextureMap)& theTextureMap); + Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx, + const Handle(Graphic3d_TextureRoot)& theTextureMap); + + //! Generate mipmaps. + Standard_EXPORT bool GenerateMipmaps (const Handle(OpenGl_Context)& theCtx); //! Initialize the texture with Image_CompressedPixMap. Standard_EXPORT bool InitCompressed (const Handle(OpenGl_Context)& theCtx, @@ -302,9 +323,7 @@ protected: Standard_Size myRevision; //!< revision of associated data source unsigned int myTextureId; //!< GL resource ID unsigned int myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D - Standard_Integer mySizeX; //!< texture width - Standard_Integer mySizeY; //!< texture height - Standard_Integer mySizeZ; //!< texture depth + Graphic3d_Vec3i mySize; //!< texture width x height x depth unsigned int myTextFormat; //!< texture format - GL_RGB, GL_RGBA,... Standard_Integer mySizedFormat;//!< internal (sized) texture format Standard_Integer myNbSamples; //!< number of MSAA samples diff --git a/src/OpenGl/OpenGl_TileSampler.cxx b/src/OpenGl/OpenGl_TileSampler.cxx index 3d988e4d1f..caa13711a6 100644 --- a/src/OpenGl/OpenGl_TileSampler.cxx +++ b/src/OpenGl/OpenGl_TileSampler.cxx @@ -302,7 +302,7 @@ bool OpenGl_TileSampler::upload (const Handle(OpenGl_Context)& theContext, if (!theOffsetsTexture->Init (theContext, OpenGl_TextureFormat::FindSizedFormat (theContext, GL_RG32I), Graphic3d_Vec2i ((int )anOffsets.SizeX, (int )anOffsets.SizeY), - Graphic3d_TOT_2D)) + Graphic3d_TypeOfTexture_2D)) { hasErrors = true; } diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 97a98a6737..54cc8b48b2 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -343,10 +343,8 @@ void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext) } Handle(OpenGl_Texture) aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams()); - if (Handle(Image_PixMap) anImage = myTextureEnvData->GetImage (theContext->SupportedTextureFormats())) - { - aTextureEnv->Init (theContext, *anImage, myTextureEnvData->Type(), true); - } + aTextureEnv->Init (theContext, myTextureEnvData); + myTextureEnv = new OpenGl_TextureSet (aTextureEnv); myTextureEnv->ChangeTextureSetBits() = Graphic3d_TextureSetBits_BaseColor; } @@ -1391,7 +1389,7 @@ bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj) aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit()); anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams); if (!aTexFormat.IsValid() - || !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get())) + || !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TypeOfTexture_2D, aPixMap.get())) { aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR"); anEnvLUT.Nullify(); diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index d36c0c5aba..299b7b014b 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -1949,13 +1949,13 @@ Standard_Boolean OpenGl_View::updateRaytraceBuffers (const Standard_Integer myRaytraceVisualErrorTexture[aViewIter]->Init (theGlContext, OpenGl_TextureFormat::FindSizedFormat (theGlContext, GL_R32I), Graphic3d_Vec2i (myTileSampler.NbTilesX(), myTileSampler.NbTilesY()), - Graphic3d_TOT_2D); + Graphic3d_TypeOfTexture_2D); if (!myRaytraceParameters.AdaptiveScreenSamplingAtomic) { myRaytraceTileSamplesTexture[aViewIter]->Init (theGlContext, OpenGl_TextureFormat::FindSizedFormat (theGlContext, GL_R32I), Graphic3d_Vec2i (myTileSampler.NbTilesX(), myTileSampler.NbTilesY()), - Graphic3d_TOT_2D); + Graphic3d_TypeOfTexture_2D); } } else // non-adaptive mode diff --git a/src/QABugs/QABugs_1.cxx b/src/QABugs/QABugs_1.cxx index b15836c6f4..f58eff1888 100644 --- a/src/QABugs/QABugs_1.cxx +++ b/src/QABugs/QABugs_1.cxx @@ -508,7 +508,7 @@ static Standard_Integer OCC30182 (Draw_Interpretor& , Standard_Integer theNbArgs const Handle(Graphic3d_AspectFillArea3d)& anAspect = aPrs->Attributes()->ShadingAspect()->Aspect(); anAspect->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit); anAspect->SetTextureMapOn (true); - anAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (anImage)); + anAspect->SetTextureMap (new Graphic3d_Texture2D (anImage)); if (anImage->IsTopDown()) { anAspect->TextureMap()->GetParams()->SetTranslation(Graphic3d_Vec2 (0.0f, -1.0f)); diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index ecd4c1d6b4..7f8eb4afec 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -479,7 +479,7 @@ void V3d_View::SetBackgroundImage (const Standard_CString theFileName, const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate) { - Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2Dmanual (theFileName); + Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2D (theFileName); aTextureMap->DisableModulate(); SetBackgroundImage (aTextureMap, theFillStyle, theToUpdate); } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 533ffb7a4a..35e392a98b 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -48,7 +48,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -4145,13 +4146,8 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, return 1; } - int toModulate = -1; - int toSetSRgb = -1; - bool toSetFilter = false; - bool toSetAniso = false; - bool toSetTrsfAngle = false; - bool toSetTrsfTrans = false; - bool toSetTrsfScale = false; + int toModulate = -1, toSetSRgb = -1; + bool toSetFilter = false, toSetAniso = false, toSetTrsfAngle = false, toSetTrsfTrans = false, toSetTrsfScale = false; Standard_ShortReal aTrsfRotAngle = 0.0f; Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f); Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f); @@ -4161,12 +4157,8 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, Handle(AIS_InteractiveObject) aTexturedIO; Handle(AIS_Shape) aTexturedShape; Handle(Graphic3d_TextureSet) aTextureSetOld; - NCollection_Vector aTextureVecNew; - bool toSetGenRepeat = false; - bool toSetGenScale = false; - bool toSetGenOrigin = false; - bool toSetImage = false; - bool toComputeUV = false; + NCollection_Vector aTextureVecNew; + bool toSetGenRepeat = false, toSetGenScale = false, toSetGenOrigin = false, toSetImage = false, toComputeUV = false; const TCollection_AsciiString aCommandName (theArgVec[0]); bool toSetDefaults = aCommandName == "vtexdefault"; @@ -4441,6 +4433,38 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aMedia); aTextureSetOld.Nullify(); } + else if (aCommandName == "vtexture" + && aTextureVecNew.IsEmpty() + && aNameCase == "-3d") + { + TColStd_SequenceOfAsciiString aSlicesSeq; + for (; anArgIter + 1 < theArgsNb; ++anArgIter) + { + TCollection_AsciiString aSlicePath (theArgVec[anArgIter + 1]); + if (aSlicePath.StartsWith ("-")) + { + break; + } + + aSlicesSeq.Append (aSlicePath); + } + + if (aSlicesSeq.Size() < 2) + { + Message::SendFail() << "Syntax error at '" << aNameCase << "'"; + return 1; + } + NCollection_Array1 aSlices; + aSlices.Resize (0, aSlicesSeq.Size() - 1, false); + Standard_Integer aSliceIndex = 0; + for (const TCollection_AsciiString& aSliceIter : aSlicesSeq) + { + aSlices[aSliceIndex++] = aSliceIter; + } + + toSetImage = true; + aTextureVecNew.SetValue (0, new Graphic3d_Texture3D (aSlices)); + } else if (aCommandName == "vtexture" && (aTextureVecNew.IsEmpty() || aNameCase.StartsWith ("-tex"))) @@ -4483,7 +4507,7 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, Message::SendFail() << "Syntax error: texture with ID " << aValue << " is undefined!"; return 1; } - aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue))); + aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2D (Graphic3d_NameOfTexture2D (aValue))); } else if (aTexName == "?") { @@ -4507,11 +4531,11 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, Message::SendFail() << "Syntax error: non-existing image file has been specified '" << aTexName << "'."; return 1; } - aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName)); + aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2D (aTexName)); } else { - aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)()); + aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_TextureMap)()); } if (aTextureVecNew.Value (aTexIndex)) @@ -4537,7 +4561,7 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size()); for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter) { - Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter); + Handle(Graphic3d_TextureMap)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter); Handle(Graphic3d_TextureRoot) aTextureOld; if (!aTextureSetOld.IsNull() && aTexIter < aTextureSetOld->Size()) @@ -4549,17 +4573,21 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, && !aTextureNew.IsNull()) { *aTextureNew->GetParams() = *aTextureOld->GetParams(); - if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld)) + + Handle(Graphic3d_Texture2D) aTex2dNew = Handle(Graphic3d_Texture2D)::DownCast (aTextureNew); + Handle(Graphic3d_Texture2D) aTex2dOld = Handle(Graphic3d_Texture2D)::DownCast (aTextureOld); + if (!aTex2dOld.IsNull() + && !aTex2dNew.IsNull()) { TCollection_AsciiString aFilePathOld, aFilePathNew; aTextureOld->Path().SystemName (aFilePathOld); aTextureNew->Path().SystemName (aFilePathNew); - if (aTextureNew->Name() == anOldManualTex->Name() + if (aTex2dNew->Name() == aTex2dOld->Name() && aFilePathOld == aFilePathNew - && (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN)) + && (!aFilePathNew.IsEmpty() || aTex2dNew->Name() != Graphic3d_NOT_2D_UNKNOWN)) { --aNbChanged; - aTextureNew = anOldManualTex; + aTextureNew = aTex2dOld; } } } @@ -6816,6 +6844,7 @@ Sets default deflection coefficient (0.0008) that defines the quality of the sha addCmd ("vtexture", VTexture, /* [vtexture] */ R"( vtexture [-noupdate|-update] name [ImageFile|IdOfTexture|off] [-tex0 Image0] [-tex1 Image1] [...] + [-3d Image0 Image1 ... ImageN] [-origin {u v|off}] [-scale {u v|off}] [-repeat {u v|off}] [-trsfTrans du dv] [-trsfScale su sv] [-trsfAngle Angle] [-modulate {on|off}] [-srgb {on|off}]=on @@ -6836,6 +6865,7 @@ The options are: -setFilter Setup texture filter -setAnisoFilter Setup anisotropic filter for texture with mip-levels -default Sets texture mapping default parameters + -3d Load 3D texture from the list of 2D image files )" /* [vtexture] */); addCmd ("vtexscale", VTexture, /* [vtexscale] */ R"( diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index fd57606da1..d3ff434e14 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -411,6 +411,15 @@ static Standard_Integer VShaderProg (Draw_Interpretor& , } aProgram->SetHeader (aHeader); } + else if (!aProgram.IsNull() + && (anArg == "-defaultsampler" + || anArg == "-defampler" + || anArg == "-nodefaultsampler" + || anArg == "-nodefsampler")) + { + bool toUseDefSampler = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); + aProgram->SetDefaultSampler (toUseDefSampler); + } else if (!anArg.StartsWith ("-") && GetMapOfAIS().IsBound2 (theArgVec[anArgIter])) { @@ -1187,6 +1196,7 @@ vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader] [-header VersionHeader] [-tessControl TessControlShader -tessEval TessEvaluationShader] [-uniform Name FloatValue] + [-defaultSampler {0|1}]=1 Assign custom GLSL program to presentation aspects. )" /* [vshader] */); diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 3bf244970b..e660e85026 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -3069,7 +3069,7 @@ static int VBackground (Draw_Interpretor& theDI, if (!anImagePath.IsEmpty()) { - Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2Dmanual (anImagePath); + Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2D (anImagePath); aTextureMap->DisableModulate(); aTextureMap->SetColorMap (isSRgb); if (!aTextureMap->IsDone()) @@ -5897,7 +5897,7 @@ public: aMat.SetSpecularColor (Quantity_NOC_BLACK); aMat.SetEmissiveColor (Quantity_NOC_BLACK); aFillAspect->SetFrontMaterial (aMat); - aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage)); + aFillAspect->SetTextureMap (new Graphic3d_Texture2D (theImage)); aFillAspect->SetTextureMapOn(); } { @@ -8609,7 +8609,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons } TCollection_AsciiString aTextureName (aChangeArgs[1]); - Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName); + Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D (aTextureName); if (!aTexture->IsDone()) { aClipPlane->SetCappingTexture (NULL); diff --git a/src/XCAFPrs/XCAFPrs_Texture.cxx b/src/XCAFPrs/XCAFPrs_Texture.cxx index 3c5519cadc..178e28b7b1 100644 --- a/src/XCAFPrs/XCAFPrs_Texture.cxx +++ b/src/XCAFPrs/XCAFPrs_Texture.cxx @@ -15,7 +15,7 @@ #include -IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2Dmanual) +IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2D) //======================================================================= //function : XCAFPrs_Texture @@ -23,7 +23,7 @@ IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2Dmanual) //======================================================================= XCAFPrs_Texture::XCAFPrs_Texture (const Image_Texture& theImageSource, const Graphic3d_TextureUnit theUnit) -: Graphic3d_Texture2Dmanual (""), +: Graphic3d_Texture2D (""), myImageSource (theImageSource) { if (!myImageSource.TextureId().IsEmpty()) diff --git a/src/XCAFPrs/XCAFPrs_Texture.hxx b/src/XCAFPrs/XCAFPrs_Texture.hxx index f950139efd..8c86b52625 100644 --- a/src/XCAFPrs/XCAFPrs_Texture.hxx +++ b/src/XCAFPrs/XCAFPrs_Texture.hxx @@ -21,9 +21,9 @@ #include //! Texture holder. -class XCAFPrs_Texture : public Graphic3d_Texture2Dmanual +class XCAFPrs_Texture : public Graphic3d_Texture2D { - DEFINE_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2Dmanual) + DEFINE_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2D) public: //! Constructor. diff --git a/tests/opengl/data/textures/cubemap_jpg b/tests/opengl/data/textures/cubemap_jpg index 31aa2ff052..a84122c665 100644 --- a/tests/opengl/data/textures/cubemap_jpg +++ b/tests/opengl/data/textures/cubemap_jpg @@ -17,8 +17,6 @@ vinit v -w 512 -h 512 vcamera -fovy 100 if { [checkplatform -windows] && [vdriver -default] == "TKOpenGles" } { # Mipmaps cannot be generated for GL_SRGB8 texture format - puts "TODO OCC30807 ALL: TKOpenGl | Type: Error" - puts "TODO OCC30807 ALL: Unable to generate mipmap of cubemap" } vbackground -cubemap $aCubeMap_posx $aCubeMap_negx $aCubeMap_posy $aCubeMap_negy $aCubeMap_posz $aCubeMap_negz diff --git a/tests/opengl/data/textures/texture_3d b/tests/opengl/data/textures/texture_3d new file mode 100644 index 0000000000..7abd9bae66 --- /dev/null +++ b/tests/opengl/data/textures/texture_3d @@ -0,0 +1,60 @@ +puts "========" +puts "0032862: Visualization, Graphic3d_TextureMap - add 3D texture definition" +puts "========" + +pload MODELING VISUALIZATION + +set aTex1 [locate_data_file SF_CubeMap_posx.jpg] +set aTex2 [locate_data_file SF_CubeMap_negx.jpg] +set aTex3 [locate_data_file SF_CubeMap_posy.jpg] +set aTex4 [locate_data_file SF_CubeMap_negy.jpg] +set aTex5 [locate_data_file SF_CubeMap_posz.jpg] +set aTex6 [locate_data_file SF_CubeMap_negz.jpg] + +set aShaderVert " +THE_SHADER_OUT vec3 TexCoord; +uniform float uSlice; +void main() { + float aNbSlices = 6.0; + TexCoord = occVertex.xyz; + if (uSlice >= 0.0) { TexCoord = vec3(occTexCoord.xy, uSlice * 1.0 / aNbSlices + 0.5 / aNbSlices); } + if (occTextureTrsf_Scale().y < 0.0) { TexCoord.y = 1.0 - TexCoord.y; } + gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex; +}" + +set aShaderFrag " +#ifdef GL_ES + uniform mediump sampler3D occSampler0; +#else + uniform sampler3D occSampler0; +#endif +THE_SHADER_IN vec3 TexCoord; +void main() { + occFragColor = occTexture3D(occSampler0, TexCoord); +}" + +set aGlslVer "#version 110" +if { [vdriver -default] == "TKOpenGles" } { set aGlslVer "#version 300 es" } + +# draw a box +box b 1.0 1.0 1.0 +vclear +vclose ALL +vinit View1 +vaxo +vdisplay -dispMode 1 b +vfit +vrotate 0.2 0.0 0.0 + +# load 3D texture +vtexture b -3d $aTex1 $aTex2 $aTex3 $aTex4 $aTex5 $aTex6 + +# texture slices +foreach aSliceIter {0 1 2 3 4 5} { + vshaderprog b -vert $aShaderVert -frag $aShaderFrag -defaultSampler 0 -uniform "uSlice" ${aSliceIter} -header "$aGlslVer" + vdump $::imagedir/${::casename}_s${aSliceIter}.png +} + +# texture interpolation +vshaderprog b -vert $aShaderVert -frag $aShaderFrag -defaultSampler 0 -uniform "uSlice" -1 -header "$aGlslVer" +vdump $::imagedir/${::casename}_def.png