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 | |
50d0e1ce |
120 | // ======================================================================= |
121 | // function : Center |
122 | // purpose : Returns centroid position along the given axis |
123 | // ======================================================================= |
124 | Standard_ShortReal OpenGl_TriangleSet::Center ( |
125 | const Standard_Integer theIndex, const Standard_Integer theAxis) const |
126 | { |
127 | // Note: Experiments show that the use of the box centroid (instead |
128 | // of the triangle centroid) increases render performance up to 12% |
129 | |
130 | const BVH_Vec4i& aTriangle = Elements[theIndex]; |
131 | |
132 | const Standard_ShortReal aVertex0 = |
133 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.x()], theAxis); |
134 | const Standard_ShortReal aVertex1 = |
135 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.y()], theAxis); |
136 | const Standard_ShortReal aVertex2 = |
137 | BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.z()], theAxis); |
138 | |
139 | return (Min (Min (aVertex0, aVertex1), aVertex2) + |
140 | Max (Max (aVertex0, aVertex1), aVertex2)) * 0.5f; |
141 | } |
142 | |
25ef750e |
143 | // ======================================================================= |
144 | // function : Box |
145 | // purpose : Returns AABB of primitive set |
146 | // ======================================================================= |
147 | OpenGl_TriangleSet::BVH_BoxNt OpenGl_TriangleSet::Box() const |
148 | { |
149 | const BVH_Transform<Standard_ShortReal, 4>* aTransform = |
150 | dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->()); |
151 | |
152 | BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 3>::Box(); |
153 | |
154 | if (aTransform != NULL) |
155 | { |
156 | BVH_BoxNt aTransformedBox; |
157 | |
158 | for (Standard_Integer aX = 0; aX <= 1; ++aX) |
159 | { |
160 | for (Standard_Integer aY = 0; aY <= 1; ++aY) |
161 | { |
162 | for (Standard_Integer aZ = 0; aZ <= 1; ++aZ) |
163 | { |
164 | BVH_Vec4f aCorner = aTransform->Transform() * BVH_Vec4f ( |
165 | aX == 0 ? aBox.CornerMin().x() : aBox.CornerMax().x(), |
166 | aY == 0 ? aBox.CornerMin().y() : aBox.CornerMax().y(), |
167 | aZ == 0 ? aBox.CornerMin().z() : aBox.CornerMax().z(), |
168 | 1.f); |
169 | |
fe30607a |
170 | aTransformedBox.Add (aCorner.xyz()); |
25ef750e |
171 | } |
172 | } |
173 | } |
174 | |
175 | return aTransformedBox; |
176 | } |
177 | |
178 | return aBox; |
179 | } |
180 | |
65578e1c |
181 | // ======================================================================= |
182 | // function : OpenGl_TriangleSet |
183 | // purpose : Creates new OpenGL element triangulation |
184 | // ======================================================================= |
185 | OpenGl_TriangleSet::OpenGl_TriangleSet (const Standard_Size theArrayID) |
186 | : BVH_Triangulation<Standard_ShortReal, 3>(), |
187 | myArrayID (theArrayID) |
188 | { |
189 | myBuilder = new BVH_BinnedBuilder<Standard_ShortReal, 3 /* dim */, 48 /* bins */> |
190 | (5 /* leaf size */, 32 /* max height */, Standard_False, OSD_Parallel::NbLogicalProcessors() + 1 /* threads */); |
191 | } |
192 | |
e276548b |
193 | // ======================================================================= |
194 | // function : Clear |
265d4508 |
195 | // purpose : Clears ray-tracing geometry |
e276548b |
196 | // ======================================================================= |
265d4508 |
197 | void OpenGl_RaytraceGeometry::Clear() |
e276548b |
198 | { |
25ef750e |
199 | BVH_Geometry<Standard_ShortReal, 3>::BVH_Geometry::Clear(); |
e276548b |
200 | |
265d4508 |
201 | std::vector<OpenGl_RaytraceLight, |
202 | NCollection_StdAllocator<OpenGl_RaytraceLight> > anEmptySources; |
e276548b |
203 | |
265d4508 |
204 | Sources.swap (anEmptySources); |
e276548b |
205 | |
206 | std::vector<OpenGl_RaytraceMaterial, |
265d4508 |
207 | NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials; |
e276548b |
208 | |
209 | Materials.swap (anEmptyMaterials); |
210 | } |
211 | |
265d4508 |
212 | struct OpenGL_BVHParallelBuilder |
e276548b |
213 | { |
25ef750e |
214 | BVH_ObjectSet<Standard_ShortReal, 3>* Set; |
e276548b |
215 | |
25ef750e |
216 | OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 3>* theSet) |
65578e1c |
217 | : Set (theSet) |
e276548b |
218 | { |
265d4508 |
219 | // |
e276548b |
220 | } |
e276548b |
221 | |
c7b59798 |
222 | void operator() (const Standard_Integer theObjectIdx) const |
265d4508 |
223 | { |
c7b59798 |
224 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> ( |
225 | Set->Objects().ChangeValue (static_cast<Standard_Integer> (theObjectIdx)).operator->()); |
5322131b |
226 | |
c7b59798 |
227 | if (aTriangleSet != NULL) |
228 | aTriangleSet->BVH(); |
265d4508 |
229 | } |
230 | }; |
e276548b |
231 | |
e276548b |
232 | // ======================================================================= |
265d4508 |
233 | // function : ProcessAcceleration |
234 | // purpose : Performs post-processing of high-level BVH |
e276548b |
235 | // ======================================================================= |
265d4508 |
236 | Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration() |
e276548b |
237 | { |
25ef750e |
238 | #ifdef RAY_TRACE_PRINT_INFO |
47e9c178 |
239 | OSD_Timer aTimer; |
e276548b |
240 | #endif |
5322131b |
241 | |
265d4508 |
242 | MarkDirty(); // force BVH rebuilding |
e276548b |
243 | |
25ef750e |
244 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
245 | aTimer.Reset(); |
246 | aTimer.Start(); |
e276548b |
247 | #endif |
248 | |
c7b59798 |
249 | OSD_Parallel::For(0, Size(), OpenGL_BVHParallelBuilder(this)); |
5322131b |
250 | |
fc73a202 |
251 | myBottomLevelTreeDepth = 0; |
252 | |
265d4508 |
253 | for (Standard_Integer anObjectIdx = 0; anObjectIdx < Size(); ++anObjectIdx) |
e276548b |
254 | { |
265d4508 |
255 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> ( |
256 | myObjects.ChangeValue (anObjectIdx).operator->()); |
257 | |
258 | Standard_ASSERT_RETURN (aTriangleSet != NULL, |
259 | "Error! Failed to get triangulation of OpenGL element", Standard_False); |
5322131b |
260 | |
265d4508 |
261 | Standard_ASSERT_RETURN (!aTriangleSet->BVH().IsNull(), |
262 | "Error! Failed to update bottom-level BVH of OpenGL element", Standard_False); |
fc73a202 |
263 | |
47e9c178 |
264 | NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> > aBVH = aTriangleSet->BVH(); |
265 | |
266 | // correct data array of bottom-level BVH to set special flag for outer |
267 | // nodes in order to distinguish them from outer nodes of top-level BVH |
268 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx) |
269 | { |
270 | if (aBVH->IsOuter (aNodeIdx)) |
271 | { |
272 | aBVH->NodeInfoBuffer()[aNodeIdx].x() = -1; |
273 | } |
274 | } |
275 | |
fc73a202 |
276 | myBottomLevelTreeDepth = Max (myBottomLevelTreeDepth, aTriangleSet->BVH()->Depth()); |
e276548b |
277 | } |
278 | |
25ef750e |
279 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
280 | aTimer.Stop(); |
e276548b |
281 | |
265d4508 |
282 | std::cout << "Updating bottom-level BVHs (sec): " << |
283 | aTimer.ElapsedTime() << std::endl; |
284 | #endif |
e276548b |
285 | |
25ef750e |
286 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
287 | aTimer.Reset(); |
288 | aTimer.Start(); |
289 | #endif |
e276548b |
290 | |
25ef750e |
291 | NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> > aBVH = BVH(); |
e276548b |
292 | |
25ef750e |
293 | #ifdef RAY_TRACE_PRINT_INFO |
265d4508 |
294 | aTimer.Stop(); |
e276548b |
295 | |
265d4508 |
296 | std::cout << "Updating high-level BVH (sec): " << |
297 | aTimer.ElapsedTime() << std::endl; |
e276548b |
298 | #endif |
299 | |
265d4508 |
300 | Standard_ASSERT_RETURN (!aBVH.IsNull(), |
301 | "Error! Failed to update high-level BVH of ray-tracing scene", Standard_False); |
e276548b |
302 | |
fc73a202 |
303 | myHighLevelTreeDepth = aBVH->Depth(); |
304 | |
265d4508 |
305 | Standard_Integer aVerticesOffset = 0; |
306 | Standard_Integer aElementsOffset = 0; |
e2da917a |
307 | Standard_Integer aBVHNodesOffset = BVH()->Length(); |
e276548b |
308 | |
265d4508 |
309 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx) |
e276548b |
310 | { |
265d4508 |
311 | if (!aBVH->IsOuter (aNodeIdx)) |
e276548b |
312 | continue; |
313 | |
265d4508 |
314 | Standard_ASSERT_RETURN (aBVH->BegPrimitive (aNodeIdx) == aBVH->EndPrimitive (aNodeIdx), |
315 | "Error! Invalid leaf node in high-level BVH (contains several objects)", Standard_False); |
e276548b |
316 | |
265d4508 |
317 | Standard_Integer anObjectIdx = aBVH->BegPrimitive (aNodeIdx); |
e276548b |
318 | |
265d4508 |
319 | Standard_ASSERT_RETURN (anObjectIdx < myObjects.Size(), |
320 | "Error! Invalid leaf node in high-level BVH (contains out-of-range object)", Standard_False); |
e276548b |
321 | |
265d4508 |
322 | OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> ( |
323 | myObjects.ChangeValue (anObjectIdx).operator->()); |
e276548b |
324 | |
265d4508 |
325 | // Note: We overwrite node info record to store parameters |
326 | // of bottom-level BVH and triangulation of OpenGL element |
e276548b |
327 | |
265d4508 |
328 | aBVH->NodeInfoBuffer().at (aNodeIdx) = BVH_Vec4i ( |
329 | anObjectIdx + 1 /* to keep leaf flag */, aBVHNodesOffset, aVerticesOffset, aElementsOffset); |
e276548b |
330 | |
d5f74e42 |
331 | aVerticesOffset += (int)aTriangleSet->Vertices.size(); |
332 | aElementsOffset += (int)aTriangleSet->Elements.size(); |
265d4508 |
333 | aBVHNodesOffset += aTriangleSet->BVH()->Length(); |
e276548b |
334 | } |
e276548b |
335 | |
265d4508 |
336 | return Standard_True; |
337 | } |
e276548b |
338 | |
265d4508 |
339 | // ======================================================================= |
340 | // function : AccelerationOffset |
341 | // purpose : Returns offset of bottom-level BVH for given leaf node |
342 | // ======================================================================= |
343 | Standard_Integer OpenGl_RaytraceGeometry::AccelerationOffset (Standard_Integer theNodeIdx) |
344 | { |
25ef750e |
345 | const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH(); |
e276548b |
346 | |
265d4508 |
347 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
348 | return INVALID_OFFSET; |
e276548b |
349 | |
265d4508 |
350 | return aBVH->NodeInfoBuffer().at (theNodeIdx).y(); |
e276548b |
351 | } |
352 | |
353 | // ======================================================================= |
265d4508 |
354 | // function : VerticesOffset |
355 | // purpose : Returns offset of triangulation vertices for given leaf node |
e276548b |
356 | // ======================================================================= |
265d4508 |
357 | Standard_Integer OpenGl_RaytraceGeometry::VerticesOffset (Standard_Integer theNodeIdx) |
e276548b |
358 | { |
25ef750e |
359 | const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH(); |
e276548b |
360 | |
265d4508 |
361 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
362 | return INVALID_OFFSET; |
e276548b |
363 | |
265d4508 |
364 | return aBVH->NodeInfoBuffer().at (theNodeIdx).z(); |
365 | } |
e276548b |
366 | |
265d4508 |
367 | // ======================================================================= |
368 | // function : ElementsOffset |
369 | // purpose : Returns offset of triangulation elements for given leaf node |
370 | // ======================================================================= |
371 | Standard_Integer OpenGl_RaytraceGeometry::ElementsOffset (Standard_Integer theNodeIdx) |
372 | { |
25ef750e |
373 | const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH(); |
e276548b |
374 | |
265d4508 |
375 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
376 | return INVALID_OFFSET; |
e276548b |
377 | |
265d4508 |
378 | return aBVH->NodeInfoBuffer().at (theNodeIdx).w(); |
e276548b |
379 | } |
380 | |
381 | // ======================================================================= |
265d4508 |
382 | // function : TriangleSet |
383 | // purpose : Returns triangulation data for given leaf node |
e276548b |
384 | // ======================================================================= |
265d4508 |
385 | OpenGl_TriangleSet* OpenGl_RaytraceGeometry::TriangleSet (Standard_Integer theNodeIdx) |
e276548b |
386 | { |
25ef750e |
387 | const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH(); |
e276548b |
388 | |
265d4508 |
389 | if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx)) |
390 | return NULL; |
e276548b |
391 | |
265d4508 |
392 | if (aBVH->NodeInfoBuffer().at (theNodeIdx).x() > myObjects.Size()) |
393 | return NULL; |
5322131b |
394 | |
265d4508 |
395 | return dynamic_cast<OpenGl_TriangleSet*> (myObjects.ChangeValue ( |
396 | aBVH->NodeInfoBuffer().at (theNodeIdx).x() - 1).operator->()); |
e276548b |
397 | } |
398 | |
25ef750e |
399 | // ======================================================================= |
400 | // function : AcquireTextures |
401 | // purpose : Makes the OpenGL texture handles resident |
402 | // ======================================================================= |
403 | Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext) const |
404 | { |
405 | if (theContext->arbTexBindless == NULL) |
406 | { |
407 | return Standard_True; |
408 | } |
409 | |
410 | #if !defined(GL_ES_VERSION_2_0) |
411 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
412 | { |
413 | theContext->arbTexBindless->glMakeTextureHandleResidentARB (myTextureHandles[anIdx]); |
414 | |
415 | if (glGetError() != GL_NO_ERROR) |
416 | { |
417 | #ifdef RAY_TRACE_PRINT_INFO |
418 | std::cout << "Error: Failed to make OpenGL texture resident" << std::endl; |
419 | #endif |
420 | return Standard_False; |
421 | } |
422 | } |
423 | #endif |
424 | |
425 | return Standard_True; |
426 | } |
427 | |
428 | // ======================================================================= |
429 | // function : ReleaseTextures |
430 | // purpose : Makes the OpenGL texture handles non-resident |
431 | // ======================================================================= |
432 | Standard_Boolean OpenGl_RaytraceGeometry::ReleaseTextures (const Handle(OpenGl_Context)& theContext) const |
433 | { |
434 | if (theContext->arbTexBindless == NULL) |
435 | { |
436 | return Standard_True; |
437 | } |
438 | |
439 | #if !defined(GL_ES_VERSION_2_0) |
440 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
441 | { |
442 | theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[anIdx]); |
443 | |
444 | if (glGetError() != GL_NO_ERROR) |
445 | { |
446 | #ifdef RAY_TRACE_PRINT_INFO |
447 | std::cout << "Error: Failed to make OpenGL texture non-resident" << std::endl; |
448 | #endif |
449 | return Standard_False; |
450 | } |
451 | } |
452 | #endif |
453 | |
454 | return Standard_True; |
455 | } |
456 | |
457 | // ======================================================================= |
458 | // function : AddTexture |
459 | // purpose : Adds new OpenGL texture to the scene and returns its index |
460 | // ======================================================================= |
461 | Standard_Integer OpenGl_RaytraceGeometry::AddTexture (const Handle(OpenGl_Texture)& theTexture) |
462 | { |
463 | NCollection_Vector<Handle (OpenGl_Texture)>::iterator anIter = |
464 | std::find (myTextures.begin(), myTextures.end(), theTexture); |
465 | |
466 | if (anIter == myTextures.end()) |
467 | { |
468 | if (myTextures.Size() >= MAX_TEX_NUMBER) |
469 | { |
470 | return -1; |
471 | } |
472 | |
473 | myTextures.Append (theTexture); |
474 | } |
475 | |
476 | return static_cast<Standard_Integer> (anIter - myTextures.begin()); |
477 | } |
478 | |
479 | // ======================================================================= |
480 | // function : UpdateTextureHandles |
481 | // purpose : Updates unique 64-bit texture handles to use in shaders |
482 | // ======================================================================= |
483 | Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(OpenGl_Context)& theContext) |
484 | { |
485 | if (theContext->arbTexBindless == NULL) |
486 | { |
487 | return Standard_False; |
488 | } |
489 | |
47e9c178 |
490 | if (myTextureSampler.IsNull()) |
491 | { |
492 | myTextureSampler = new OpenGl_Sampler(); |
493 | myTextureSampler->Init (*theContext.operator->()); |
494 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
495 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
496 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_S, GL_REPEAT); |
497 | myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_T, GL_REPEAT); |
498 | } |
499 | |
25ef750e |
500 | myTextureHandles.clear(); |
501 | |
502 | #if !defined(GL_ES_VERSION_2_0) |
503 | for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx) |
504 | { |
47e9c178 |
505 | const GLuint64 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB ( |
506 | myTextures.Value (anIdx)->TextureId(), myTextureSampler->SamplerID()); |
25ef750e |
507 | |
508 | if (glGetError() != GL_NO_ERROR) |
509 | { |
510 | #ifdef RAY_TRACE_PRINT_INFO |
511 | std::cout << "Error: Failed to get 64-bit handle of OpenGL texture" << std::endl; |
512 | #endif |
513 | return Standard_False; |
514 | } |
515 | |
516 | myTextureHandles.push_back (aHandle); |
517 | } |
518 | #endif |
519 | |
520 | return Standard_True; |
521 | } |
522 | |
e276548b |
523 | namespace OpenGl_Raytrace |
524 | { |
525 | // ======================================================================= |
526 | // function : IsRaytracedElement |
527 | // purpose : Checks to see if the element contains ray-trace geometry |
528 | // ======================================================================= |
529 | Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode) |
530 | { |
25ef750e |
531 | OpenGl_PrimitiveArray* anArray = dynamic_cast<OpenGl_PrimitiveArray*> (theNode->elem); |
5322131b |
532 | return anArray != NULL |
871fa103 |
533 | && anArray->DrawMode() >= GL_TRIANGLES; |
e276548b |
534 | } |
535 | |
a89742cf |
536 | // ======================================================================= |
537 | // function : IsRaytracedElement |
538 | // purpose : Checks to see if the element contains ray-trace geometry |
539 | // ======================================================================= |
540 | Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement) |
541 | { |
542 | const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement); |
543 | return anArray != NULL |
544 | && anArray->DrawMode() >= GL_TRIANGLES; |
545 | } |
546 | |
e276548b |
547 | // ======================================================================= |
548 | // function : IsRaytracedGroup |
549 | // purpose : Checks to see if the group contains ray-trace geometry |
550 | // ======================================================================= |
d4aaad5b |
551 | Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup) |
e276548b |
552 | { |
d4aaad5b |
553 | for (const OpenGl_ElementNode* aNode = theGroup->FirstNode(); aNode != NULL; aNode = aNode->next) |
e276548b |
554 | { |
555 | if (IsRaytracedElement (aNode)) |
556 | { |
557 | return Standard_True; |
558 | } |
559 | } |
560 | return Standard_False; |
561 | } |
562 | |
563 | // ======================================================================= |
564 | // function : IsRaytracedStructure |
565 | // purpose : Checks to see if the structure contains ray-trace geometry |
566 | // ======================================================================= |
b64d84be |
567 | Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure) |
e276548b |
568 | { |
d4aaad5b |
569 | for (OpenGl_Structure::GroupIterator anIter (theStructure->DrawGroups()); anIter.More(); anIter.Next()) |
e276548b |
570 | { |
d4aaad5b |
571 | if (anIter.Value()->IsRaytracable()) |
572 | { |
e276548b |
573 | return Standard_True; |
d4aaad5b |
574 | } |
e276548b |
575 | } |
576 | return Standard_False; |
577 | } |
578 | } |