Commit | Line | Data |
---|---|---|
bf5f0ca2 | 1 | // Copyright (c) 2019 OPEN CASCADE SAS |
b311480e | 2 | // |
973c2be1 | 3 | // This file is part of Open CASCADE Technology software library. |
b311480e | 4 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 10 | // |
973c2be1 | 11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. | |
b311480e | 13 | |
bf5f0ca2 | 14 | #include <OpenGl_AspectsTextureSet.hxx> |
30f0ad28 | 15 | |
30f0ad28 | 16 | #include <OpenGl_Context.hxx> |
cc8cbabe | 17 | #include <OpenGl_Sampler.hxx> |
737e9a8d | 18 | #include <OpenGl_PointSprite.hxx> |
bf5f0ca2 | 19 | #include <OpenGl_TextureSet.hxx> |
2166f0fa | 20 | |
c04c30b3 | 21 | #include <Graphic3d_TextureParams.hxx> |
4269bd1b | 22 | |
c04c30b3 | 23 | #include <Image_PixMap.hxx> |
24 | ||
bf75be98 | 25 | namespace |
2166f0fa | 26 | { |
bf5f0ca2 | 27 | static const TCollection_AsciiString THE_EMPTY_KEY; |
2166f0fa SK |
28 | } |
29 | ||
bf75be98 | 30 | // ======================================================================= |
31 | // function : Release | |
32 | // purpose : | |
33 | // ======================================================================= | |
bf5f0ca2 | 34 | void OpenGl_AspectsTextureSet::Release (OpenGl_Context* theCtx) |
fd4a6963 | 35 | { |
737e9a8d | 36 | if (myTextures[0].IsNull()) |
cc8cbabe | 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()) | |
fd4a6963 | 48 | { |
cc8cbabe | 49 | Handle(OpenGl_Texture)& aTextureRes = aTextureIter.ChangeValue(); |
50 | if (aTextureRes.IsNull()) | |
d2edda76 | 51 | { |
cc8cbabe | 52 | continue; |
53 | } | |
54 | ||
55 | if (theCtx != NULL) | |
56 | { | |
57 | if (aTextureRes->ResourceId().IsEmpty()) | |
d2edda76 | 58 | { |
cc8cbabe | 59 | theCtx->DelayedRelease (aTextureRes); |
d2edda76 | 60 | } |
cc8cbabe | 61 | else |
62 | { | |
737e9a8d | 63 | // OpenGl_PointSprite will be actually released later by OpenGl_AspectsSprite, |
64 | // see order OpenGl_Aspects::Release() | |
cc8cbabe | 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 | // ======================================================================= | |
bf5f0ca2 | 76 | // function : UpdateRediness |
cc8cbabe | 77 | // purpose : |
78 | // ======================================================================= | |
737e9a8d | 79 | void OpenGl_AspectsTextureSet::UpdateRediness (const Handle(Graphic3d_Aspects)& theAspect) |
cc8cbabe | 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 | ||
cc8cbabe | 92 | if (aNbTexturesOld != aNbTexturesNew) |
93 | { | |
94 | myIsTextureReady = Standard_False; | |
95 | return; | |
96 | } | |
737e9a8d | 97 | if (aNbTexturesOld == 0 |
98 | || !theAspect->ToMapTexture()) | |
cc8cbabe | 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()) | |
cc8cbabe | 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; | |
d2edda76 | 117 | } |
118 | ||
cc8cbabe | 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()) | |
30f0ad28 | 126 | { |
cc8cbabe | 127 | myIsTextureReady = Standard_False; |
128 | return; | |
30f0ad28 | 129 | } |
130 | else | |
fd4a6963 | 131 | { |
cc8cbabe | 132 | // just invalidate texture parameters |
133 | aResource->Sampler()->SetParameters (aTexture->GetParams()); | |
72f6dc61 | 134 | aResIter.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit(); |
30f0ad28 | 135 | } |
136 | } | |
cc8cbabe | 137 | } |
30f0ad28 | 138 | |
cc8cbabe | 139 | // ======================================================================= |
bf5f0ca2 | 140 | // function : build |
cc8cbabe | 141 | // purpose : |
142 | // ======================================================================= | |
bf5f0ca2 | 143 | void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx, |
737e9a8d | 144 | const Handle(Graphic3d_Aspects)& theAspect, |
145 | const Handle(OpenGl_PointSprite)& theSprite, | |
146 | const Handle(OpenGl_PointSprite)& theSpriteA) | |
cc8cbabe | 147 | { |
737e9a8d | 148 | const Handle(Graphic3d_TextureSet)& aNewTextureSet = theAspect->TextureSet(); |
149 | ||
150 | const bool hasSprite = theAspect->IsMarkerSprite(); | |
151 | const Standard_Integer aNbTexturesOld = !myTextures[0].IsNull() ? myTextures[0]->Size() : 0; | |
152 | Standard_Integer aNbTexturesNew = !aNewTextureSet.IsNull() && theAspect->ToMapTexture() | |
153 | ? aNewTextureSet->Size() | |
154 | : 0; | |
155 | if (hasSprite) | |
156 | { | |
157 | ++aNbTexturesNew; | |
158 | } | |
159 | ||
cc8cbabe | 160 | // release old texture resources |
cc8cbabe | 161 | if (aNbTexturesOld != aNbTexturesNew) |
162 | { | |
bf5f0ca2 | 163 | Release (theCtx.get()); |
cc8cbabe | 164 | if (aNbTexturesNew > 0) |
165 | { | |
737e9a8d | 166 | myTextures[0] = new OpenGl_TextureSet (aNbTexturesNew); |
cc8cbabe | 167 | } |
168 | else | |
169 | { | |
737e9a8d | 170 | myTextures[0].Nullify(); |
171 | myTextures[1].Nullify(); | |
cc8cbabe | 172 | } |
173 | } | |
737e9a8d | 174 | if (myTextures[0].IsNull()) |
cc8cbabe | 175 | { |
176 | return; | |
177 | } | |
30f0ad28 | 178 | |
737e9a8d | 179 | if (theSprite == theSpriteA) |
180 | { | |
181 | myTextures[1].Nullify(); | |
182 | } | |
183 | else | |
30f0ad28 | 184 | { |
737e9a8d | 185 | if (myTextures[1].IsNull() |
186 | || myTextures[1]->Size() != myTextures[0]->Size()) | |
cc8cbabe | 187 | { |
737e9a8d | 188 | myTextures[1] = new OpenGl_TextureSet (aNbTexturesNew); |
cc8cbabe | 189 | } |
737e9a8d | 190 | else |
191 | { | |
192 | myTextures[1]->InitZero(); | |
193 | } | |
194 | } | |
cc8cbabe | 195 | |
72f6dc61 | 196 | Standard_Integer& aTextureSetBits = myTextures[0]->ChangeTextureSetBits(); |
197 | aTextureSetBits = Graphic3d_TextureSetBits_NONE; | |
d850414a | 198 | Standard_Integer aPrevTextureUnit = -1; |
737e9a8d | 199 | if (theAspect->ToMapTexture()) |
200 | { | |
201 | Graphic3d_TextureSet::Iterator aTextureIter (aNewTextureSet); | |
202 | OpenGl_TextureSet::Iterator aResIter0 (myTextures[0]); | |
203 | for (; aTextureIter.More(); aResIter0.Next(), aTextureIter.Next()) | |
30f0ad28 | 204 | { |
737e9a8d | 205 | Handle(OpenGl_Texture)& aResource = aResIter0.ChangeValue(); |
206 | const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value(); | |
207 | if (!aResource.IsNull()) | |
fd4a6963 | 208 | { |
737e9a8d | 209 | if (!aTexture.IsNull() |
210 | && aTexture->GetId() == aResource->ResourceId() | |
211 | && aTexture->Revision() != aResource->Revision()) | |
cc8cbabe | 212 | { |
077a220c | 213 | if (aResource->Init(theCtx, aTexture)) |
737e9a8d | 214 | { |
72f6dc61 | 215 | aResIter0.ChangeUnit() = aResource->Sampler()->Parameters()->TextureUnit(); |
d850414a | 216 | if (aResIter0.Unit() < aPrevTextureUnit) |
217 | { | |
218 | throw Standard_ProgramError("Graphic3d_TextureMap defines texture units in non-ascending order"); | |
219 | } | |
220 | aPrevTextureUnit = aResIter0.Unit(); | |
077a220c | 221 | aResource->Sampler()->SetParameters(aTexture->GetParams()); |
737e9a8d | 222 | aResource->SetRevision (aTexture->Revision()); |
737e9a8d | 223 | } |
224 | } | |
225 | ||
226 | if (aResource->ResourceId().IsEmpty()) | |
227 | { | |
228 | theCtx->DelayedRelease (aResource); | |
229 | aResource.Nullify(); | |
cc8cbabe | 230 | } |
737e9a8d | 231 | else |
cc8cbabe | 232 | { |
737e9a8d | 233 | const TCollection_AsciiString aTextureKey = aResource->ResourceId(); |
234 | aResource.Nullify(); // we need nullify all handles before ReleaseResource() call | |
235 | theCtx->ReleaseResource (aTextureKey, Standard_True); | |
cc8cbabe | 236 | } |
fd4a6963 | 237 | } |
737e9a8d | 238 | |
239 | if (!aTexture.IsNull()) | |
fd4a6963 | 240 | { |
737e9a8d | 241 | const TCollection_AsciiString& aTextureKeyNew = aTexture->GetId(); |
242 | if (aTextureKeyNew.IsEmpty() | |
243 | || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource)) | |
31fe1f8e | 244 | { |
737e9a8d | 245 | aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams()); |
077a220c | 246 | |
247 | if (aResource->Init(theCtx, aTexture)) | |
31fe1f8e | 248 | { |
31fe1f8e | 249 | aResource->SetRevision (aTexture->Revision()); |
250 | } | |
737e9a8d | 251 | if (!aTextureKeyNew.IsEmpty()) |
252 | { | |
253 | theCtx->ShareResource (aTextureKeyNew, aResource); | |
254 | } | |
255 | } | |
256 | else | |
257 | { | |
258 | if (aTexture->Revision() != aResource->Revision()) | |
259 | { | |
077a220c | 260 | if (aResource->Init(theCtx, aTexture)) |
737e9a8d | 261 | { |
737e9a8d | 262 | aResource->SetRevision (aTexture->Revision()); |
263 | } | |
264 | } | |
265 | aResource->Sampler()->SetParameters (aTexture->GetParams()); | |
31fe1f8e | 266 | } |
72f6dc61 | 267 | |
268 | // update occupation of texture units | |
269 | const Graphic3d_TextureUnit aTexUnit = aResource->Sampler()->Parameters()->TextureUnit(); | |
270 | aResIter0.ChangeUnit() = aTexUnit; | |
d850414a | 271 | if (aResIter0.Unit() < aPrevTextureUnit) |
272 | { | |
273 | throw Standard_ProgramError("Graphic3d_TextureMap defines texture units in non-ascending order"); | |
274 | } | |
275 | aPrevTextureUnit = aResIter0.Unit(); | |
72f6dc61 | 276 | if (aTexUnit >= Graphic3d_TextureUnit_0 && aTexUnit <= Graphic3d_TextureUnit_5) |
277 | { | |
278 | aTextureSetBits |= (1 << int(aTexUnit)); | |
279 | } | |
fd4a6963 | 280 | } |
281 | } | |
30f0ad28 | 282 | } |
737e9a8d | 283 | |
284 | if (hasSprite) | |
285 | { | |
286 | myTextures[0]->ChangeLast() = theSprite; | |
72f6dc61 | 287 | myTextures[0]->ChangeLastUnit() = theCtx->SpriteTextureUnit(); |
288 | // Graphic3d_TextureUnit_PointSprite | |
737e9a8d | 289 | if (!theSprite.IsNull()) |
290 | { | |
291 | theSprite ->Sampler()->Parameters()->SetTextureUnit (theCtx->SpriteTextureUnit()); | |
292 | } | |
293 | if (!theSpriteA.IsNull()) | |
294 | { | |
295 | theSpriteA->Sampler()->Parameters()->SetTextureUnit (theCtx->SpriteTextureUnit()); | |
296 | } | |
297 | } | |
298 | if (myTextures[1].IsNull()) | |
299 | { | |
300 | return; | |
301 | } | |
302 | ||
72f6dc61 | 303 | myTextures[1]->ChangeTextureSetBits() = aTextureSetBits; |
737e9a8d | 304 | for (OpenGl_TextureSet::Iterator aResIter0 (myTextures[0]), aResIter1 (myTextures[1]); aResIter0.More(); aResIter0.Next(), aResIter1.Next()) |
305 | { | |
306 | aResIter1.ChangeValue() = aResIter0.Value(); | |
72f6dc61 | 307 | aResIter1.ChangeUnit() = aResIter0.Unit(); |
737e9a8d | 308 | } |
309 | if (hasSprite) | |
310 | { | |
311 | myTextures[1]->ChangeLast() = theSpriteA; | |
72f6dc61 | 312 | myTextures[1]->ChangeLastUnit() = theCtx->SpriteTextureUnit(); |
737e9a8d | 313 | } |
30f0ad28 | 314 | } |