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