0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / OpenGl / OpenGl_AspectsTextureSet.cxx
CommitLineData
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 25namespace
2166f0fa 26{
bf5f0ca2 27 static const TCollection_AsciiString THE_EMPTY_KEY;
2166f0fa
SK
28}
29
bf75be98 30// =======================================================================
31// function : Release
32// purpose :
33// =======================================================================
bf5f0ca2 34void 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 79void 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 143void 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}