0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[occt.git] / src / OpenGl / OpenGl_SceneGeometry.cxx
CommitLineData
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 28namespace
29{
e276548b 30 //! Useful constant for null floating-point 4D vector.
265d4508 31 static const BVH_Vec4f ZERO_VEC_4F;
25ef750e 32}
e276548b 33
f5b72419 34IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TriangleSet, OpenGl_BVHTriangulation3f)
35
e276548b 36// =======================================================================
64c759f8 37// function : OpenGl_RaytraceMaterial
e276548b 38// purpose : Creates new default material
39// =======================================================================
40OpenGl_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 54OpenGl_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 72OpenGl_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 92OpenGl_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// =======================================================================
992ed6b3 111// function : OpenGl_RaytraceLight
e276548b 112// purpose : Creates new light source
113// =======================================================================
6e728f3b 114OpenGl_RaytraceLight::OpenGl_RaytraceLight (const BVH_Vec4f& theEmission,
265d4508 115 const BVH_Vec4f& thePosition)
6e728f3b 116: Emission (theEmission),
e276548b 117 Position (thePosition)
118{
119 //
120}
121
122// =======================================================================
f2474958 123// function : QuadBVH
124// purpose : Returns quad BVH (QBVH) tree produced from binary BVH
125// =======================================================================
126const QuadBvhHandle& OpenGl_TriangleSet::QuadBVH()
127{
128 if (!myIsDirty)
129 {
130 Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH");
131 }
132 else
133 {
134 myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it
135
136 myBVH->Clear(); // erase binary BVH
137 }
138
139 return myQuadBVH;
140}
141
142// =======================================================================
50d0e1ce 143// function : Center
144// purpose : Returns centroid position along the given axis
145// =======================================================================
146Standard_ShortReal OpenGl_TriangleSet::Center (
147 const Standard_Integer theIndex, const Standard_Integer theAxis) const
148{
149 // Note: Experiments show that the use of the box centroid (instead
150 // of the triangle centroid) increases render performance up to 12%
151
152 const BVH_Vec4i& aTriangle = Elements[theIndex];
153
154 const Standard_ShortReal aVertex0 =
155 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.x()], theAxis);
156 const Standard_ShortReal aVertex1 =
157 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.y()], theAxis);
158 const Standard_ShortReal aVertex2 =
159 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.z()], theAxis);
160
161 return (Min (Min (aVertex0, aVertex1), aVertex2) +
162 Max (Max (aVertex0, aVertex1), aVertex2)) * 0.5f;
163}
164
165// =======================================================================
25ef750e 166// function : Box
167// purpose : Returns AABB of primitive set
168// =======================================================================
169OpenGl_TriangleSet::BVH_BoxNt OpenGl_TriangleSet::Box() const
170{
25ef750e 171 BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 3>::Box();
f5b72419 172 const BVH_Transform<Standard_ShortReal, 4>* aTransform = dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().get());
173 if (aTransform == NULL)
25ef750e 174 {
f5b72419 175 return aBox;
176 }
25ef750e 177
f5b72419 178 BVH_BoxNt aTransformedBox;
179 for (Standard_Integer aX = 0; aX <= 1; ++aX)
180 {
181 for (Standard_Integer aY = 0; aY <= 1; ++aY)
25ef750e 182 {
f5b72419 183 for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
25ef750e 184 {
f5b72419 185 BVH_Vec4f aCorner = aTransform->Transform() * BVH_Vec4f (
186 aX == 0 ? aBox.CornerMin().x() : aBox.CornerMax().x(),
187 aY == 0 ? aBox.CornerMin().y() : aBox.CornerMax().y(),
188 aZ == 0 ? aBox.CornerMin().z() : aBox.CornerMax().z(),
189 1.f);
190
191 aTransformedBox.Add (aCorner.xyz());
25ef750e 192 }
193 }
25ef750e 194 }
f5b72419 195 return aTransformedBox;
25ef750e 196}
197
198// =======================================================================
65578e1c 199// function : OpenGl_TriangleSet
200// purpose : Creates new OpenGL element triangulation
201// =======================================================================
f5b72419 202OpenGl_TriangleSet::OpenGl_TriangleSet (const Standard_Size theArrayID,
203 const opencascade::handle<BVH_Builder<Standard_ShortReal, 3> >& theBuilder)
204: BVH_Triangulation<Standard_ShortReal, 3> (theBuilder),
65578e1c 205 myArrayID (theArrayID)
206{
f5b72419 207 //
65578e1c 208}
209
210// =======================================================================
e276548b 211// function : Clear
265d4508 212// purpose : Clears ray-tracing geometry
e276548b 213// =======================================================================
265d4508 214void OpenGl_RaytraceGeometry::Clear()
e276548b 215{
25ef750e 216 BVH_Geometry<Standard_ShortReal, 3>::BVH_Geometry::Clear();
e276548b 217
265d4508 218 std::vector<OpenGl_RaytraceLight,
219 NCollection_StdAllocator<OpenGl_RaytraceLight> > anEmptySources;
e276548b 220
265d4508 221 Sources.swap (anEmptySources);
e276548b 222
223 std::vector<OpenGl_RaytraceMaterial,
265d4508 224 NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials;
e276548b 225
226 Materials.swap (anEmptyMaterials);
227}
228
265d4508 229struct OpenGL_BVHParallelBuilder
e276548b 230{
25ef750e 231 BVH_ObjectSet<Standard_ShortReal, 3>* Set;
e276548b 232
25ef750e 233 OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 3>* theSet)
65578e1c 234 : Set (theSet)
e276548b 235 {
265d4508 236 //
e276548b 237 }
e276548b 238
c7b59798 239 void operator() (const Standard_Integer theObjectIdx) const
265d4508 240 {
c7b59798 241 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
242 Set->Objects().ChangeValue (static_cast<Standard_Integer> (theObjectIdx)).operator->());
5322131b 243
c7b59798 244 if (aTriangleSet != NULL)
f2474958 245 aTriangleSet->QuadBVH();
265d4508 246 }
247};
e276548b 248
e276548b 249// =======================================================================
265d4508 250// function : ProcessAcceleration
251// purpose : Performs post-processing of high-level BVH
e276548b 252// =======================================================================
265d4508 253Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration()
e276548b 254{
25ef750e 255#ifdef RAY_TRACE_PRINT_INFO
47e9c178 256 OSD_Timer aTimer;
e276548b 257#endif
5322131b 258
265d4508 259 MarkDirty(); // force BVH rebuilding
e276548b 260
25ef750e 261#ifdef RAY_TRACE_PRINT_INFO
265d4508 262 aTimer.Reset();
263 aTimer.Start();
e276548b 264#endif
265
f2474958 266 OSD_Parallel::For (0, Size(), OpenGL_BVHParallelBuilder (this));
5322131b 267
f2474958 268 myBotLevelTreeDepth = 1;
fc73a202 269
265d4508 270 for (Standard_Integer anObjectIdx = 0; anObjectIdx < Size(); ++anObjectIdx)
e276548b 271 {
265d4508 272 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
273 myObjects.ChangeValue (anObjectIdx).operator->());
274
275 Standard_ASSERT_RETURN (aTriangleSet != NULL,
276 "Error! Failed to get triangulation of OpenGL element", Standard_False);
5322131b 277
f2474958 278 Standard_ASSERT_RETURN (!aTriangleSet->QuadBVH().IsNull(),
265d4508 279 "Error! Failed to update bottom-level BVH of OpenGL element", Standard_False);
fc73a202 280
f2474958 281 QuadBvhHandle aBVH = aTriangleSet->QuadBVH();
47e9c178 282
283 // correct data array of bottom-level BVH to set special flag for outer
284 // nodes in order to distinguish them from outer nodes of top-level BVH
285 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx)
286 {
287 if (aBVH->IsOuter (aNodeIdx))
288 {
289 aBVH->NodeInfoBuffer()[aNodeIdx].x() = -1;
290 }
291 }
292
f2474958 293 myBotLevelTreeDepth = Max (myBotLevelTreeDepth, aTriangleSet->QuadBVH()->Depth());
e276548b 294 }
295
25ef750e 296#ifdef RAY_TRACE_PRINT_INFO
265d4508 297 aTimer.Stop();
e276548b 298
265d4508 299 std::cout << "Updating bottom-level BVHs (sec): " <<
300 aTimer.ElapsedTime() << std::endl;
301#endif
e276548b 302
25ef750e 303#ifdef RAY_TRACE_PRINT_INFO
265d4508 304 aTimer.Reset();
305 aTimer.Start();
306#endif
e276548b 307
f2474958 308 QuadBvhHandle aBVH = QuadBVH();
309
310 Standard_ASSERT_RETURN (!aBVH.IsNull(),
311 "Error! Failed to update high-level BVH of ray-tracing scene", Standard_False);
312
313 myTopLevelTreeDepth = aBVH->Depth();
e276548b 314
25ef750e 315#ifdef RAY_TRACE_PRINT_INFO
265d4508 316 aTimer.Stop();
e276548b 317
265d4508 318 std::cout << "Updating high-level BVH (sec): " <<
319 aTimer.ElapsedTime() << std::endl;
e276548b 320#endif
321
265d4508 322 Standard_Integer aVerticesOffset = 0;
323 Standard_Integer aElementsOffset = 0;
f2474958 324 Standard_Integer aBvhNodesOffset = QuadBVH()->Length();
e276548b 325
265d4508 326 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx)
e276548b 327 {
f2474958 328 if (aBVH->IsOuter (aNodeIdx))
329 {
330 Standard_ASSERT_RETURN (aBVH->BegPrimitive (aNodeIdx) == aBVH->EndPrimitive (aNodeIdx),
331 "Error! Invalid leaf node in high-level BVH (contains several objects)", Standard_False);
e276548b 332
f2474958 333 const Standard_Integer anObjectIdx = aBVH->BegPrimitive (aNodeIdx);
e276548b 334
f2474958 335 Standard_ASSERT_RETURN (anObjectIdx < myObjects.Size(),
336 "Error! Invalid leaf node in high-level BVH (contains out-of-range object)", Standard_False);
e276548b 337
f2474958 338 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (myObjects (anObjectIdx).get());
e276548b 339
f2474958 340 // Note: We overwrite node info record to store parameters
341 // of bottom-level BVH and triangulation of OpenGL element
e276548b 342
f2474958 343 aBVH->NodeInfoBuffer()[aNodeIdx] = BVH_Vec4i (anObjectIdx + 1, // to keep leaf flag
344 aBvhNodesOffset,
345 aVerticesOffset,
346 aElementsOffset);
e276548b 347
f2474958 348 aVerticesOffset += static_cast<Standard_Integer> (aTriangleSet->Vertices.size());
349 aElementsOffset += static_cast<Standard_Integer> (aTriangleSet->Elements.size());
e276548b 350
f2474958 351 aBvhNodesOffset += aTriangleSet->QuadBVH()->Length();
352 }
e276548b 353 }
e276548b 354
265d4508 355 return Standard_True;
356}
e276548b 357
265d4508 358// =======================================================================
f2474958 359// function : QuadBVH
360// purpose : Returns quad BVH (QBVH) tree produced from binary BVH
361// =======================================================================
362const QuadBvhHandle& OpenGl_RaytraceGeometry::QuadBVH()
363{
364 if (!myIsDirty)
365 {
366 Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH");
367 }
368 else
369 {
370 myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it
371
372 myBVH->Clear(); // erase binary BVH
373 }
374
375 return myQuadBVH;
376}
377
378// =======================================================================
265d4508 379// function : AccelerationOffset
380// purpose : Returns offset of bottom-level BVH for given leaf node
381// =======================================================================
382Standard_Integer OpenGl_RaytraceGeometry::AccelerationOffset (Standard_Integer theNodeIdx)
383{
f2474958 384 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 385
265d4508 386 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
387 return INVALID_OFFSET;
e276548b 388
265d4508 389 return aBVH->NodeInfoBuffer().at (theNodeIdx).y();
e276548b 390}
391
392// =======================================================================
265d4508 393// function : VerticesOffset
394// purpose : Returns offset of triangulation vertices for given leaf node
e276548b 395// =======================================================================
265d4508 396Standard_Integer OpenGl_RaytraceGeometry::VerticesOffset (Standard_Integer theNodeIdx)
e276548b 397{
f2474958 398 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 399
265d4508 400 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
401 return INVALID_OFFSET;
e276548b 402
265d4508 403 return aBVH->NodeInfoBuffer().at (theNodeIdx).z();
404}
e276548b 405
265d4508 406// =======================================================================
407// function : ElementsOffset
408// purpose : Returns offset of triangulation elements for given leaf node
409// =======================================================================
410Standard_Integer OpenGl_RaytraceGeometry::ElementsOffset (Standard_Integer theNodeIdx)
411{
f2474958 412 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 413
265d4508 414 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
415 return INVALID_OFFSET;
e276548b 416
265d4508 417 return aBVH->NodeInfoBuffer().at (theNodeIdx).w();
e276548b 418}
419
420// =======================================================================
265d4508 421// function : TriangleSet
422// purpose : Returns triangulation data for given leaf node
e276548b 423// =======================================================================
265d4508 424OpenGl_TriangleSet* OpenGl_RaytraceGeometry::TriangleSet (Standard_Integer theNodeIdx)
e276548b 425{
f2474958 426 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 427
265d4508 428 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
429 return NULL;
e276548b 430
265d4508 431 if (aBVH->NodeInfoBuffer().at (theNodeIdx).x() > myObjects.Size())
432 return NULL;
5322131b 433
f2474958 434 return dynamic_cast<OpenGl_TriangleSet*> (
435 myObjects (aBVH->NodeInfoBuffer().at (theNodeIdx).x() - 1).get());
e276548b 436}
437
25ef750e 438// =======================================================================
439// function : AcquireTextures
440// purpose : Makes the OpenGL texture handles resident
441// =======================================================================
cc8cbabe 442Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext)
25ef750e 443{
444 if (theContext->arbTexBindless == NULL)
445 {
446 return Standard_True;
447 }
448
449#if !defined(GL_ES_VERSION_2_0)
cc8cbabe 450 Standard_Integer aTexIter = 0;
451 for (NCollection_Vector<Handle(OpenGl_Texture)>::Iterator aTexSrcIter (myTextures); aTexSrcIter.More(); aTexSrcIter.Next(), ++aTexIter)
25ef750e 452 {
cc8cbabe 453 GLuint64& aHandle = myTextureHandles[aTexIter];
454 const Handle(OpenGl_Texture)& aTexture = aTexSrcIter.Value();
455 if (!aTexture->Sampler()->IsValid()
456 || !aTexture->Sampler()->IsImmutable())
457 {
458 // need to recreate texture sampler handle
459 aHandle = GLuint64(-1); // specs do not define value for invalid handle, set -1 to initialize something
460 if (!aTexture->InitSamplerObject (theContext))
461 {
462 continue;
463 }
25ef750e 464
cc8cbabe 465 aTexture->Sampler()->SetImmutable();
466 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (aTexture->TextureId(), aTexture->Sampler()->SamplerID());
467 const GLenum anErr = glGetError();
468 if (anErr != GL_NO_ERROR)
469 {
470 theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
471 TCollection_AsciiString ("Error: Failed to get 64-bit handle of OpenGL texture #") + int(anErr));
472 myTextureHandles.clear();
473 return Standard_False;
474 }
475 }
476
477 theContext->arbTexBindless->glMakeTextureHandleResidentARB (aHandle);
478 const GLenum anErr = glGetError();
479 if (anErr != GL_NO_ERROR)
25ef750e 480 {
cc8cbabe 481 theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
482 TCollection_AsciiString ("Error: Failed to make OpenGL texture resident #") + int(anErr));
25ef750e 483 return Standard_False;
484 }
485 }
486#endif
487
488 return Standard_True;
489}
490
491// =======================================================================
492// function : ReleaseTextures
493// purpose : Makes the OpenGL texture handles non-resident
494// =======================================================================
495Standard_Boolean OpenGl_RaytraceGeometry::ReleaseTextures (const Handle(OpenGl_Context)& theContext) const
496{
497 if (theContext->arbTexBindless == NULL)
498 {
499 return Standard_True;
500 }
501
502#if !defined(GL_ES_VERSION_2_0)
cc8cbabe 503 for (size_t aTexIter = 0; aTexIter < myTextureHandles.size(); ++aTexIter)
25ef750e 504 {
cc8cbabe 505 theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[aTexIter]);
506 const GLenum anErr = glGetError();
507 if (anErr != GL_NO_ERROR)
25ef750e 508 {
cc8cbabe 509 theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
510 TCollection_AsciiString("Error: Failed to make OpenGL texture non-resident #") + int(anErr));
25ef750e 511 return Standard_False;
512 }
513 }
514#endif
515
516 return Standard_True;
517}
518
519// =======================================================================
520// function : AddTexture
521// purpose : Adds new OpenGL texture to the scene and returns its index
522// =======================================================================
523Standard_Integer OpenGl_RaytraceGeometry::AddTexture (const Handle(OpenGl_Texture)& theTexture)
524{
3a9b5dc8 525 if (theTexture->TextureId() == OpenGl_Texture::NO_TEXTURE)
526 {
527 return -1;
528 }
529
25ef750e 530 NCollection_Vector<Handle (OpenGl_Texture)>::iterator anIter =
531 std::find (myTextures.begin(), myTextures.end(), theTexture);
532
533 if (anIter == myTextures.end())
534 {
535 if (myTextures.Size() >= MAX_TEX_NUMBER)
536 {
537 return -1;
538 }
539
540 myTextures.Append (theTexture);
541 }
542
543 return static_cast<Standard_Integer> (anIter - myTextures.begin());
544}
545
546// =======================================================================
547// function : UpdateTextureHandles
548// purpose : Updates unique 64-bit texture handles to use in shaders
549// =======================================================================
550Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(OpenGl_Context)& theContext)
551{
552 if (theContext->arbTexBindless == NULL)
553 {
554 return Standard_False;
555 }
556
557 myTextureHandles.clear();
cc8cbabe 558 myTextureHandles.resize (myTextures.Size());
25ef750e 559
560#if !defined(GL_ES_VERSION_2_0)
cc8cbabe 561 Standard_Integer aTexIter = 0;
562 for (NCollection_Vector<Handle(OpenGl_Texture)>::Iterator aTexSrcIter (myTextures); aTexSrcIter.More(); aTexSrcIter.Next(), ++aTexIter)
25ef750e 563 {
cc8cbabe 564 GLuint64& aHandle = myTextureHandles[aTexIter];
565 aHandle = GLuint64(-1); // specs do not define value for invalid handle, set -1 to initialize something
25ef750e 566
cc8cbabe 567 const Handle(OpenGl_Texture)& aTexture = aTexSrcIter.Value();
568 if (!aTexture->Sampler()->IsValid()
569 && !aTexture->InitSamplerObject (theContext))
25ef750e 570 {
cc8cbabe 571 continue;
25ef750e 572 }
573
cc8cbabe 574 aTexture->Sampler()->SetImmutable();
575 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (aTexture->TextureId(), aTexture->Sampler()->SamplerID());
576 const GLenum anErr = glGetError();
577 if (anErr != GL_NO_ERROR)
578 {
579 theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
580 TCollection_AsciiString ("Error: Failed to get 64-bit handle of OpenGL texture #") + int(anErr));
581 myTextureHandles.clear();
582 return Standard_False;
583 }
25ef750e 584 }
585#endif
586
587 return Standard_True;
588}
589
e276548b 590namespace OpenGl_Raytrace
591{
592 // =======================================================================
593 // function : IsRaytracedElement
594 // purpose : Checks to see if the element contains ray-trace geometry
595 // =======================================================================
596 Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode)
597 {
25ef750e 598 OpenGl_PrimitiveArray* anArray = dynamic_cast<OpenGl_PrimitiveArray*> (theNode->elem);
5322131b 599 return anArray != NULL
871fa103 600 && anArray->DrawMode() >= GL_TRIANGLES;
e276548b 601 }
602
603 // =======================================================================
a89742cf 604 // function : IsRaytracedElement
605 // purpose : Checks to see if the element contains ray-trace geometry
606 // =======================================================================
607 Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement)
608 {
609 const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
610 return anArray != NULL
611 && anArray->DrawMode() >= GL_TRIANGLES;
612 }
613
614 // =======================================================================
e276548b 615 // function : IsRaytracedGroup
616 // purpose : Checks to see if the group contains ray-trace geometry
617 // =======================================================================
d4aaad5b 618 Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup)
e276548b 619 {
d4aaad5b 620 for (const OpenGl_ElementNode* aNode = theGroup->FirstNode(); aNode != NULL; aNode = aNode->next)
e276548b 621 {
622 if (IsRaytracedElement (aNode))
623 {
624 return Standard_True;
625 }
626 }
627 return Standard_False;
628 }
e276548b 629}