6aca4d39 |
1 | // Created on: 2012-02-02 |
b311480e |
2 | // Created by: Anton POLETAEV |
6aca4d39 |
3 | // Copyright (c) 2012-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
59f45b7c |
15 | |
a1073ae2 |
16 | #include <OpenGl_GlCore15.hxx> |
5f8b738e |
17 | |
f5b72419 |
18 | #include <BVH_LinearBuilder.hxx> |
a1073ae2 |
19 | #include <OpenGl_FrameBuffer.hxx> |
59f45b7c |
20 | #include <OpenGl_LayerList.hxx> |
a1073ae2 |
21 | #include <OpenGl_ShaderManager.hxx> |
59f45b7c |
22 | #include <OpenGl_Structure.hxx> |
a1073ae2 |
23 | #include <OpenGl_VertexBuffer.hxx> |
24 | #include <OpenGl_View.hxx> |
550f3b8b |
25 | #include <OpenGl_Workspace.hxx> |
59f45b7c |
26 | |
c04c30b3 |
27 | #include <Graphic3d_GraphicDriver.hxx> |
59f45b7c |
28 | |
f88457e6 |
29 | namespace |
30 | { |
31 | //! Auxiliary class extending sequence iterator with index. |
1c728f2d |
32 | class OpenGl_IndexedLayerIterator : public NCollection_List<Handle(Graphic3d_Layer)>::Iterator |
f88457e6 |
33 | { |
34 | public: |
35 | //! Main constructor. |
1c728f2d |
36 | OpenGl_IndexedLayerIterator (const NCollection_List<Handle(Graphic3d_Layer)>& theSeq) |
37 | : NCollection_List<Handle(Graphic3d_Layer)>::Iterator (theSeq), |
38 | myIndex (1) {} |
f88457e6 |
39 | |
40 | //! Return index of current position. |
41 | Standard_Integer Index() const { return myIndex; } |
42 | |
43 | //! Move to the next position. |
44 | void Next() |
45 | { |
1c728f2d |
46 | NCollection_List<Handle(Graphic3d_Layer)>::Iterator::Next(); |
f88457e6 |
47 | ++myIndex; |
48 | } |
49 | |
50 | private: |
51 | Standard_Integer myIndex; |
52 | }; |
53 | |
54 | //! Iterator through layers with filter. |
55 | class OpenGl_FilteredIndexedLayerIterator |
56 | { |
57 | public: |
58 | //! Main constructor. |
1c728f2d |
59 | OpenGl_FilteredIndexedLayerIterator (const NCollection_List<Handle(Graphic3d_Layer)>& theSeq, |
f88457e6 |
60 | Standard_Boolean theToDrawImmediate, |
61 | OpenGl_LayerFilter theLayersToProcess) |
62 | : myIter (theSeq), |
f88457e6 |
63 | myLayersToProcess (theLayersToProcess), |
64 | myToDrawImmediate (theToDrawImmediate) |
65 | { |
66 | next(); |
67 | } |
68 | |
69 | //! Return true if iterator points to the valid value. |
70 | bool More() const { return myIter.More(); } |
71 | |
72 | //! Return layer at current position. |
73 | const OpenGl_Layer& Value() const { return *myIter.Value(); } |
74 | |
75 | //! Return index of current position. |
76 | Standard_Integer Index() const { return myIter.Index(); } |
77 | |
78 | //! Go to the next item. |
79 | void Next() |
80 | { |
81 | myIter.Next(); |
82 | next(); |
83 | } |
84 | |
85 | private: |
86 | //! Look for the nearest item passing filters. |
87 | void next() |
88 | { |
89 | for (; myIter.More(); myIter.Next()) |
90 | { |
1c728f2d |
91 | const Handle(Graphic3d_Layer)& aLayer = myIter.Value(); |
92 | if (aLayer->IsImmediate() != myToDrawImmediate) |
f88457e6 |
93 | { |
94 | continue; |
95 | } |
96 | |
97 | switch (myLayersToProcess) |
98 | { |
99 | case OpenGl_LF_All: |
100 | { |
1c728f2d |
101 | return; |
f88457e6 |
102 | } |
103 | case OpenGl_LF_Upper: |
104 | { |
1c728f2d |
105 | if (aLayer->LayerId() != Graphic3d_ZLayerId_BotOSD |
106 | && (!aLayer->LayerSettings().IsRaytracable() |
107 | || aLayer->IsImmediate())) |
f88457e6 |
108 | { |
1c728f2d |
109 | return; |
f88457e6 |
110 | } |
111 | break; |
112 | } |
113 | case OpenGl_LF_Bottom: |
114 | { |
1c728f2d |
115 | if (aLayer->LayerId() == Graphic3d_ZLayerId_BotOSD |
116 | && !aLayer->LayerSettings().IsRaytracable()) |
f88457e6 |
117 | { |
1c728f2d |
118 | return; |
f88457e6 |
119 | } |
120 | break; |
121 | } |
1c728f2d |
122 | case OpenGl_LF_RayTracable: |
f88457e6 |
123 | { |
1c728f2d |
124 | if (aLayer->LayerSettings().IsRaytracable() |
125 | && !aLayer->IsImmediate()) |
f88457e6 |
126 | { |
1c728f2d |
127 | return; |
f88457e6 |
128 | } |
129 | break; |
130 | } |
131 | } |
f88457e6 |
132 | } |
133 | } |
134 | private: |
135 | OpenGl_IndexedLayerIterator myIter; |
f88457e6 |
136 | OpenGl_LayerFilter myLayersToProcess; |
137 | Standard_Boolean myToDrawImmediate; |
138 | }; |
139 | } |
140 | |
d325cb7f |
141 | struct OpenGl_GlobalLayerSettings |
142 | { |
143 | GLint DepthFunc; |
144 | GLboolean DepthMask; |
145 | }; |
146 | |
59f45b7c |
147 | //======================================================================= |
148 | //function : OpenGl_LayerList |
149 | //purpose : Constructor |
150 | //======================================================================= |
151 | |
152 | OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities) |
f5b72419 |
153 | : myBVHBuilder (new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth)), |
bd6a8454 |
154 | myNbPriorities (theNbPriorities), |
a1954302 |
155 | myNbStructures (0), |
bd6a8454 |
156 | myImmediateNbStructures (0), |
1b661a81 |
157 | myModifStateOfRaytraceable (0) |
59f45b7c |
158 | { |
1c728f2d |
159 | // |
59f45b7c |
160 | } |
161 | |
162 | //======================================================================= |
a1954302 |
163 | //function : ~OpenGl_LayerList |
164 | //purpose : Destructor |
59f45b7c |
165 | //======================================================================= |
166 | |
a1954302 |
167 | OpenGl_LayerList::~OpenGl_LayerList() |
59f45b7c |
168 | { |
59f45b7c |
169 | } |
170 | |
f5b72419 |
171 | //======================================================================= |
172 | //function : SetFrustumCullingBVHBuilder |
173 | //purpose : |
174 | //======================================================================= |
175 | void OpenGl_LayerList::SetFrustumCullingBVHBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) |
176 | { |
177 | myBVHBuilder = theBuilder; |
1c728f2d |
178 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
f5b72419 |
179 | { |
1c728f2d |
180 | aLayerIter.ChangeValue()->SetFrustumCullingBVHBuilder (theBuilder); |
f5b72419 |
181 | } |
182 | } |
183 | |
59f45b7c |
184 | //======================================================================= |
1c728f2d |
185 | //function : InsertLayerBefore |
186 | //purpose : |
59f45b7c |
187 | //======================================================================= |
1c728f2d |
188 | void OpenGl_LayerList::InsertLayerBefore (const Graphic3d_ZLayerId theNewLayerId, |
189 | const Graphic3d_ZLayerSettings& theSettings, |
190 | const Graphic3d_ZLayerId theLayerAfter) |
59f45b7c |
191 | { |
1c728f2d |
192 | if (myLayerIds.IsBound (theNewLayerId)) |
a1954302 |
193 | { |
59f45b7c |
194 | return; |
a1954302 |
195 | } |
59f45b7c |
196 | |
1c728f2d |
197 | Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, myNbPriorities, myBVHBuilder); |
198 | aNewLayer->SetLayerSettings (theSettings); |
a1073ae2 |
199 | |
1c728f2d |
200 | Handle(Graphic3d_Layer) anOtherLayer; |
201 | if (theLayerAfter != Graphic3d_ZLayerId_UNKNOWN |
202 | && myLayerIds.Find (theLayerAfter, anOtherLayer)) |
203 | { |
204 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
205 | { |
206 | if (aLayerIter.Value() == anOtherLayer) |
207 | { |
208 | myLayers.InsertBefore (aNewLayer, aLayerIter); |
209 | break; |
210 | } |
211 | } |
212 | } |
213 | else |
214 | { |
215 | myLayers.Prepend (aNewLayer); |
216 | } |
59f45b7c |
217 | |
1c728f2d |
218 | myLayerIds.Bind (theNewLayerId, aNewLayer); |
219 | myTransparentToProcess.Allocate (myLayers.Size()); |
c5751993 |
220 | } |
221 | |
222 | //======================================================================= |
1c728f2d |
223 | //function : InsertLayerAfter |
224 | //purpose : |
c5751993 |
225 | //======================================================================= |
1c728f2d |
226 | void OpenGl_LayerList::InsertLayerAfter (const Graphic3d_ZLayerId theNewLayerId, |
227 | const Graphic3d_ZLayerSettings& theSettings, |
228 | const Graphic3d_ZLayerId theLayerBefore) |
c5751993 |
229 | { |
1c728f2d |
230 | if (myLayerIds.IsBound (theNewLayerId)) |
231 | { |
232 | return; |
233 | } |
234 | |
235 | Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, myNbPriorities, myBVHBuilder); |
236 | aNewLayer->SetLayerSettings (theSettings); |
237 | |
238 | Handle(Graphic3d_Layer) anOtherLayer; |
239 | if (theLayerBefore != Graphic3d_ZLayerId_UNKNOWN |
240 | && myLayerIds.Find (theLayerBefore, anOtherLayer)) |
241 | { |
242 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
243 | { |
244 | if (aLayerIter.Value() == anOtherLayer) |
245 | { |
246 | myLayers.InsertAfter (aNewLayer, aLayerIter); |
247 | break; |
248 | } |
249 | } |
250 | } |
251 | else |
252 | { |
253 | myLayers.Append (aNewLayer); |
254 | } |
255 | |
256 | myLayerIds.Bind (theNewLayerId, aNewLayer); |
257 | myTransparentToProcess.Allocate (myLayers.Size()); |
c5751993 |
258 | } |
259 | |
59f45b7c |
260 | //======================================================================= |
261 | //function : RemoveLayer |
262 | //purpose : |
263 | //======================================================================= |
a1954302 |
264 | void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId) |
59f45b7c |
265 | { |
1c728f2d |
266 | Handle(Graphic3d_Layer) aLayerToRemove; |
267 | if (theLayerId <= 0 |
268 | || !myLayerIds.Find (theLayerId, aLayerToRemove)) |
a1954302 |
269 | { |
59f45b7c |
270 | return; |
a1954302 |
271 | } |
59f45b7c |
272 | |
59f45b7c |
273 | // move all displayed structures to first layer |
1c728f2d |
274 | myLayerIds.Find (Graphic3d_ZLayerId_Default)->Append (*aLayerToRemove); |
59f45b7c |
275 | |
276 | // remove layer |
1c728f2d |
277 | myLayers.Remove (aLayerToRemove); |
59f45b7c |
278 | myLayerIds.UnBind (theLayerId); |
279 | |
1c728f2d |
280 | myTransparentToProcess.Allocate (myLayers.Size()); |
59f45b7c |
281 | } |
282 | |
283 | //======================================================================= |
284 | //function : AddStructure |
285 | //purpose : |
286 | //======================================================================= |
287 | |
a1954302 |
288 | void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct, |
289 | const Graphic3d_ZLayerId theLayerId, |
290 | const Standard_Integer thePriority, |
291 | Standard_Boolean isForChangePriority) |
59f45b7c |
292 | { |
293 | // add structure to associated layer, |
294 | // if layer doesn't exists, display structure in default layer |
1c728f2d |
295 | const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId); |
296 | const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default); |
297 | aLayer->Add (theStruct, thePriority, isForChangePriority); |
a1954302 |
298 | ++myNbStructures; |
1c728f2d |
299 | if (aLayer->IsImmediate()) |
a1954302 |
300 | { |
301 | ++myImmediateNbStructures; |
302 | } |
e276548b |
303 | |
304 | // Note: In ray-tracing mode we don't modify modification |
305 | // state here. It is redundant, because the possible changes |
306 | // will be handled in the loop for structures |
59f45b7c |
307 | } |
308 | |
309 | //======================================================================= |
310 | //function : RemoveStructure |
a1954302 |
311 | //purpose : |
59f45b7c |
312 | //======================================================================= |
313 | |
c357e426 |
314 | void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure) |
59f45b7c |
315 | { |
c357e426 |
316 | const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); |
1c728f2d |
317 | const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (aLayerId); |
318 | const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default); |
a1954302 |
319 | |
a1954302 |
320 | Standard_Integer aPriority = -1; |
59f45b7c |
321 | |
322 | // remove structure from associated list |
323 | // if the structure is not found there, |
324 | // scan through layers and remove it |
1c728f2d |
325 | if (aLayer->Remove (theStructure, aPriority)) |
59f45b7c |
326 | { |
a1954302 |
327 | --myNbStructures; |
1c728f2d |
328 | if (aLayer->IsImmediate()) |
a1954302 |
329 | { |
330 | --myImmediateNbStructures; |
331 | } |
e276548b |
332 | |
1c728f2d |
333 | if (aLayer->LayerSettings().IsRaytracable() |
bd6a8454 |
334 | && theStructure->IsRaytracable()) |
e276548b |
335 | { |
bd6a8454 |
336 | ++myModifStateOfRaytraceable; |
e276548b |
337 | } |
e276548b |
338 | |
59f45b7c |
339 | return; |
340 | } |
a1954302 |
341 | |
59f45b7c |
342 | // scan through layers and remove it |
1c728f2d |
343 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
59f45b7c |
344 | { |
1c728f2d |
345 | const Handle(Graphic3d_Layer)& aLayerEx = aLayerIter.ChangeValue(); |
346 | if (aLayerEx == aLayer) |
59f45b7c |
347 | { |
a1954302 |
348 | continue; |
349 | } |
e276548b |
350 | |
1c728f2d |
351 | if (aLayerEx->Remove (theStructure, aPriority)) |
a1954302 |
352 | { |
353 | --myNbStructures; |
1c728f2d |
354 | if (aLayerEx->IsImmediate()) |
e276548b |
355 | { |
a1954302 |
356 | --myImmediateNbStructures; |
e276548b |
357 | } |
e276548b |
358 | |
1c728f2d |
359 | if (aLayerEx->LayerSettings().IsRaytracable() |
bd6a8454 |
360 | && theStructure->IsRaytracable()) |
a1954302 |
361 | { |
bd6a8454 |
362 | ++myModifStateOfRaytraceable; |
a1954302 |
363 | } |
59f45b7c |
364 | return; |
365 | } |
366 | } |
367 | } |
368 | |
b7cd4ba7 |
369 | //======================================================================= |
370 | //function : InvalidateBVHData |
371 | //purpose : |
372 | //======================================================================= |
a1954302 |
373 | void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) |
b7cd4ba7 |
374 | { |
1c728f2d |
375 | const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId); |
376 | const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default); |
377 | aLayer->InvalidateBVHData(); |
b7cd4ba7 |
378 | } |
379 | |
59f45b7c |
380 | //======================================================================= |
381 | //function : ChangeLayer |
382 | //purpose : |
383 | //======================================================================= |
384 | |
a1954302 |
385 | void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure, |
386 | const Graphic3d_ZLayerId theOldLayerId, |
387 | const Graphic3d_ZLayerId theNewLayerId) |
59f45b7c |
388 | { |
1c728f2d |
389 | const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theOldLayerId); |
390 | const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default); |
391 | |
a1954302 |
392 | Standard_Integer aPriority = -1; |
59f45b7c |
393 | |
394 | // take priority and remove structure from list found by <theOldLayerId> |
395 | // if the structure is not found there, scan through all other layers |
1c728f2d |
396 | if (aLayer->Remove (theStructure, aPriority, Standard_False)) |
59f45b7c |
397 | { |
1c728f2d |
398 | if (aLayer->LayerSettings().IsRaytracable() |
399 | && !aLayer->LayerSettings().IsImmediate() |
400 | && theStructure->IsRaytracable()) |
bd6a8454 |
401 | { |
402 | ++myModifStateOfRaytraceable; |
403 | } |
404 | |
a1954302 |
405 | --myNbStructures; |
1c728f2d |
406 | if (aLayer->IsImmediate()) |
a1954302 |
407 | { |
408 | --myImmediateNbStructures; |
409 | } |
410 | |
a0c20252 |
411 | // isForChangePriority should be Standard_False below, because we want |
412 | // the BVH tree in the target layer to be updated with theStructure |
413 | AddStructure (theStructure, theNewLayerId, aPriority); |
a1954302 |
414 | return; |
59f45b7c |
415 | } |
a1954302 |
416 | |
417 | // scan through layers and remove it |
1c728f2d |
418 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
59f45b7c |
419 | { |
1c728f2d |
420 | const Handle(OpenGl_Layer)& aLayerEx = aLayerIter.ChangeValue(); |
421 | if (aLayerEx == aLayer) |
59f45b7c |
422 | { |
a1954302 |
423 | continue; |
424 | } |
59f45b7c |
425 | |
a1954302 |
426 | // try to remove structure and get priority value from this layer |
1c728f2d |
427 | if (aLayerEx->Remove (theStructure, aPriority, Standard_True)) |
a1954302 |
428 | { |
1c728f2d |
429 | if (aLayerEx->LayerSettings().IsRaytracable() |
430 | && !aLayerEx->LayerSettings().IsImmediate() |
431 | && theStructure->IsRaytracable()) |
bd6a8454 |
432 | { |
433 | ++myModifStateOfRaytraceable; |
434 | } |
435 | |
a1954302 |
436 | --myNbStructures; |
1c728f2d |
437 | if (aLayerEx->IsImmediate()) |
b7cd4ba7 |
438 | { |
a1954302 |
439 | --myImmediateNbStructures; |
b7cd4ba7 |
440 | } |
a1954302 |
441 | |
442 | // isForChangePriority should be Standard_False below, because we want |
443 | // the BVH tree in the target layer to be updated with theStructure |
444 | AddStructure (theStructure, theNewLayerId, aPriority); |
445 | return; |
b7cd4ba7 |
446 | } |
447 | } |
448 | } |
449 | |
450 | //======================================================================= |
451 | //function : ChangePriority |
452 | //purpose : |
453 | //======================================================================= |
a1954302 |
454 | void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure, |
455 | const Graphic3d_ZLayerId theLayerId, |
456 | const Standard_Integer theNewPriority) |
b7cd4ba7 |
457 | { |
1c728f2d |
458 | const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId); |
459 | const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default); |
460 | |
a1954302 |
461 | Standard_Integer anOldPriority = -1; |
b7cd4ba7 |
462 | |
1c728f2d |
463 | if (aLayer->Remove (theStructure, anOldPriority, Standard_True)) |
b7cd4ba7 |
464 | { |
a1954302 |
465 | --myNbStructures; |
1c728f2d |
466 | if (aLayer->IsImmediate()) |
a1954302 |
467 | { |
468 | --myImmediateNbStructures; |
469 | } |
470 | |
b7cd4ba7 |
471 | AddStructure (theStructure, theLayerId, theNewPriority, Standard_True); |
a1954302 |
472 | return; |
b7cd4ba7 |
473 | } |
a1954302 |
474 | |
1c728f2d |
475 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
b7cd4ba7 |
476 | { |
1c728f2d |
477 | const Handle(OpenGl_Layer)& aLayerEx = aLayerIter.ChangeValue(); |
478 | if (aLayerEx == aLayer) |
b7cd4ba7 |
479 | { |
a1954302 |
480 | continue; |
481 | } |
b7cd4ba7 |
482 | |
1c728f2d |
483 | if (aLayerEx->Remove (theStructure, anOldPriority, Standard_True)) |
a1954302 |
484 | { |
485 | --myNbStructures; |
1c728f2d |
486 | if (aLayerEx->IsImmediate()) |
59f45b7c |
487 | { |
a1954302 |
488 | --myImmediateNbStructures; |
59f45b7c |
489 | } |
a1954302 |
490 | |
491 | AddStructure (theStructure, theLayerId, theNewPriority, Standard_True); |
492 | return; |
59f45b7c |
493 | } |
494 | } |
495 | } |
496 | |
497 | //======================================================================= |
a1954302 |
498 | //function : SetLayerSettings |
499 | //purpose : |
59f45b7c |
500 | //======================================================================= |
a1954302 |
501 | void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLayerId, |
502 | const Graphic3d_ZLayerSettings& theSettings) |
503 | { |
1c728f2d |
504 | Graphic3d_Layer& aLayer = Layer (theLayerId); |
505 | if (aLayer.LayerSettings().IsRaytracable() != theSettings.IsRaytracable() |
506 | && aLayer.NbStructures() != 0) |
507 | { |
508 | ++myModifStateOfRaytraceable; |
509 | } |
7c3ef2f7 |
510 | if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate()) |
a1954302 |
511 | { |
7c3ef2f7 |
512 | if (theSettings.IsImmediate()) |
a1954302 |
513 | { |
514 | myImmediateNbStructures += aLayer.NbStructures(); |
515 | } |
516 | else |
517 | { |
518 | myImmediateNbStructures -= aLayer.NbStructures(); |
519 | } |
520 | } |
521 | aLayer.SetLayerSettings (theSettings); |
522 | } |
59f45b7c |
523 | |
2b8832bb |
524 | //======================================================================= |
525 | //function : UpdateCulling |
526 | //purpose : |
527 | //======================================================================= |
528 | void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspace, |
529 | const Standard_Boolean theToDrawImmediate) |
530 | { |
5e30547b |
531 | const Handle(OpenGl_FrameStats)& aStats = theWorkspace->GetGlContext()->FrameStats(); |
532 | OSD_Timer& aTimer = aStats->ActiveDataFrame().ChangeTimer (Graphic3d_FrameStatsTimer_CpuCulling); |
533 | aTimer.Start(); |
534 | |
5dc0517d |
535 | const Standard_Integer aViewId = theWorkspace->View()->Identification(); |
d325cb7f |
536 | const Graphic3d_CullingTool& aSelector = theWorkspace->View()->BVHTreeSelector(); |
1c728f2d |
537 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next()) |
2b8832bb |
538 | { |
1c728f2d |
539 | const Handle(Graphic3d_Layer)& aLayer = aLayerIter.ChangeValue(); |
540 | if (aLayer->IsImmediate() != theToDrawImmediate) |
2b8832bb |
541 | { |
542 | continue; |
543 | } |
544 | |
1c728f2d |
545 | aLayer->UpdateCulling (aViewId, aSelector, theWorkspace->View()->RenderingParams().FrustumCullingState); |
2b8832bb |
546 | } |
5e30547b |
547 | |
548 | aTimer.Stop(); |
549 | aStats->ActiveDataFrame()[Graphic3d_FrameStatsTimer_CpuCulling] = aTimer.UserTimeCPU(); |
2b8832bb |
550 | } |
551 | |
d325cb7f |
552 | //======================================================================= |
553 | //function : renderLayer |
554 | //purpose : |
555 | //======================================================================= |
556 | void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace, |
557 | const OpenGl_GlobalLayerSettings& theDefaultSettings, |
558 | const Graphic3d_Layer& theLayer) const |
559 | { |
560 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
561 | |
562 | const Graphic3d_ZLayerSettings& aLayerSettings = theLayer.LayerSettings(); |
563 | // aLayerSettings.ToClearDepth() is handled outside |
564 | |
565 | // handle depth test |
566 | if (aLayerSettings.ToEnableDepthTest()) |
567 | { |
568 | // assuming depth test is enabled by default |
569 | glDepthFunc (theDefaultSettings.DepthFunc); |
570 | } |
571 | else |
572 | { |
573 | glDepthFunc (GL_ALWAYS); |
574 | } |
575 | |
576 | // save environment texture |
577 | Handle(OpenGl_TextureSet) anEnvironmentTexture = theWorkspace->EnvironmentTexture(); |
578 | if (!aLayerSettings.UseEnvironmentTexture()) |
579 | { |
580 | theWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)()); |
581 | } |
582 | |
583 | // handle depth offset |
584 | const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->SetDefaultPolygonOffset (aLayerSettings.PolygonOffset()); |
585 | |
586 | // handle depth write |
587 | theWorkspace->UseDepthWrite() = aLayerSettings.ToEnableDepthWrite() && theDefaultSettings.DepthMask == GL_TRUE; |
588 | glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE); |
589 | |
590 | const Standard_Boolean hasLocalCS = !aLayerSettings.OriginTransformation().IsNull(); |
591 | const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); |
592 | Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources(); |
593 | const bool hasOwnLights = aCtx->ColorMask() && !aLayerSettings.Lights().IsNull() && aLayerSettings.Lights() != aLightsBack; |
594 | if (hasOwnLights) |
595 | { |
596 | aLayerSettings.Lights()->UpdateRevision(); |
67312b79 |
597 | aManager->UpdateLightSourceStateTo (aLayerSettings.Lights(), theWorkspace->View()->SpecIBLMapLevels()); |
d325cb7f |
598 | } |
599 | |
600 | const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera(); |
601 | if (hasLocalCS) |
602 | { |
603 | // Apply local camera transformation. |
604 | // The vertex position is computed by the following formula in GLSL program: |
605 | // gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex; |
606 | // where: |
607 | // occProjectionMatrix - matrix defining orthographic/perspective/stereographic projection |
608 | // occWorldViewMatrix - world-view matrix defining Camera position and orientation |
609 | // occModelWorldMatrix - model-world matrix defining Object transformation from local coordinate system to the world coordinate system |
610 | // occVertex - input vertex position |
611 | // |
612 | // Since double precision is quite expensive on modern GPUs, and not available on old hardware, |
613 | // all these values are passed with single float precision to the shader. |
614 | // As result, single precision become insufficient for handling objects far from the world origin. |
615 | // |
616 | // Several approaches can be used to solve precision issues: |
617 | // - [Broute force] migrate to double precision for all matrices and vertex position. |
618 | // This is too expensive for most hardware. |
619 | // - Store only translation part with double precision and pass it to GLSL program. |
620 | // This requires modified GLSL programs for computing transformation |
621 | // and extra packing mechanism for hardware not supporting double precision natively. |
622 | // This solution is less expensive then previous one. |
623 | // - Move translation part of occModelWorldMatrix into occWorldViewMatrix. |
624 | // The main idea here is that while moving Camera towards the object, |
625 | // Camera translation part and Object translation part will compensate each other |
626 | // to fit into single float precision. |
627 | // But this operation should be performed with double precision - this is why we are moving |
628 | // translation part of occModelWorldMatrix to occWorldViewMatrix. |
629 | // |
630 | // All approaches might be useful in different scenarios, but for the moment we consider the last one as main scenario. |
631 | // Here we do the trick: |
632 | // - OpenGl_Layer defines the Local Origin, which is expected to be the center of objects stored within it. |
633 | // This Local Origin is included into occWorldViewMatrix during rendering. |
634 | // - OpenGl_Structure defines Object local transformation occModelWorldMatrix with subtracted Local Origin of the Layer. |
635 | // This means that Object itself should be defined within either Local Transformation equal or near to Local Origin of the Layer. |
636 | theWorkspace->View()->SetLocalOrigin (aLayerSettings.Origin()); |
637 | |
638 | NCollection_Mat4<Standard_Real> aWorldView = aWorldCamera->OrientationMatrix(); |
639 | Graphic3d_TransformUtils::Translate (aWorldView, aLayerSettings.Origin().X(), aLayerSettings.Origin().Y(), aLayerSettings.Origin().Z()); |
640 | |
641 | NCollection_Mat4<Standard_ShortReal> aWorldViewF; |
642 | aWorldViewF.ConvertFrom (aWorldView); |
643 | aCtx->WorldViewState.SetCurrent (aWorldViewF); |
644 | aCtx->ShaderManager()->UpdateClippingState(); |
645 | aCtx->ShaderManager()->UpdateLightSourceState(); |
646 | } |
647 | |
648 | // render priority list |
649 | const Standard_Integer aViewId = theWorkspace->View()->Identification(); |
650 | for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (theLayer.ArrayOfStructures()); aMapIter.More(); aMapIter.Next()) |
651 | { |
652 | const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value(); |
653 | for (OpenGl_Structure::StructIterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) |
654 | { |
655 | const OpenGl_Structure* aStruct = aStructIter.Value(); |
656 | if (aStruct->IsCulled() |
657 | || !aStruct->IsVisible (aViewId)) |
658 | { |
659 | continue; |
660 | } |
661 | |
662 | aStruct->Render (theWorkspace); |
663 | } |
664 | } |
665 | |
666 | if (hasOwnLights) |
667 | { |
67312b79 |
668 | aManager->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels()); |
d325cb7f |
669 | } |
670 | if (hasLocalCS) |
671 | { |
672 | aCtx->ShaderManager()->RevertClippingState(); |
673 | aCtx->ShaderManager()->UpdateLightSourceState(); |
674 | |
675 | aCtx->WorldViewState.SetCurrent (aWorldCamera->OrientationMatrixF()); |
676 | theWorkspace->View() ->SetLocalOrigin (gp_XYZ (0.0, 0.0, 0.0)); |
677 | } |
678 | |
679 | // always restore polygon offset between layers rendering |
680 | theWorkspace->SetDefaultPolygonOffset (anAppliedOffsetParams); |
681 | |
682 | // restore environment texture |
683 | if (!aLayerSettings.UseEnvironmentTexture()) |
684 | { |
685 | theWorkspace->SetEnvironmentTexture (anEnvironmentTexture); |
686 | } |
687 | } |
688 | |
a1954302 |
689 | //======================================================================= |
690 | //function : Render |
691 | //purpose : |
692 | //======================================================================= |
693 | void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, |
91c60b57 |
694 | const Standard_Boolean theToDrawImmediate, |
a1073ae2 |
695 | const OpenGl_LayerFilter theLayersToProcess, |
696 | OpenGl_FrameBuffer* theReadDrawFbo, |
697 | OpenGl_FrameBuffer* theOitAccumFbo) const |
59f45b7c |
698 | { |
a1073ae2 |
699 | // Remember global settings for glDepth function and write mask. |
f88457e6 |
700 | OpenGl_GlobalLayerSettings aPrevSettings; |
c5751993 |
701 | |
a1954302 |
702 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
f88457e6 |
703 | aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aPrevSettings.DepthFunc); |
704 | aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aPrevSettings.DepthMask); |
705 | OpenGl_GlobalLayerSettings aDefaultSettings = aPrevSettings; |
a1954302 |
706 | |
a1073ae2 |
707 | // Two render filters are used to support transparency draw. Opaque filter accepts |
708 | // only non-transparent OpenGl elements of a layer and counts number of skipped |
709 | // transparent ones. If the counter has positive value the layer is added into |
710 | // transparency post-processing stack. At the end of drawing or once the depth |
711 | // buffer is to be cleared the layers in the stack should be drawn using |
712 | // blending and depth mask settings and another transparency filter which accepts |
713 | // only transparent OpenGl elements of a layer. The stack <myTransparentToProcess> |
714 | // was preallocated before going into this method and has enough space to keep |
715 | // maximum number of references to layers, therefore it will not increase memory |
716 | // fragmentation during regular rendering. |
1b661a81 |
717 | const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly); |
718 | theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly); |
a1073ae2 |
719 | |
720 | myTransparentToProcess.Clear(); |
721 | |
722 | OpenGl_LayerStack::iterator aStackIter (myTransparentToProcess.Origin()); |
f88457e6 |
723 | Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1; |
724 | const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass |
725 | && aPrevSettings.DepthMask == GL_TRUE; |
992ed6b3 |
726 | const Handle(Graphic3d_LightSet) aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources(); |
1c728f2d |
727 | for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();) |
59f45b7c |
728 | { |
f88457e6 |
729 | bool hasSkippedDepthLayers = false; |
730 | for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter) |
91c60b57 |
731 | { |
f88457e6 |
732 | if (aPassIter == 0) |
733 | { |
734 | aCtx->SetColorMask (false); |
67312b79 |
735 | aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)(), theWorkspace->View()->SpecIBLMapLevels()); |
f88457e6 |
736 | aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc; |
737 | aDefaultSettings.DepthMask = GL_TRUE; |
738 | } |
739 | else if (aPassIter == 1) |
740 | { |
741 | if (!hasSkippedDepthLayers) |
742 | { |
743 | continue; |
744 | } |
745 | aCtx->SetColorMask (true); |
67312b79 |
746 | aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels()); |
f88457e6 |
747 | aDefaultSettings = aPrevSettings; |
748 | } |
749 | else if (aPassIter == 2) |
750 | { |
751 | aCtx->SetColorMask (true); |
67312b79 |
752 | aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels()); |
f88457e6 |
753 | if (toPerformDepthPrepass) |
754 | { |
755 | aDefaultSettings.DepthFunc = GL_EQUAL; |
756 | aDefaultSettings.DepthMask = GL_FALSE; |
757 | } |
758 | } |
91c60b57 |
759 | |
f88457e6 |
760 | OpenGl_FilteredIndexedLayerIterator aLayerIter (aLayerIterStart); |
761 | for (; aLayerIter.More(); aLayerIter.Next()) |
762 | { |
763 | const OpenGl_Layer& aLayer = aLayerIter.Value(); |
764 | |
765 | // make sure to clear depth of previous layers even if layer has no structures |
766 | if (aLayer.LayerSettings().ToClearDepth()) |
767 | { |
768 | aClearDepthLayer = aLayerIter.Index(); |
769 | } |
2b8832bb |
770 | if (aLayer.IsCulled()) |
f88457e6 |
771 | { |
772 | continue; |
773 | } |
774 | else if (aClearDepthLayer > aClearDepthLayerPrev) |
775 | { |
776 | // At this point the depth buffer may be set to clear by previous configuration of layers or configuration of the current layer. |
777 | // Additional rendering pass to handle transparent elements of recently drawn layers require use of current depth |
778 | // buffer so we put remaining layers for processing as one bunch before erasing the depth buffer. |
779 | if (aPassIter == 2) |
780 | { |
781 | aLayerIterStart = aLayerIter; |
782 | } |
783 | else |
784 | { |
785 | aClearDepthLayer = -1; |
786 | } |
787 | break; |
788 | } |
789 | else if (aPassIter == 0 |
790 | && !aLayer.LayerSettings().ToRenderInDepthPrepass()) |
791 | { |
792 | hasSkippedDepthLayers = true; |
793 | continue; |
794 | } |
795 | else if (aPassIter == 1 |
796 | && aLayer.LayerSettings().ToRenderInDepthPrepass()) |
797 | { |
798 | continue; |
799 | } |
800 | |
801 | // Render opaque OpenGl elements of a layer and count the number of skipped. |
802 | // If a layer has skipped (e.g. transparent) elements it should be added into |
803 | // the transparency post-processing stack. |
1b661a81 |
804 | theWorkspace->ResetSkippedCounter(); |
f88457e6 |
805 | |
d325cb7f |
806 | renderLayer (theWorkspace, aDefaultSettings, aLayer); |
f88457e6 |
807 | |
808 | if (aPassIter != 0 |
1b661a81 |
809 | && theWorkspace->NbSkippedTransparentElements() > 0) |
f88457e6 |
810 | { |
811 | myTransparentToProcess.Push (&aLayer); |
812 | } |
813 | } |
814 | if (aPassIter == 2 |
815 | && !aLayerIter.More()) |
816 | { |
817 | aLayerIterStart = aLayerIter; |
818 | } |
a1954302 |
819 | } |
f88457e6 |
820 | |
821 | if (!myTransparentToProcess.IsEmpty()) |
59f45b7c |
822 | { |
f88457e6 |
823 | renderTransparent (theWorkspace, aStackIter, aPrevSettings, theReadDrawFbo, theOitAccumFbo); |
59f45b7c |
824 | } |
f88457e6 |
825 | if (aClearDepthLayer > aClearDepthLayerPrev) |
a1954302 |
826 | { |
f88457e6 |
827 | aClearDepthLayerPrev = aClearDepthLayer; |
b3eab8ef |
828 | glDepthMask (GL_TRUE); |
829 | glClear (GL_DEPTH_BUFFER_BIT); |
a1954302 |
830 | } |
b3eab8ef |
831 | } |
832 | |
f88457e6 |
833 | aCtx->core11fwd->glDepthMask (aPrevSettings.DepthMask); |
834 | aCtx->core11fwd->glDepthFunc (aPrevSettings.DepthFunc); |
a1073ae2 |
835 | |
836 | theWorkspace->SetRenderFilter (aPrevFilter); |
837 | } |
838 | |
839 | //======================================================================= |
840 | //function : renderTransparent |
841 | //purpose : Render transparent objects using blending operator. |
842 | //======================================================================= |
843 | void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theWorkspace, |
844 | OpenGl_LayerStack::iterator& theLayerIter, |
845 | const OpenGl_GlobalLayerSettings& theGlobalSettings, |
846 | OpenGl_FrameBuffer* theReadDrawFbo, |
847 | OpenGl_FrameBuffer* theOitAccumFbo) const |
848 | { |
849 | // Blended order-independent transparency algorithm require several preconditions |
850 | // to be enabled. It should be requested by user, at least two outputs from |
851 | // fragment shader should be supported by GPU, so is the given framebuffer |
852 | // should contain two additional color buffers to handle accumulated color channels, |
853 | // blended alpha channel and weight factors - these accumulation buffers are required |
854 | // to implement commuting blend operator (at least OpenGl 2.0 should be available). |
855 | const bool isEnabledOit = theOitAccumFbo != NULL |
856 | && theOitAccumFbo->NbColorBuffers() >= 2 |
857 | && theOitAccumFbo->ColorTexture (0)->IsValid() |
858 | && theOitAccumFbo->ColorTexture (1)->IsValid(); |
859 | |
860 | // Check if current iterator has already reached the end of the stack. |
861 | // This should happen if no additional layers has been added to |
862 | // the processing stack after last transparency pass. |
863 | if (theLayerIter == myTransparentToProcess.Back()) |
864 | { |
865 | return; |
866 | } |
867 | |
868 | const Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext(); |
869 | const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); |
870 | OpenGl_View* aView = theWorkspace->View(); |
871 | const float aDepthFactor = aView != NULL ? aView->RenderingParams().OitDepthFactor : 0.0f; |
872 | |
1b661a81 |
873 | const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly); |
874 | theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_TransparentOnly); |
a1073ae2 |
875 | |
876 | aCtx->core11fwd->glEnable (GL_BLEND); |
877 | |
878 | if (isEnabledOit) |
879 | { |
880 | aManager->SetOitState (true, aDepthFactor); |
881 | |
882 | theOitAccumFbo->BindBuffer (aCtx); |
883 | |
884 | static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1 }; |
885 | aCtx->SetDrawBuffers (2, aDrawBuffers); |
886 | aCtx->core11fwd->glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
887 | aCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT); |
888 | aCtx->core15fwd->glBlendFuncSeparate (GL_ONE, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); |
889 | } |
890 | else |
891 | { |
892 | aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
893 | } |
894 | |
895 | // During blended order-independent transparency pass the depth test |
896 | // should be enabled to discard fragments covered by opaque geometry |
897 | // and depth writing should be disabled, because transparent fragments |
898 | // overal each other with non unitary coverage factor. |
899 | OpenGl_GlobalLayerSettings aGlobalSettings = theGlobalSettings; |
900 | aGlobalSettings.DepthMask = GL_FALSE; |
901 | aCtx->core11fwd->glDepthMask (GL_FALSE); |
902 | |
903 | for (; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter) |
904 | { |
d325cb7f |
905 | renderLayer (theWorkspace, aGlobalSettings, *(*theLayerIter)); |
a1073ae2 |
906 | } |
907 | |
908 | // Revert state of rendering. |
909 | if (isEnabledOit) |
910 | { |
911 | aManager->SetOitState (false, aDepthFactor); |
912 | theOitAccumFbo->UnbindBuffer (aCtx); |
913 | if (theReadDrawFbo) |
914 | { |
915 | theReadDrawFbo->BindBuffer (aCtx); |
916 | } |
917 | |
918 | static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; |
919 | aCtx->SetDrawBuffers (1, aDrawBuffers); |
920 | } |
921 | |
1b661a81 |
922 | theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly); |
a1073ae2 |
923 | if (isEnabledOit) |
924 | { |
925 | const Standard_Boolean isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0; |
926 | OpenGl_VertexBuffer* aVerts = theWorkspace->View()->initBlitQuad (Standard_False); |
927 | if (aVerts->IsValid() && aManager->BindOitCompositingProgram (isMSAA)) |
928 | { |
929 | aCtx->core11fwd->glDepthFunc (GL_ALWAYS); |
930 | aCtx->core11fwd->glDepthMask (GL_FALSE); |
931 | |
932 | // Bind full screen quad buffer and framebuffer resources. |
933 | aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS); |
934 | |
cc8cbabe |
935 | const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)()); |
a1073ae2 |
936 | |
cc8cbabe |
937 | theOitAccumFbo->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_0); |
938 | theOitAccumFbo->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_1); |
a1073ae2 |
939 | |
940 | // Draw full screen quad with special shader to compose the buffers. |
941 | aCtx->core11fwd->glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); |
942 | aCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); |
943 | |
944 | // Unbind OpenGL texture objects and shader program. |
945 | aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS); |
cc8cbabe |
946 | theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, Graphic3d_TextureUnit_1); |
ce1c28b8 |
947 | theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, Graphic3d_TextureUnit_0); |
a1073ae2 |
948 | aCtx->BindProgram (NULL); |
949 | |
950 | if (!aTextureBack.IsNull()) |
951 | { |
cc8cbabe |
952 | aCtx->BindTextures (aTextureBack); |
a1073ae2 |
953 | } |
954 | } |
955 | else |
956 | { |
957 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
958 | "Initialization of OIT compositing pass has failed.\n" |
959 | " Blended order-independent transparency will not be available.\n"); |
960 | if (aView != NULL) |
961 | { |
962 | Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT; |
963 | aOITFlag = Standard_True; |
964 | } |
965 | } |
966 | } |
967 | |
968 | aCtx->core11fwd->glDisable (GL_BLEND); |
969 | aCtx->core11fwd->glBlendFunc (GL_ONE, GL_ZERO); |
970 | aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask); |
971 | aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc); |
972 | } |