e276548b |
1 | // Created on: 2013-08-27 |
2 | // Created by: Denis BOGOLEPOV |
3 | // Copyright (c) 2013 OPEN CASCADE SAS |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
e276548b |
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. |
e276548b |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
e276548b |
15 | |
65578e1c |
16 | #include <OSD_Timer.hxx> |
c7b59798 |
17 | #include <OSD_Parallel.hxx> |
65578e1c |
18 | #include <Standard_Assert.hxx> |
25ef750e |
19 | #include <OpenGl_ArbTexBindless.hxx> |
b7cd4ba7 |
20 | #include <OpenGl_PrimitiveArray.hxx> |
65578e1c |
21 | #include <OpenGl_SceneGeometry.hxx> |
b7cd4ba7 |
22 | #include <OpenGl_Structure.hxx> |
c04c30b3 |
23 | #include <Graphic3d_GraphicDriver.hxx> |
b7cd4ba7 |
24 | |
265d4508 |
25 | //! Use this macro to output BVH profiling info |
25ef750e |
26 | // #define RAY_TRACE_PRINT_INFO |
e276548b |
27 | |
265d4508 |
28 | namespace |
29 | { |
e276548b |
30 | //! Useful constant for null floating-point 4D vector. |
265d4508 |
31 | static const BVH_Vec4f ZERO_VEC_4F; |
25ef750e |
32 | } |
e276548b |
33 | |
34 | // ======================================================================= |
64c759f8 |
35 | // function : OpenGl_RaytraceMaterial |
e276548b |
36 | // purpose : Creates new default material |
37 | // ======================================================================= |
38 | OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial() |
265d4508 |
39 | : Ambient (ZERO_VEC_4F), |
40 | Diffuse (ZERO_VEC_4F), |
41 | Specular (ZERO_VEC_4F), |
42 | Emission (ZERO_VEC_4F), |
43 | Reflection (ZERO_VEC_4F), |
44 | Refraction (ZERO_VEC_4F), |
45 | Transparency (ZERO_VEC_4F) |
e276548b |
46 | { } |
47 | |
48 | // ======================================================================= |
64c759f8 |
49 | // function : OpenGl_RaytraceMaterial |
e276548b |
50 | // purpose : Creates new material with specified properties |
51 | // ======================================================================= |
265d4508 |
52 | OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient, |
53 | const BVH_Vec4f& theDiffuse, |
54 | const BVH_Vec4f& theSpecular) |
e276548b |
55 | : Ambient (theAmbient), |
56 | Diffuse (theDiffuse), |
57 | Specular (theSpecular), |
265d4508 |
58 | Emission (ZERO_VEC_4F), |
59 | Reflection (ZERO_VEC_4F), |
60 | Refraction (ZERO_VEC_4F), |
61 | Transparency (ZERO_VEC_4F) |
e276548b |
62 | { |
63 | // |
64 | } |
65 | |
66 | // ======================================================================= |
64c759f8 |
67 | // function : OpenGl_RaytraceMaterial |
e276548b |
68 | // purpose : Creates new material with specified properties |
69 | // ======================================================================= |
265d4508 |
70 | OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient, |
71 | const BVH_Vec4f& theDiffuse, |
72 | const BVH_Vec4f& theSpecular, |
73 | const BVH_Vec4f& theEmission, |
74 | const BVH_Vec4f& theTranspar) |
e276548b |
75 | : Ambient (theAmbient), |
76 | Diffuse (theDiffuse), |
77 | Specular (theSpecular), |
78 | Emission (theEmission), |
265d4508 |
79 | Reflection (ZERO_VEC_4F), |
80 | Refraction (ZERO_VEC_4F), |
e276548b |
81 | Transparency (theTranspar) |
82 | { |
83 | // |
84 | } |
85 | |
86 | // ======================================================================= |
64c759f8 |
87 | // function : OpenGl_RaytraceMaterial |
e276548b |
88 | // purpose : Creates new material with specified properties |
89 | // ======================================================================= |
265d4508 |
90 | OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient, |
91 | const BVH_Vec4f& theDiffuse, |
92 | const BVH_Vec4f& theSpecular, |
93 | const BVH_Vec4f& theEmission, |
94 | const BVH_Vec4f& theTranspar, |
95 | const BVH_Vec4f& theReflection, |
96 | const BVH_Vec4f& theRefraction) |
e276548b |
97 | : Ambient (theAmbient), |
98 | Diffuse (theDiffuse), |
99 | Specular (theSpecular), |
100 | Emission (theEmission), |
101 | Reflection (theReflection), |
102 | Refraction (theRefraction), |
103 | Transparency (theTranspar) |
104 | { |
105 | // |
106 | } |
107 | |
108 | // ======================================================================= |
109 | // function : OpenGl_LightSource |
110 | // purpose : Creates new light source |
111 | // ======================================================================= |
265d4508 |
112 | OpenGl_RaytraceLight::OpenGl_RaytraceLight (const BVH_Vec4f& theDiffuse, |
113 | const BVH_Vec4f& thePosition) |
e276548b |
114 | : Diffuse (theDiffuse), |
115 | Position (thePosition) |
116 | { |
117 | // |
118 | } |
119 | |
f2474958 |
120 | // ======================================================================= |
121 | // function : QuadBVH |
122 | // purpose : Returns quad BVH (QBVH) tree produced from binary BVH |
123 | // ======================================================================= |
124 | const QuadBvhHandle& OpenGl_TriangleSet::QuadBVH() |
125 | { |
126 | if (!myIsDirty) |
127 | { |
128 | Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH"); |
129 | } |
130 | else |
131 | { |
132 | myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it |
133 | |
134 | myBVH->Clear(); // erase binary BVH |
135 | } |
136 | |
137 | return myQuadBVH; |
138 | } |
139 | |
50d0e1ce |
140 | // ======================================================================= |
141 | // function : Center |
142 | // purpose : Returns centroid position along the given axis |
143 | // ======================================================================= |
144 | Standard_ShortReal OpenGl_TriangleSet::Center ( |
145 | const Standard_Integer theIndex, const Standard_Integer theAxis) const |
146 | { |
147 | // Note: Experiments show that the use of the box centroid (instead |
148 | // of the triangle centroid) increases render performance up to 12% |
149 | |
150 | const BVH_Vec4i& aTriangle = Elements[theIndex]; |
151 | |
152 | const Standard_ShortReal aVertex0 = |
153 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.x()], theAxis); |
154 | const Standard_ShortReal aVertex1 = |
155 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.y()], theAxis); |
156 | const Standard_ShortReal aVertex2 = |
157 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.z()], theAxis); |
158 | |
159 | return (Min (Min (aVertex0, aVertex1), aVertex2) + |
160 | Max (Max (aVertex0, aVertex1), aVertex2)) * 0.5f; |
161 | } |
162 | |
25ef750e |
163 | // ======================================================================= |
164 | // function : Box |
165 | // purpose : Returns AABB of primitive set |
166 | // ======================================================================= |
167 | OpenGl_TriangleSet::BVH_BoxNt OpenGl_TriangleSet::Box() const |
168 | { |
169 | const BVH_Transform<Standard_ShortReal, 4>* aTransform = |
170 | dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->()); |
171 | |
172 | BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 3>::Box(); |
173 | |
174 | if (aTransform != NULL) |
175 | { |
176 | BVH_BoxNt aTransformedBox; |
177 | |
178 | for (Standard_Integer aX = 0; aX <= 1; ++aX) |
179 | { |
180 | for (Standard_Integer aY = 0; aY <= 1; ++aY) |
181 | { |
182 | for (Standard_Integer aZ = 0; aZ <= 1; ++aZ) |
183 | { |
184 | BVH_Vec4f aCorner = aTransform->Transform() * BVH_Vec4f ( |
185 | aX == 0 ? aBox.CornerMin().x() : aBox.CornerMax().x(), |
186 | aY == 0 ? aBox.CornerMin().y() : aBox.CornerMax().y(), |
187 | aZ == 0 ? aBox.CornerMin().z() : aBox.CornerMax().z(), |
188 | 1.f); |
189 | |
fe30607a |
190 | aTransformedBox.Add (aCorner.xyz()); |
25ef750e |
191 | } |
192 | } |
193 | } |
194 | |
195 | return aTransformedBox; |
196 | } |
197 | |
198 | return aBox; |
199 | } |
200 | |
65578e1c |
201 | // ======================================================================= |
202 | // function : OpenGl_TriangleSet |
203 | // purpose : Creates new OpenGL element triangulation |
204 | // ======================================================================= |
205 | OpenGl_TriangleSet::OpenGl_TriangleSet (const Standard_Size theArrayID) |
206 | : BVH_Triangulation<Standard_ShortReal, 3>(), |
207 | myArrayID (theArrayID) |
208 | { |
209 | myBuilder = new BVH_BinnedBuilder<Standard_ShortReal, 3 /* dim */, 48 /* bins */> |
210 | (5 /* leaf size */, 32 /* max height */, Standard_False, OSD_Parallel::NbLogicalProcessors() + 1 /* threads */); |
211 | } |
212 | |
e276548b |
213 | // ======================================================================= |
214 | // function : Clear |
265d4508 |
215 | // purpose : Clears ray-tracing geometry |
e276548b |
216 | // ======================================================================= |
265d4508 |
217 | void OpenGl_RaytraceGeometry::Clear() |
e276548b |
218 | { |
25ef750e |
219 | BVH_Geometry<Standard_ShortReal, 3>::BVH_Geometry::Clear(); |
e276548b |
220 | |
265d4508 |
221 | std::vector<OpenGl_RaytraceLight, |
222 | NCollection_StdAllocator<OpenGl_RaytraceLight> > anEmptySources; |
e276548b |
223 | |
265d4508 |
224 | Sources.swap (anEmptySources); |
e276548b |
225 | |
226 | std::vector<OpenGl_RaytraceMaterial, |
265d4508 |
227 | NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials; |
e276548b |
228 | |
229 | Materials.swap (anEmptyMaterials); |
230 | } |
231 | |
265d4508 |
232 | struct OpenGL_BVHParallelBuilder |
e276548b |
233 | { |
25ef750e |
234 | BVH_ObjectSet<Standard_ShortReal, 3>* Set; |
e276548b |
235 | |
25ef750e |
236 | OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 3>* theSet) |
65578e1c |
237 | : Set (theSet) |
e276548b |
238 | { |
265d4508 |
239 | // |
e276548b |
240 | } |
e276548b |
241 | |
c7b59798 |
242 | void operator() (const Standard_Integer theObjectIdx) const |
265d4508 |
243 | { |
c7b59798 |
244 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> ( |
245 | Set->Objects().ChangeValue (static_cast<Standard_Integer> (theObjectIdx)).operator->()); |
5322131b |
246 | |
c7b59798 |
247 | if (aTriangleSet != NULL) |
f2474958 |
248 | aTriangleSet->QuadBVH(); |
265d4508 |
249 | } |
250 | }; |
e276548b |
251 | |
e276548b |
252 | // ======================================================================= |
265d4508 |
253 | // function : ProcessAcceleration |
254 | // purpose : Performs post-processing of high-level BVH |
e276548b |
255 | // ======================================================================= |
265d4508 |
256 | Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration() |
e276548b |
257 | { |
25ef750e |
258 | #ifdef RAY_TRACE_PRINT_INFO |
47e9c178 |
259 | OSD_Timer aTimer; |
e276548b |
260 | #endif |
5322131b |
261 | |
265d4508 |
262 | MarkDirty(); // force BVH rebuilding |
e276548b |
263 | |
25ef750e |
264 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
265 | aTimer.Reset(); |
266 | aTimer.Start(); |
e276548b |
267 | #endif |
268 | |
f2474958 |
269 | OSD_Parallel::For (0, Size(), OpenGL_BVHParallelBuilder (this)); |
5322131b |
270 | |
f2474958 |
271 | myBotLevelTreeDepth = 1; |
fc73a202 |
272 | |
265d4508 |
273 | for (Standard_Integer anObjectIdx = 0; anObjectIdx < Size(); ++anObjectIdx) |
e276548b |
274 | { |
265d4508 |
275 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> ( |
276 | myObjects.ChangeValue (anObjectIdx).operator->()); |
277 | |
278 | Standard_ASSERT_RETURN (aTriangleSet != NULL, |
279 | "Error! Failed to get triangulation of OpenGL element", Standard_False); |
5322131b |
280 | |
f2474958 |
281 | Standard_ASSERT_RETURN (!aTriangleSet->QuadBVH().IsNull(), |
265d4508 |
282 | "Error! Failed to update bottom-level BVH of OpenGL element", Standard_False); |
fc73a202 |
283 | |
f2474958 |
284 | QuadBvhHandle aBVH = aTriangleSet->QuadBVH(); |
47e9c178 |
285 | |
286 | // correct data array of bottom-level BVH to set special flag for outer |
287 | // nodes in order to distinguish them from outer nodes of top-level BVH |
288 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx) |
289 | { |
290 | if (aBVH->IsOuter (aNodeIdx)) |
291 | { |
292 | aBVH->NodeInfoBuffer()[aNodeIdx].x() = -1; |
293 | } |
294 | } |
295 | |
f2474958 |
296 | myBotLevelTreeDepth = Max (myBotLevelTreeDepth, aTriangleSet->QuadBVH()->Depth()); |
e276548b |
297 | } |
298 | |
25ef750e |
299 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
300 | aTimer.Stop(); |
e276548b |
301 | |
265d4508 |
302 | std::cout << "Updating bottom-level BVHs (sec): " << |
303 | aTimer.ElapsedTime() << std::endl; |
304 | #endif |
e276548b |
305 | |
25ef750e |
306 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
307 | aTimer.Reset(); |
308 | aTimer.Start(); |
309 | #endif |
e276548b |
310 | |
f2474958 |
311 | QuadBvhHandle aBVH = QuadBVH(); |
312 | |
313 | Standard_ASSERT_RETURN (!aBVH.IsNull(), |
314 | "Error! Failed to update high-level BVH of ray-tracing scene", Standard_False); |
315 | |
316 | myTopLevelTreeDepth = aBVH->Depth(); |
e276548b |
317 | |
25ef750e |
318 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
319 | aTimer.Stop(); |
e276548b |
320 | |
265d4508 |
321 | std::cout << "Updating high-level BVH (sec): " << |
322 | aTimer.ElapsedTime() << std::endl; |
e276548b |
323 | #endif |
324 | |
265d4508 |
325 | Standard_Integer aVerticesOffset = 0; |
326 | Standard_Integer aElementsOffset = 0; |
f2474958 |
327 | Standard_Integer aBvhNodesOffset = QuadBVH()->Length(); |
e276548b |
328 | |
265d4508 |
329 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx) |
e276548b |
330 | { |
f2474958 |
331 | if (aBVH->IsOuter (aNodeIdx)) |
332 | { |
333 | Standard_ASSERT_RETURN (aBVH->BegPrimitive (aNodeIdx) == aBVH->EndPrimitive (aNodeIdx), |
334 | "Error! Invalid leaf node in high-level BVH (contains several objects)", Standard_False); |
e276548b |
335 | |
f2474958 |
336 | const Standard_Integer anObjectIdx = aBVH->BegPrimitive (aNodeIdx); |
e276548b |
337 | |
f2474958 |
338 | Standard_ASSERT_RETURN (anObjectIdx < myObjects.Size(), |
339 | "Error! Invalid leaf node in high-level BVH (contains out-of-range object)", Standard_False); |
e276548b |
340 | |
f2474958 |
341 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (myObjects (anObjectIdx).get()); |
e276548b |
342 | |
f2474958 |
343 | // Note: We overwrite node info record to store parameters |
344 | // of bottom-level BVH and triangulation of OpenGL element |
e276548b |
345 | |
f2474958 |
346 | aBVH->NodeInfoBuffer()[aNodeIdx] = BVH_Vec4i (anObjectIdx + 1, // to keep leaf flag |
347 | aBvhNodesOffset, |
348 | aVerticesOffset, |
349 | aElementsOffset); |
e276548b |
350 | |
f2474958 |
351 | aVerticesOffset += static_cast<Standard_Integer> (aTriangleSet->Vertices.size()); |
352 | aElementsOffset += static_cast<Standard_Integer> (aTriangleSet->Elements.size()); |
e276548b |
353 | |
f2474958 |
354 | aBvhNodesOffset += aTriangleSet->QuadBVH()->Length(); |
355 | } |
e276548b |
356 | } |
e276548b |
357 | |
265d4508 |
358 | return Standard_True; |
359 | } |
e276548b |
360 | |
f2474958 |
361 | // ======================================================================= |
362 | // function : QuadBVH |
363 | // purpose : Returns quad BVH (QBVH) tree produced from binary BVH |
364 | // ======================================================================= |
365 | const QuadBvhHandle& OpenGl_RaytraceGeometry::QuadBVH() |
366 | { |
367 | if (!myIsDirty) |
368 | { |
369 | Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH"); |
370 | } |
371 | else |
372 | { |
373 | myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it |
374 | |
375 | myBVH->Clear(); // erase binary BVH |
376 | } |
377 | |
378 | return myQuadBVH; |
379 | } |
380 | |
265d4508 |
381 | // ======================================================================= |
382 | // function : AccelerationOffset |
383 | // purpose : Returns offset of bottom-level BVH for given leaf node |
384 | // ======================================================================= |
385 | Standard_Integer OpenGl_RaytraceGeometry::AccelerationOffset (Standard_Integer theNodeIdx) |
386 | { |
f2474958 |
387 | const QuadBvhHandle& aBVH = QuadBVH(); |
e276548b |
388 | |
265d4508 |
389 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
390 | return INVALID_OFFSET; |
e276548b |
391 | |
265d4508 |
392 | return aBVH->NodeInfoBuffer().at (theNodeIdx).y(); |
e276548b |
393 | } |
394 | |
395 | // ======================================================================= |
265d4508 |
396 | // function : VerticesOffset |
397 | // purpose : Returns offset of triangulation vertices for given leaf node |
e276548b |
398 | // ======================================================================= |
265d4508 |
399 | Standard_Integer OpenGl_RaytraceGeometry::VerticesOffset (Standard_Integer theNodeIdx) |
e276548b |
400 | { |
f2474958 |
401 | const QuadBvhHandle& aBVH = QuadBVH(); |
e276548b |
402 | |
265d4508 |
403 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
404 | return INVALID_OFFSET; |
e276548b |
405 | |
265d4508 |
406 | return aBVH->NodeInfoBuffer().at (theNodeIdx).z(); |
407 | } |
e276548b |
408 | |
265d4508 |
409 | // ======================================================================= |
410 | // function : ElementsOffset |
411 | // purpose : Returns offset of triangulation elements for given leaf node |
412 | // ======================================================================= |
413 | Standard_Integer OpenGl_RaytraceGeometry::ElementsOffset (Standard_Integer theNodeIdx) |
414 | { |
f2474958 |
415 | const QuadBvhHandle& aBVH = QuadBVH(); |
e276548b |
416 | |
265d4508 |
417 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
418 | return INVALID_OFFSET; |
e276548b |
419 | |
265d4508 |
420 | return aBVH->NodeInfoBuffer().at (theNodeIdx).w(); |
e276548b |
421 | } |
422 | |
423 | // ======================================================================= |
265d4508 |
424 | // function : TriangleSet |
425 | // purpose : Returns triangulation data for given leaf node |
e276548b |
426 | // ======================================================================= |
265d4508 |
427 | OpenGl_TriangleSet* OpenGl_RaytraceGeometry::TriangleSet (Standard_Integer theNodeIdx) |
e276548b |
428 | { |
f2474958 |
429 | const QuadBvhHandle& aBVH = QuadBVH(); |
e276548b |
430 | |
265d4508 |
431 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
432 | return NULL; |
e276548b |
433 | |
265d4508 |
434 | if (aBVH->NodeInfoBuffer().at (theNodeIdx).x() > myObjects.Size()) |
435 | return NULL; |
5322131b |
436 | |
f2474958 |
437 | return dynamic_cast<OpenGl_TriangleSet*> ( |
438 | myObjects (aBVH->NodeInfoBuffer().at (theNodeIdx).x() - 1).get()); |
e276548b |
439 | } |
440 | |
25ef750e |
441 | // ======================================================================= |
442 | // function : AcquireTextures |
443 | // purpose : Makes the OpenGL texture handles resident |
444 | // ======================================================================= |
445 | Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext) const |
446 | { |
447 | if (theContext->arbTexBindless == NULL) |
448 | { |
449 | return Standard_True; |
450 | } |
451 | |
452 | #if !defined(GL_ES_VERSION_2_0) |
453 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
454 | { |
455 | theContext->arbTexBindless->glMakeTextureHandleResidentARB (myTextureHandles[anIdx]); |
456 | |
457 | if (glGetError() != GL_NO_ERROR) |
458 | { |
459 | #ifdef RAY_TRACE_PRINT_INFO |
460 | std::cout << "Error: Failed to make OpenGL texture resident" << std::endl; |
461 | #endif |
462 | return Standard_False; |
463 | } |
464 | } |
465 | #endif |
466 | |
467 | return Standard_True; |
468 | } |
469 | |
470 | // ======================================================================= |
471 | // function : ReleaseTextures |
472 | // purpose : Makes the OpenGL texture handles non-resident |
473 | // ======================================================================= |
474 | Standard_Boolean OpenGl_RaytraceGeometry::ReleaseTextures (const Handle(OpenGl_Context)& theContext) const |
475 | { |
476 | if (theContext->arbTexBindless == NULL) |
477 | { |
478 | return Standard_True; |
479 | } |
480 | |
481 | #if !defined(GL_ES_VERSION_2_0) |
482 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
483 | { |
484 | theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[anIdx]); |
485 | |
486 | if (glGetError() != GL_NO_ERROR) |
487 | { |
488 | #ifdef RAY_TRACE_PRINT_INFO |
489 | std::cout << "Error: Failed to make OpenGL texture non-resident" << std::endl; |
490 | #endif |
491 | return Standard_False; |
492 | } |
493 | } |
494 | #endif |
495 | |
496 | return Standard_True; |
497 | } |
498 | |
499 | // ======================================================================= |
500 | // function : AddTexture |
501 | // purpose : Adds new OpenGL texture to the scene and returns its index |
502 | // ======================================================================= |
503 | Standard_Integer OpenGl_RaytraceGeometry::AddTexture (const Handle(OpenGl_Texture)& theTexture) |
504 | { |
3a9b5dc8 |
505 | if (theTexture->TextureId() == OpenGl_Texture::NO_TEXTURE) |
506 | { |
507 | return -1; |
508 | } |
509 | |
25ef750e |
510 | NCollection_Vector<Handle (OpenGl_Texture)>::iterator anIter = |
511 | std::find (myTextures.begin(), myTextures.end(), theTexture); |
512 | |
513 | if (anIter == myTextures.end()) |
514 | { |
515 | if (myTextures.Size() >= MAX_TEX_NUMBER) |
516 | { |
517 | return -1; |
518 | } |
519 | |
520 | myTextures.Append (theTexture); |
521 | } |
522 | |
523 | return static_cast<Standard_Integer> (anIter - myTextures.begin()); |
524 | } |
525 | |
526 | // ======================================================================= |
527 | // function : UpdateTextureHandles |
528 | // purpose : Updates unique 64-bit texture handles to use in shaders |
529 | // ======================================================================= |
530 | Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(OpenGl_Context)& theContext) |
531 | { |
532 | if (theContext->arbTexBindless == NULL) |
533 | { |
534 | return Standard_False; |
535 | } |
536 | |
47e9c178 |
537 | if (myTextureSampler.IsNull()) |
538 | { |
539 | myTextureSampler = new OpenGl_Sampler(); |
540 | myTextureSampler->Init (*theContext.operator->()); |
541 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
542 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
543 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_S, GL_REPEAT); |
544 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_T, GL_REPEAT); |
545 | } |
546 | |
25ef750e |
547 | myTextureHandles.clear(); |
548 | |
549 | #if !defined(GL_ES_VERSION_2_0) |
550 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
551 | { |
47e9c178 |
552 | const GLuint64 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB ( |
553 | myTextures.Value (anIdx)->TextureId(), myTextureSampler->SamplerID()); |
25ef750e |
554 | |
555 | if (glGetError() != GL_NO_ERROR) |
556 | { |
557 | #ifdef RAY_TRACE_PRINT_INFO |
558 | std::cout << "Error: Failed to get 64-bit handle of OpenGL texture" << std::endl; |
559 | #endif |
560 | return Standard_False; |
561 | } |
562 | |
563 | myTextureHandles.push_back (aHandle); |
564 | } |
565 | #endif |
566 | |
567 | return Standard_True; |
568 | } |
569 | |
e276548b |
570 | namespace OpenGl_Raytrace |
571 | { |
572 | // ======================================================================= |
573 | // function : IsRaytracedElement |
574 | // purpose : Checks to see if the element contains ray-trace geometry |
575 | // ======================================================================= |
576 | Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode) |
577 | { |
25ef750e |
578 | OpenGl_PrimitiveArray* anArray = dynamic_cast<OpenGl_PrimitiveArray*> (theNode->elem); |
5322131b |
579 | return anArray != NULL |
871fa103 |
580 | && anArray->DrawMode() >= GL_TRIANGLES; |
e276548b |
581 | } |
582 | |
a89742cf |
583 | // ======================================================================= |
584 | // function : IsRaytracedElement |
585 | // purpose : Checks to see if the element contains ray-trace geometry |
586 | // ======================================================================= |
587 | Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement) |
588 | { |
589 | const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement); |
590 | return anArray != NULL |
591 | && anArray->DrawMode() >= GL_TRIANGLES; |
592 | } |
593 | |
e276548b |
594 | // ======================================================================= |
595 | // function : IsRaytracedGroup |
596 | // purpose : Checks to see if the group contains ray-trace geometry |
597 | // ======================================================================= |
d4aaad5b |
598 | Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup) |
e276548b |
599 | { |
d4aaad5b |
600 | for (const OpenGl_ElementNode* aNode = theGroup->FirstNode(); aNode != NULL; aNode = aNode->next) |
e276548b |
601 | { |
602 | if (IsRaytracedElement (aNode)) |
603 | { |
604 | return Standard_True; |
605 | } |
606 | } |
607 | return Standard_False; |
608 | } |
e276548b |
609 | } |