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