0032969: Coding - get rid of unused headers [IMeshData to PLib]
[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_PointSprite.hxx>
18 #include <OpenGl_TextureSet.hxx>
19
20 #include <Graphic3d_TextureParams.hxx>
21
22 namespace
23 {
24   static const TCollection_AsciiString THE_EMPTY_KEY;
25 }
26
27 // =======================================================================
28 // function : Release
29 // purpose  :
30 // =======================================================================
31 void OpenGl_AspectsTextureSet::Release (OpenGl_Context* theCtx)
32 {
33   if (myTextures[0].IsNull())
34   {
35     return;
36   }
37
38   if (!myTextures[1].IsNull())
39   {
40     // ReleaseResource() will have no effect until nullifying all copies
41     myTextures[1]->InitZero();
42   }
43
44   for (OpenGl_TextureSet::Iterator aTextureIter (myTextures[0]); aTextureIter.More(); aTextureIter.Next())
45   {
46     Handle(OpenGl_Texture)& aTextureRes = aTextureIter.ChangeValue();
47     if (aTextureRes.IsNull())
48     {
49       continue;
50     }
51
52     if (theCtx != NULL)
53     {
54       if (aTextureRes->ResourceId().IsEmpty())
55       {
56         theCtx->DelayedRelease (aTextureRes);
57       }
58       else
59       {
60         // OpenGl_PointSprite will be actually released later by OpenGl_AspectsSprite,
61         // see order OpenGl_Aspects::Release()
62         const TCollection_AsciiString aName = aTextureRes->ResourceId();
63         aTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
64         theCtx->ReleaseResource (aName, Standard_True);
65       }
66     }
67     aTextureRes.Nullify();
68   }
69   myIsTextureReady = Standard_False;
70 }
71
72 // =======================================================================
73 // function : UpdateRediness
74 // purpose  :
75 // =======================================================================
76 void OpenGl_AspectsTextureSet::UpdateRediness (const Handle(Graphic3d_Aspects)& theAspect)
77 {
78   const Handle(Graphic3d_TextureSet)& aNewTextureSet = theAspect->TextureSet();
79
80   const Standard_Integer aNbTexturesOld = !myTextures[0].IsNull() ? myTextures[0]->Size() : 0;
81   Standard_Integer aNbTexturesNew = !aNewTextureSet.IsNull() && theAspect->ToMapTexture()
82                                    ? aNewTextureSet->Size()
83                                    : 0;
84   if (theAspect->IsMarkerSprite())
85   {
86     ++aNbTexturesNew;
87   }
88
89   if (aNbTexturesOld != aNbTexturesNew)
90   {
91     myIsTextureReady = Standard_False;
92     return;
93   }
94   if (aNbTexturesOld == 0
95   || !theAspect->ToMapTexture())
96   {
97     return;
98   }
99
100   Graphic3d_TextureSet::Iterator aTextureIter (aNewTextureSet);
101   OpenGl_TextureSet::Iterator aResIter (myTextures[0]);
102   for (; aTextureIter.More(); aResIter.Next(), aTextureIter.Next())
103   {
104     const Handle(OpenGl_Texture)&       aResource = aResIter.Value();
105     const Handle(Graphic3d_TextureMap)& aTexture  = aTextureIter.Value();
106     if (aTexture.IsNull() != aResource.IsNull())
107     {
108       myIsTextureReady = Standard_False;
109       return;
110     }
111     else if (aTexture.IsNull())
112     {
113       continue;
114     }
115
116     const TCollection_AsciiString& aTextureKey = aTexture->GetId();
117     if (aTextureKey.IsEmpty() || aResource->ResourceId() != aTextureKey)
118     {
119       myIsTextureReady = Standard_False;
120       return;
121     }
122     else if (aResource->Revision() != aTexture->Revision())
123     {
124       myIsTextureReady = Standard_False;
125       return;
126     }
127     else
128     {
129       // just invalidate texture parameters
130       aResource->Sampler()->SetParameters (aTexture->GetParams());
131       aResIter.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit();
132     }
133   }
134 }
135
136 // =======================================================================
137 // function : build
138 // purpose  :
139 // =======================================================================
140 void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx,
141                                       const Handle(Graphic3d_Aspects)& theAspect,
142                                       const Handle(OpenGl_PointSprite)& theSprite,
143                                       const Handle(OpenGl_PointSprite)& theSpriteA)
144 {
145   const Handle(Graphic3d_TextureSet)& aNewTextureSet = theAspect->TextureSet();
146
147   const bool hasSprite = theAspect->IsMarkerSprite();
148   const Standard_Integer aNbTexturesOld = !myTextures[0].IsNull() ? myTextures[0]->Size() : 0;
149   Standard_Integer aNbTexturesNew = !aNewTextureSet.IsNull() && theAspect->ToMapTexture()
150                                   ? aNewTextureSet->Size()
151                                   : 0;
152   if (hasSprite)
153   {
154     ++aNbTexturesNew;
155   }
156
157   // release old texture resources
158   if (aNbTexturesOld != aNbTexturesNew)
159   {
160     Release (theCtx.get());
161     if (aNbTexturesNew > 0)
162     {
163       myTextures[0] = new OpenGl_TextureSet (aNbTexturesNew);
164     }
165     else
166     {
167       myTextures[0].Nullify();
168       myTextures[1].Nullify();
169     }
170   }
171   if (myTextures[0].IsNull())
172   {
173     return;
174   }
175
176   if (theSprite == theSpriteA)
177   {
178     myTextures[1].Nullify();
179   }
180   else
181   {
182     if (myTextures[1].IsNull()
183      || myTextures[1]->Size() != myTextures[0]->Size())
184     {
185       myTextures[1] = new OpenGl_TextureSet (aNbTexturesNew);
186     }
187     else
188     {
189       myTextures[1]->InitZero();
190     }
191   }
192
193   Standard_Integer& aTextureSetBits = myTextures[0]->ChangeTextureSetBits();
194   aTextureSetBits = Graphic3d_TextureSetBits_NONE;
195   Standard_Integer aPrevTextureUnit = -1;
196   if (theAspect->ToMapTexture())
197   {
198     Graphic3d_TextureSet::Iterator aTextureIter (aNewTextureSet);
199     OpenGl_TextureSet::Iterator aResIter0 (myTextures[0]);
200     for (; aTextureIter.More(); aResIter0.Next(), aTextureIter.Next())
201     {
202       Handle(OpenGl_Texture)& aResource = aResIter0.ChangeValue();
203       const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
204       if (!aResource.IsNull())
205       {
206         if (!aTexture.IsNull()
207          &&  aTexture->GetId()    == aResource->ResourceId()
208          &&  aTexture->Revision() != aResource->Revision())
209         {
210           if (aResource->Init(theCtx, aTexture))
211           {
212             aResIter0.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit();
213             if (aResIter0.Unit() < aPrevTextureUnit)
214             {
215               throw Standard_ProgramError("Graphic3d_TextureMap defines texture units in non-ascending order");
216             }
217             aPrevTextureUnit = aResIter0.Unit();
218             aResource->Sampler()->SetParameters(aTexture->GetParams());
219             aResource->SetRevision (aTexture->Revision());
220           }
221         }
222
223         if (aResource->ResourceId().IsEmpty())
224         {
225           theCtx->DelayedRelease (aResource);
226           aResource.Nullify();
227         }
228         else
229         {
230           const TCollection_AsciiString aTextureKey = aResource->ResourceId();
231           aResource.Nullify(); // we need nullify all handles before ReleaseResource() call
232           theCtx->ReleaseResource (aTextureKey, Standard_True);
233         }
234       }
235
236       if (!aTexture.IsNull())
237       {
238         const TCollection_AsciiString& aTextureKeyNew = aTexture->GetId();
239         if (aTextureKeyNew.IsEmpty()
240         || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource))
241         {
242           aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams());
243
244           if (aResource->Init(theCtx, aTexture))
245           {
246             aResource->SetRevision (aTexture->Revision());
247           }
248           if (!aTextureKeyNew.IsEmpty())
249           {
250             theCtx->ShareResource (aTextureKeyNew, aResource);
251           }
252         }
253         else
254         {
255           if (aTexture->Revision() != aResource->Revision())
256           {
257             if (aResource->Init(theCtx, aTexture))
258             {
259               aResource->SetRevision (aTexture->Revision());
260             }
261           }
262           aResource->Sampler()->SetParameters (aTexture->GetParams());
263         }
264
265         // update occupation of texture units
266         const Graphic3d_TextureUnit aTexUnit = aResource->Sampler()->Parameters()->TextureUnit();
267         aResIter0.ChangeUnit() = aTexUnit;
268         if (aResIter0.Unit() < aPrevTextureUnit)
269         {
270           throw Standard_ProgramError("Graphic3d_TextureMap defines texture units in non-ascending order");
271         }
272         aPrevTextureUnit = aResIter0.Unit();
273         if (aTexUnit >= Graphic3d_TextureUnit_0 && aTexUnit <= Graphic3d_TextureUnit_5)
274         {
275           aTextureSetBits |= (1 << int(aTexUnit));
276         }
277       }
278     }
279   }
280
281   if (hasSprite)
282   {
283     myTextures[0]->ChangeLast() = theSprite;
284     myTextures[0]->ChangeLastUnit() = theCtx->SpriteTextureUnit();
285     // Graphic3d_TextureUnit_PointSprite
286     if (!theSprite.IsNull())
287     {
288       theSprite ->Sampler()->Parameters()->SetTextureUnit (theCtx->SpriteTextureUnit());
289     }
290     if (!theSpriteA.IsNull())
291     {
292       theSpriteA->Sampler()->Parameters()->SetTextureUnit (theCtx->SpriteTextureUnit());
293     }
294   }
295   if (myTextures[1].IsNull())
296   {
297     return;
298   }
299
300   myTextures[1]->ChangeTextureSetBits() = aTextureSetBits;
301   for (OpenGl_TextureSet::Iterator aResIter0 (myTextures[0]), aResIter1 (myTextures[1]); aResIter0.More(); aResIter0.Next(), aResIter1.Next())
302   {
303     aResIter1.ChangeValue() = aResIter0.Value();
304     aResIter1.ChangeUnit()  = aResIter0.Unit();
305   }
306   if (hasSprite)
307   {
308     myTextures[1]->ChangeLast() = theSpriteA;
309     myTextures[1]->ChangeLastUnit() = theCtx->SpriteTextureUnit();
310   }
311 }