From d2edda76a976f2767a2993797dd9fc6de4759663 Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 8 Sep 2016 17:16:56 +0300 Subject: [PATCH] 0027853: Visualization, OpenGl_Texture - optimize sequential upload of texture image Graphic3d_TextureRoot - added methods Revision() and UpdateRevision() for marking updates in texture data source. OpenGl_AspectFace handles Graphic3d_TextureRoot::Revision() changes. OpenGl_Texture::Init() now patches already allocated texture image when possible. Graphic3d_Texture2D - added methods HasMipMaps()/SetMipMaps() for configuring MipMap usage (as alternative to sub-classing). --- src/Graphic3d/Graphic3d_Texture2D.cxx | 15 ++- src/Graphic3d/Graphic3d_Texture2D.hxx | 49 +++----- src/Graphic3d/Graphic3d_Texture2Dmanual.cxx | 4 +- src/Graphic3d/Graphic3d_Texture2Dmanual.hxx | 39 ++----- src/Graphic3d/Graphic3d_TextureRoot.cxx | 65 +++-------- src/Graphic3d/Graphic3d_TextureRoot.hxx | 89 +++++++-------- src/OpenGl/OpenGl_AspectFace.cxx | 20 ++++ src/OpenGl/OpenGl_Texture.cxx | 119 ++++++++++++++------ src/OpenGl/OpenGl_Texture.hxx | 7 ++ 9 files changed, 202 insertions(+), 205 deletions(-) diff --git a/src/Graphic3d/Graphic3d_Texture2D.cxx b/src/Graphic3d/Graphic3d_Texture2D.cxx index 8fda9a28e5..37e7308682 100644 --- a/src/Graphic3d/Graphic3d_Texture2D.cxx +++ b/src/Graphic3d/Graphic3d_Texture2D.cxx @@ -14,11 +14,9 @@ // 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_Texture2D,Graphic3d_TextureMap) @@ -116,3 +114,14 @@ TCollection_AsciiString Graphic3d_Texture2D::TextureName (const Standard_Integer Standard_Integer i = aFileName.SearchFromEnd ("."); return aFileName.SubString (4, i - 1); } + +// ======================================================================= +// function : SetImage +// purpose : +// ======================================================================= +void Graphic3d_Texture2D::SetImage (const Handle(Image_PixMap)& thePixMap) +{ + myPixMap = thePixMap; + myPath = OSD_Path(); + myName = Graphic3d_NOT_2D_UNKNOWN; +} diff --git a/src/Graphic3d/Graphic3d_Texture2D.hxx b/src/Graphic3d/Graphic3d_Texture2D.hxx index bf8f990de6..1a64bfcaed 100644 --- a/src/Graphic3d/Graphic3d_Texture2D.hxx +++ b/src/Graphic3d/Graphic3d_Texture2D.hxx @@ -17,48 +17,39 @@ #ifndef _Graphic3d_Texture2D_HeaderFile #define _Graphic3d_Texture2D_HeaderFile -#include -#include - #include #include -#include -#include -#include -class Standard_OutOfRange; -class TCollection_AsciiString; - - -class Graphic3d_Texture2D; -DEFINE_STANDARD_HANDLE(Graphic3d_Texture2D, Graphic3d_TextureMap) //! This abstract class for managing 2D textures class Graphic3d_Texture2D : public Graphic3d_TextureMap { - + DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture2D, Graphic3d_TextureMap) public: - - - //! 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; - - //! Returns the number of predefined textures. Standard_EXPORT static Standard_Integer NumberOfTextures(); - //! Returns the name of the predefined texture of rank Standard_EXPORT static TCollection_AsciiString TextureName (const Standard_Integer theRank); +public: + //! 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; + //! 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); - DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture2D,Graphic3d_TextureMap) + //! 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); @@ -66,20 +57,12 @@ protected: Standard_EXPORT Graphic3d_Texture2D(const Handle(Image_PixMap)& thePixMap, const Graphic3d_TypeOfTexture theType); - - -private: - +protected: Graphic3d_NameOfTexture2D myName; - }; - - - - - +DEFINE_STANDARD_HANDLE(Graphic3d_Texture2D, Graphic3d_TextureMap) #endif // _Graphic3d_Texture2D_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx b/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx index 89c38fd0b4..d15d21bbd5 100644 --- a/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx +++ b/src/Graphic3d/Graphic3d_Texture2Dmanual.cxx @@ -14,12 +14,10 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include + #include #include -#include -#include IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture2Dmanual,Graphic3d_Texture2D) diff --git a/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx b/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx index d3a82c1610..4389c23dec 100644 --- a/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx +++ b/src/Graphic3d/Graphic3d_Texture2Dmanual.hxx @@ -17,56 +17,31 @@ #ifndef _Graphic3d_Texture2Dmanual_HeaderFile #define _Graphic3d_Texture2Dmanual_HeaderFile -#include -#include - #include #include -class TCollection_AsciiString; - - -class Graphic3d_Texture2Dmanual; -DEFINE_STANDARD_HANDLE(Graphic3d_Texture2Dmanual, Graphic3d_Texture2D) //! 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 + //! 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_RTTIEXT(Graphic3d_Texture2Dmanual,Graphic3d_Texture2D) - -protected: - - - - -private: - - - - }; - - - - - +DEFINE_STANDARD_HANDLE(Graphic3d_Texture2Dmanual, Graphic3d_Texture2D) #endif // _Graphic3d_Texture2Dmanual_HeaderFile diff --git a/src/Graphic3d/Graphic3d_TextureRoot.cxx b/src/Graphic3d/Graphic3d_TextureRoot.cxx index 3902b10e53..6e2dde758c 100644 --- a/src/Graphic3d/Graphic3d_TextureRoot.cxx +++ b/src/Graphic3d/Graphic3d_TextureRoot.cxx @@ -14,21 +14,18 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include -#include #include #include #include #include -#include #include #include -#include -#include -IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TextureRoot,MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TextureRoot, Standard_Transient) namespace { @@ -91,12 +88,12 @@ TCollection_AsciiString Graphic3d_TextureRoot::TexturesFolder() // ======================================================================= Graphic3d_TextureRoot::Graphic3d_TextureRoot (const TCollection_AsciiString& theFileName, const Graphic3d_TypeOfTexture theType) -: myParams (new Graphic3d_TextureParams()), - myPath (theFileName), - myType (theType) +: myParams (new Graphic3d_TextureParams()), + myPath (theFileName), + myRevision (0), + myType (theType) { - myTexId = TCollection_AsciiString ("Graphic3d_TextureRoot_") //DynamicType()->Name() - + TCollection_AsciiString (Standard_Atomic_Increment (&THE_TEXTURE_COUNTER)); + generateId(); } // ======================================================================= @@ -105,39 +102,31 @@ Graphic3d_TextureRoot::Graphic3d_TextureRoot (const TCollection_AsciiString& the // ======================================================================= Graphic3d_TextureRoot::Graphic3d_TextureRoot (const Handle(Image_PixMap)& thePixMap, const Graphic3d_TypeOfTexture theType) -: myParams (new Graphic3d_TextureParams()), - myPixMap (thePixMap), - myType (theType) +: myParams (new Graphic3d_TextureParams()), + myPixMap (thePixMap), + myRevision (0), + myType (theType) { - myTexId = TCollection_AsciiString ("Graphic3d_TextureRoot_") - + TCollection_AsciiString (Standard_Atomic_Increment (&THE_TEXTURE_COUNTER)); + generateId(); } // ======================================================================= -// function : Destroy +// function : ~Graphic3d_TextureRoot // purpose : // ======================================================================= -void Graphic3d_TextureRoot::Destroy() const +Graphic3d_TextureRoot::~Graphic3d_TextureRoot() { // } // ======================================================================= -// function : GetId +// function : generateId // purpose : // ======================================================================= -const TCollection_AsciiString& Graphic3d_TextureRoot::GetId() const +void Graphic3d_TextureRoot::generateId() { - return myTexId; -} - -// ======================================================================= -// function : GetParams -// purpose : -// ======================================================================= -const Handle(Graphic3d_TextureParams)& Graphic3d_TextureRoot::GetParams() const -{ - return myParams; + myTexId = TCollection_AsciiString ("Graphic3d_TextureRoot_") + + TCollection_AsciiString (Standard_Atomic_Increment (&THE_TEXTURE_COUNTER)); } // ======================================================================= @@ -185,21 +174,3 @@ Standard_Boolean Graphic3d_TextureRoot::IsDone() const OSD_File aTextureFile (myPath); return aTextureFile.Exists(); } - -// ======================================================================= -// function : Path -// purpose : -// ======================================================================= -const OSD_Path& Graphic3d_TextureRoot::Path() const -{ - return myPath; -} - -// ======================================================================= -// function : Type -// purpose : -// ======================================================================= -Graphic3d_TypeOfTexture Graphic3d_TextureRoot::Type() const -{ - return myType; -} diff --git a/src/Graphic3d/Graphic3d_TextureRoot.hxx b/src/Graphic3d/Graphic3d_TextureRoot.hxx index c4e63e756a..b5784c8b75 100644 --- a/src/Graphic3d/Graphic3d_TextureRoot.hxx +++ b/src/Graphic3d/Graphic3d_TextureRoot.hxx @@ -17,48 +17,41 @@ #ifndef _Graphic3d_TextureRoot_HeaderFile #define _Graphic3d_TextureRoot_HeaderFile -#include -#include - -#include #include #include #include -#include -#include +#include +#include +#include +#include + class Graphic3d_TextureParams; -class TCollection_AsciiString; -class OSD_Path; - - -class Graphic3d_TextureRoot; -DEFINE_STANDARD_HANDLE(Graphic3d_TextureRoot, MMgt_TShared) //! This is the texture root class enable the dialog with the GraphicDriver allows the loading of texture. -class Graphic3d_TextureRoot : public MMgt_TShared +class Graphic3d_TextureRoot : public Standard_Transient { + DEFINE_STANDARD_RTTIEXT(Graphic3d_TextureRoot, Standard_Transient) +public: + + //! The path to textures determined from CSF_MDTVTexturesDirectory or CASROOT environment variables. + //! @return the root folder with default textures. + Standard_EXPORT static TCollection_AsciiString TexturesFolder(); public: - - Standard_EXPORT void Destroy() const; -~Graphic3d_TextureRoot() -{ - Destroy(); -} - + //! Destructor. + Standard_EXPORT ~Graphic3d_TextureRoot(); + //! Checks if a texture class is valid or not. //! @return true if the construction of the class is correct Standard_EXPORT virtual Standard_Boolean IsDone() const; - //! Returns the full path of the defined texture. //! It could be empty path if GetImage() is overridden to load image not from file. - Standard_EXPORT const OSD_Path& Path() const; - + const OSD_Path& Path() const { return myPath; } + //! @return the texture type. - Standard_EXPORT Graphic3d_TypeOfTexture Type() const; - + Graphic3d_TypeOfTexture Type() const { return myType; } //! This ID will be used to manage resource in graphic driver. //! @@ -74,7 +67,15 @@ public: //! for each instance of Graphic3d_AspectFillArea3d where texture will be used. //! //! @return texture identifier. - Standard_EXPORT const TCollection_AsciiString& GetId() const; + const TCollection_AsciiString& GetId() const { return myTexId; } + + //! Return image revision. + Standard_Size Revision() const { return myRevision; } + + //! Update image revision. + //! Can be used for signalling changes in the texture source (e.g. file update, pixmap update) + //! without re-creating texture source itself (e.g. preserving the unique id). + void UpdateRevision() { ++myRevision; } //! This method will be called by graphic driver each time when texture resource should be created. //! Default constructors allow defining the texture source as path to texture image or directly as pixmap. @@ -86,20 +87,10 @@ public: Standard_EXPORT virtual Handle(Image_PixMap) GetImage() const; //! @return low-level texture parameters - Standard_EXPORT const Handle(Graphic3d_TextureParams)& GetParams() const; - - - //! The path to textures determined from CSF_MDTVTexturesDirectory or CASROOT environment variables. - //! @return the root folder with default textures. - Standard_EXPORT static TCollection_AsciiString TexturesFolder(); - - - - DEFINE_STANDARD_RTTIEXT(Graphic3d_TextureRoot,MMgt_TShared) + const Handle(Graphic3d_TextureParams)& GetParams() const { return myParams; } protected: - //! Creates a texture from a file //! Warning: Note that if is NULL the texture must be realized //! using LoadTexture(image) method. @@ -110,24 +101,20 @@ protected: //! to be in Bottom-Up order (see Image_PixMap::IsTopDown()). Standard_EXPORT Graphic3d_TextureRoot(const Handle(Image_PixMap)& thePixmap, const Graphic3d_TypeOfTexture theType); - Handle(Graphic3d_TextureParams) myParams; - TCollection_AsciiString myTexId; - Handle(Image_PixMap) myPixMap; - OSD_Path myPath; + //! Unconditionally generate new texture id. + Standard_EXPORT void generateId(); +protected: -private: - - - Graphic3d_TypeOfTexture myType; - + Handle(Graphic3d_TextureParams) myParams; //!< associated texture parameters + TCollection_AsciiString myTexId; //!< unique identifier of this resource (for sharing) + Handle(Image_PixMap) myPixMap; //!< image pixmap - as one of the ways for defining the texture source + OSD_Path myPath; //!< image file path - as one of the ways for defining the texture source + Standard_Size myRevision; //!< image revision - for signalling changes in the texture source (e.g. file update, pixmap update) + Graphic3d_TypeOfTexture myType; //!< texture type }; - - - - - +DEFINE_STANDARD_HANDLE(Graphic3d_TextureRoot, Standard_Transient) #endif // _Graphic3d_TextureRoot_HeaderFile diff --git a/src/OpenGl/OpenGl_AspectFace.cxx b/src/OpenGl/OpenGl_AspectFace.cxx index 2200dfc18d..983941297a 100644 --- a/src/OpenGl/OpenGl_AspectFace.cxx +++ b/src/OpenGl/OpenGl_AspectFace.cxx @@ -102,6 +102,12 @@ void OpenGl_AspectFace::SetAspect (const Handle(Graphic3d_AspectFillArea3d)& the { myResources.ResetTextureReadiness(); } + else if (!myResources.Texture.IsNull() + && !myAspect->TextureMap().IsNull() + && myResources.Texture->Revision() != myAspect->TextureMap()->Revision()) + { + myResources.ResetTextureReadiness(); + } // update shader program binding const TCollection_AsciiString& aShaderKey = myAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : myAspect->ShaderProgram()->GetId(); @@ -165,6 +171,19 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Context)& // release old texture resource if (!Texture.IsNull()) { + if (!theTexture.IsNull() + && theTexture->GetId() == TextureId + && theTexture->Revision() != Texture->Revision()) + { + Handle(Image_PixMap) anImage = theTexture->GetImage(); + if (!anImage.IsNull()) + { + Texture->Init (theCtx, *anImage.operator->(), theTexture->Type()); + Texture->SetRevision (Texture->Revision()); + return; + } + } + if (TextureId.IsEmpty()) { theCtx->DelayedRelease (Texture); @@ -188,6 +207,7 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Context)& if (!anImage.IsNull()) { Texture->Init (theCtx, *anImage.operator->(), theTexture->Type()); + Texture->SetRevision (Texture->Revision()); } if (!TextureId.IsEmpty()) { diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index a35e65384f..f0ec3e4969 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -51,6 +51,7 @@ struct OpenGl_UnpackAlignmentSentry // ======================================================================= OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams) : OpenGl_Resource(), + myRevision (0), myTextureId (NO_TEXTURE), myTarget (GL_TEXTURE_2D), mySizeX (0), @@ -136,7 +137,7 @@ void OpenGl_Texture::Release (OpenGl_Context* theGlCtx) glDeleteTextures (1, &myTextureId); } myTextureId = NO_TEXTURE; - mySizeX = mySizeY = 0; + mySizeX = mySizeY = mySizeZ = 0; } // ======================================================================= @@ -357,6 +358,20 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, const Graphic3d_TypeOfTexture theType, const Image_PixMap* theImage) { +#if !defined(GL_ES_VERSION_2_0) + const GLenum aTarget = theType == Graphic3d_TOT_1D + ? GL_TEXTURE_1D + : GL_TEXTURE_2D; +#else + const GLenum aTarget = GL_TEXTURE_2D; +#endif + const Standard_Boolean toCreateMipMaps = (theType == Graphic3d_TOT_2D_MIPMAP); + const bool toPatchExisting = IsValid() + && myTextFormat == thePixelFormat + && myTarget == aTarget + && myHasMipmaps == toCreateMipMaps + && mySizeX == theSizeX + && (mySizeY == theSizeY || theType == Graphic3d_TOT_1D); if (!Create (theCtx)) { Release (theCtx.operator->()); @@ -373,7 +388,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, myIsAlpha = thePixelFormat == GL_ALPHA; } - myHasMipmaps = Standard_False; + myHasMipmaps = toCreateMipMaps; myTextFormat = thePixelFormat; #if !defined(GL_ES_VERSION_2_0) const GLint anIntFormat = theTextFormat; @@ -382,14 +397,13 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, const GLint anIntFormat = thePixelFormat; (void) theTextFormat; #endif - const GLsizei aWidth = theSizeX; - const GLsizei aHeight = theSizeY; - const GLsizei aMaxSize = theCtx->MaxTextureSize(); - if (aWidth > aMaxSize || aHeight > aMaxSize) + const GLsizei aMaxSize = theCtx->MaxTextureSize(); + if (theSizeX > aMaxSize + || theSizeY > aMaxSize) { TCollection_ExtendedString aWarnMessage = TCollection_ExtendedString ("Error: Texture dimension - ") - + aWidth + "x" + aHeight + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")"; + + theSizeX + "x" + theSizeY + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")"; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage); Release (theCtx.operator->()); @@ -402,13 +416,14 @@ 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 (aWidth, aMaxSize); - const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize); + const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize); + const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize); - if (aWidth != aWidthP2 || (theType != Graphic3d_TOT_1D && aHeight != aHeightP2)) + if (theSizeX != aWidthP2 + || (theType != Graphic3d_TOT_1D && theSizeY != aHeightP2)) { TCollection_ExtendedString aWarnMessage = - TCollection_ExtendedString ("Error: NPOT Textures (") + aWidth + "x" + aHeight + ") are not supported by hardware."; + TCollection_ExtendedString ("Error: NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by hardware."; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage); @@ -420,13 +435,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, else if (!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 (aWidth, aMaxSize); - const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize); + const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize); + const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize); - if (aWidth != aWidthP2 || aHeight != aHeightP2) + if (theSizeX != aWidthP2 + || theSizeY != aHeightP2) { TCollection_ExtendedString aWarnMessage = - TCollection_ExtendedString ("Error: Mipmap NPOT Textures (") + aWidth + "x" + aHeight + ") are not supported by OpenGL ES 2.0"; + TCollection_ExtendedString ("Error: Mipmap NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by OpenGL ES 2.0"; theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage); @@ -462,20 +478,27 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, #endif } + myTarget = aTarget; switch (theType) { case Graphic3d_TOT_1D: { #if !defined(GL_ES_VERSION_2_0) - myTarget = GL_TEXTURE_1D; Bind (theCtx); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter); glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode); + if (toPatchExisting) + { + glTexSubImage1D (GL_TEXTURE_1D, 0, 0, + theSizeX, thePixelFormat, theDataType, aDataPtr); + Unbind (theCtx); + return true; + } // use proxy to check texture could be created or not glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat, - aWidth, 0, + theSizeX, 0, thePixelFormat, theDataType, NULL); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth); if (aTestWidth == 0) @@ -487,7 +510,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, } glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat, - aWidth, 0, + theSizeX, 0, thePixelFormat, theDataType, aDataPtr); if (glGetError() != GL_NO_ERROR) { @@ -496,7 +519,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = aWidth; + mySizeX = theSizeX; mySizeY = 1; Unbind (theCtx); @@ -508,17 +531,25 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, } case Graphic3d_TOT_2D: { - myTarget = GL_TEXTURE_2D; Bind (theCtx); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode); + if (toPatchExisting) + { + glTexSubImage2D (GL_TEXTURE_2D, 0, + 0, 0, + theSizeX, theSizeY, + thePixelFormat, theDataType, aDataPtr); + Unbind (theCtx); + return true; + } #if !defined(GL_ES_VERSION_2_0) // use proxy to check texture could be created or not glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat, - aWidth, aHeight, 0, + theSizeX, theSizeY, 0, thePixelFormat, theDataType, NULL); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight); @@ -532,7 +563,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, #endif glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat, - aWidth, aHeight, 0, + theSizeX, theSizeY, 0, thePixelFormat, theDataType, aDataPtr); if (glGetError() != GL_NO_ERROR) { @@ -541,17 +572,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = aWidth; - mySizeY = aHeight; + mySizeX = theSizeX; + mySizeY = theSizeY; Unbind (theCtx); return true; } case Graphic3d_TOT_2D_MIPMAP: { - myTarget = GL_TEXTURE_2D; - myHasMipmaps = Standard_True; - GLenum aFilterMin = aFilter; aFilterMin = GL_NEAREST_MIPMAP_NEAREST; if (myParams->Filter() == Graphic3d_TOTF_BILINEAR) @@ -568,11 +596,32 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode); + if (toPatchExisting) + { + glTexSubImage2D (GL_TEXTURE_2D, 0, + 0, 0, + theSizeX, theSizeY, + thePixelFormat, theDataType, aDataPtr); + if (theCtx->arbFBO != NULL) + { + // generate mipmaps + theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D); + if (glGetError() != GL_NO_ERROR) + { + Unbind (theCtx); + Release (theCtx.operator->()); + return false; + } + } + + Unbind (theCtx); + return true; + } #if !defined(GL_ES_VERSION_2_0) // use proxy to check texture could be created or not glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat, - aWidth, aHeight, 0, + theSizeX, theSizeY, 0, thePixelFormat, theDataType, NULL); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight); @@ -587,7 +636,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, // upload main picture glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat, - aWidth, aHeight, 0, + theSizeX, theSizeY, 0, thePixelFormat, theDataType, theImage->Data()); if (glGetError() != GL_NO_ERROR) { @@ -596,8 +645,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, return false; } - mySizeX = aWidth; - mySizeY = aHeight; + mySizeX = theSizeX; + mySizeY = theSizeY; if (theCtx->arbFBO != NULL) { @@ -626,12 +675,10 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, Unbind (theCtx); return true; } - default: - { - Release (theCtx.operator->()); - return false; - } } + + Release (theCtx.operator->()); + return false; } // ======================================================================= diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index c7242b0628..e8e9b84536 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -363,6 +363,12 @@ public: Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx, const GLenum theTextureUnit = GL_TEXTURE0) const; + //! Revision of associated data source. + Standard_Size Revision() const { return myRevision; } + + //! Set revision of associated data source. + void SetRevision (const Standard_Size theRevision) { myRevision = theRevision; } + //! Notice that texture will be unbound after this call. Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx, const Image_PixMap& theImage, @@ -422,6 +428,7 @@ public: protected: + Standard_Size myRevision; //!< revision of associated data source GLuint myTextureId; //!< GL resource ID GLenum myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D GLsizei mySizeX; //!< texture width