7c03faf82795afe509a87a34a1083911f6d8d434
[occt.git] / src / OpenGl / OpenGl_AspectsTextureSet.cxx
1 // Copyright (c) 2019 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <OpenGl_AspectsTextureSet.hxx>
15
16 #include <OpenGl_Context.hxx>
17 #include <OpenGl_Sampler.hxx>
18 #include <OpenGl_Texture.hxx>
19 #include <OpenGl_TextureSet.hxx>
20
21 #include <Graphic3d_TextureParams.hxx>
22
23 #include <Image_PixMap.hxx>
24
25 namespace
26 {
27   static const TCollection_AsciiString THE_EMPTY_KEY;
28 }
29
30 // =======================================================================
31 // function : Release
32 // purpose  :
33 // =======================================================================
34 void OpenGl_AspectsTextureSet::Release (OpenGl_Context* theCtx)
35 {
36   if (myTextures.IsNull())
37   {
38     return;
39   }
40
41   for (OpenGl_TextureSet::Iterator aTextureIter (myTextures); aTextureIter.More(); aTextureIter.Next())
42   {
43     Handle(OpenGl_Texture)& aTextureRes = aTextureIter.ChangeValue();
44     if (aTextureRes.IsNull())
45     {
46       continue;
47     }
48
49     if (theCtx != NULL)
50     {
51       if (aTextureRes->ResourceId().IsEmpty())
52       {
53         theCtx->DelayedRelease (aTextureRes);
54       }
55       else
56       {
57         const TCollection_AsciiString aName = aTextureRes->ResourceId();
58         aTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
59         theCtx->ReleaseResource (aName, Standard_True);
60       }
61     }
62     aTextureRes.Nullify();
63   }
64   myIsTextureReady = Standard_False;
65 }
66
67 // =======================================================================
68 // function : UpdateRediness
69 // purpose  :
70 // =======================================================================
71 void OpenGl_AspectsTextureSet::UpdateRediness (const Handle(Graphic3d_TextureSet)& theTextures)
72 {
73   const Standard_Integer aNbTexturesOld = !myTextures.IsNull()  ? myTextures->Size()  : 0;
74   const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
75   if (aNbTexturesOld != aNbTexturesNew)
76   {
77     myIsTextureReady = Standard_False;
78     return;
79   }
80   if (aNbTexturesOld == 0)
81   {
82     return;
83   }
84
85   Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
86   OpenGl_TextureSet::Iterator aResIter (myTextures);
87   for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
88   {
89     const Handle(OpenGl_Texture)&       aResource = aResIter.Value();
90     const Handle(Graphic3d_TextureMap)& aTexture  = aTextureIter.Value();
91     if (aTexture.IsNull() != aResource.IsNull())
92     {
93       myIsTextureReady = Standard_False;
94       return;
95     }
96     else if (aTexture.IsNull())
97     {
98       continue;
99     }
100
101     const TCollection_AsciiString& aTextureKey = aTexture->GetId();
102     if (aTextureKey.IsEmpty() || aResource->ResourceId() != aTextureKey)
103     {
104       myIsTextureReady = Standard_False;
105       return;
106     }
107     else if (aResource->Revision() != aTexture->Revision())
108     {
109       myIsTextureReady = Standard_False;
110       return;
111     }
112     else
113     {
114       // just invalidate texture parameters
115       aResource->Sampler()->SetParameters (aTexture->GetParams());
116     }
117   }
118 }
119
120 // =======================================================================
121 // function : build
122 // purpose  :
123 // =======================================================================
124 void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx,
125                                       const Handle(Graphic3d_TextureSet)& theTextures)
126 {
127   // release old texture resources
128   const Standard_Integer aNbTexturesOld = !myTextures.IsNull()  ? myTextures->Size()  : 0;
129   const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
130   if (aNbTexturesOld != aNbTexturesNew)
131   {
132     Release (theCtx.get());
133     if (aNbTexturesNew > 0)
134     {
135       myTextures = new OpenGl_TextureSet (theTextures->Size());
136     }
137     else
138     {
139       myTextures.Nullify();
140     }
141   }
142   if (myTextures.IsNull())
143   {
144     return;
145   }
146
147   Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
148   OpenGl_TextureSet::Iterator aResIter (myTextures);
149   for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
150   {
151     Handle(OpenGl_Texture)& aResource = aResIter.ChangeValue();
152     const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
153     if (!aResource.IsNull())
154     {
155       if (!aTexture.IsNull()
156        &&  aTexture->GetId()    == aResource->ResourceId()
157        &&  aTexture->Revision() != aResource->Revision())
158       {
159         if (Handle(Image_PixMap) anImage = aTexture->GetImage())
160         {
161           aResource->Sampler()->SetParameters (aTexture->GetParams());
162           aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
163           aResource->SetRevision (aTexture->Revision());
164           continue;
165         }
166       }
167
168       if (aResource->ResourceId().IsEmpty())
169       {
170         theCtx->DelayedRelease (aResource);
171         aResource.Nullify();
172       }
173       else
174       {
175         const TCollection_AsciiString aTextureKey = aResource->ResourceId();
176         aResource.Nullify(); // we need nullify all handles before ReleaseResource() call
177         theCtx->ReleaseResource (aTextureKey, Standard_True);
178       }
179     }
180
181     if (!aTexture.IsNull())
182     {
183       const TCollection_AsciiString& aTextureKeyNew = aTexture->GetId();
184       if (aTextureKeyNew.IsEmpty()
185       || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource))
186       {
187         aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams());
188         if (Handle(Image_PixMap) anImage = aTexture->GetImage())
189         {
190           aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
191           aResource->SetRevision (aTexture->Revision());
192         }
193         if (!aTextureKeyNew.IsEmpty())
194         {
195           theCtx->ShareResource (aTextureKeyNew, aResource);
196         }
197       }
198       else
199       {
200         aResource->Sampler()->SetParameters (aTexture->GetParams());
201       }
202     }
203   }
204 }