0027853: Visualization, OpenGl_Texture - optimize sequential upload of texture image
authorkgv <kgv@opencascade.com>
Thu, 8 Sep 2016 14:16:56 +0000 (17:16 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 15 Sep 2016 08:50:32 +0000 (11:50 +0300)
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
src/Graphic3d/Graphic3d_Texture2D.hxx
src/Graphic3d/Graphic3d_Texture2Dmanual.cxx
src/Graphic3d/Graphic3d_Texture2Dmanual.hxx
src/Graphic3d/Graphic3d_TextureRoot.cxx
src/Graphic3d/Graphic3d_TextureRoot.hxx
src/OpenGl/OpenGl_AspectFace.cxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx

index 8fda9a2..37e7308 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <Graphic3d_Texture2D.hxx>
+
 #include <Standard_OutOfRange.hxx>
-#include <Standard_Type.hxx>
-#include <TCollection_AsciiString.hxx>
 
 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;
+}
index bf8f990..1a64bfc 100644 (file)
 #ifndef _Graphic3d_Texture2D_HeaderFile
 #define _Graphic3d_Texture2D_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
 #include <Graphic3d_NameOfTexture2D.hxx>
 #include <Graphic3d_TextureMap.hxx>
-#include <Graphic3d_TypeOfTexture.hxx>
-#include <Image_PixMap.hxx>
-#include <Standard_Integer.hxx>
-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 <aRank>
   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);
 
+  //! Return true if mip-maps should be used.
+  Standard_Boolean HasMipMaps() const { return myType == Graphic3d_TOT_2D_MIPMAP; }
 
-  DEFINE_STANDARD_RTTIEXT(Graphic3d_Texture2D,Graphic3d_TextureMap)
+  //! 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
index 89c38fd..d15d21b 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <Graphic3d_Texture2Dmanual.hxx>
+
 #include <Graphic3d_TextureParams.hxx>
 #include <Graphic3d_TypeOfTextureMode.hxx>
-#include <Standard_Type.hxx>
-#include <TCollection_AsciiString.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Texture2Dmanual,Graphic3d_Texture2D)
 
index d3a82c1..4389c23 100644 (file)
 #ifndef _Graphic3d_Texture2Dmanual_HeaderFile
 #define _Graphic3d_Texture2Dmanual_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
 #include <Graphic3d_Texture2D.hxx>
 #include <Graphic3d_NameOfTexture2D.hxx>
-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
index 3902b10..6e2dde7 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Graphic3d_TextureRoot.hxx>
 
 #include <Graphic3d_GraphicDriver.hxx>
 #include <Graphic3d_TextureParams.hxx>
-#include <Graphic3d_TextureRoot.hxx>
 #include <Image_AlienPixMap.hxx>
 #include <OSD_Directory.hxx>
 #include <OSD_Environment.hxx>
 #include <OSD_File.hxx>
-#include <OSD_Path.hxx>
 #include <OSD_Protection.hxx>
 #include <Standard_Atomic.hxx>
-#include <Standard_Type.hxx>
-#include <TCollection_AsciiString.hxx>
 
-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;
-}
index c4e63e7..b5784c8 100644 (file)
 #ifndef _Graphic3d_TextureRoot_HeaderFile
 #define _Graphic3d_TextureRoot_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <TCollection_AsciiString.hxx>
 #include <Image_PixMap.hxx>
 #include <OSD_Path.hxx>
 #include <Graphic3d_TypeOfTexture.hxx>
-#include <MMgt_TShared.hxx>
-#include <Standard_Boolean.hxx>
-class Graphic3d_TextureParams;
-class TCollection_AsciiString;
-class OSD_Path;
-
+#include <Standard.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
 
-class Graphic3d_TextureRoot;
-DEFINE_STANDARD_HANDLE(Graphic3d_TextureRoot, MMgt_TShared)
+class Graphic3d_TextureParams;
 
 //! 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 <FileName> 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;
-
-
-private:
+  //! Unconditionally generate new texture id.
+  Standard_EXPORT void generateId();
 
+protected:
 
-  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
index 2200dfc..9839412 100644 (file)
@@ -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())
       {
index a35e653..f0ec3e4 100644 (file)
@@ -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;
 }
 
 // =======================================================================
index c7242b0..e8e9b84 100644 (file)
@@ -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