#include <OpenGl_Workspace.hxx>
-#include <NCollection_Mat4.hxx>
-#include <OpenGl_ArbFBO.hxx>
+#include <Graphic3d_TextureParams.hxx>
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_PrimitiveArray.hxx>
-#include <OpenGl_Texture.hxx>
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_View.hxx>
#include <OSD_File.hxx>
#include <OSD_Protection.hxx>
-#include <Standard_Assert.hxx>
using namespace OpenGl_Raytrace;
#include <OSD_Timer.hxx>
#endif
-// =======================================================================
-// function : MatVecMult
-// purpose : Multiples 4x4 matrix by 4D vector
-// =======================================================================
-template<typename T>
-BVH_Vec4f MatVecMult (const T m[16], const BVH_Vec4f& v)
-{
- return BVH_Vec4f (
- static_cast<float> (m[ 0] * v.x() + m[ 4] * v.y() +
- m[ 8] * v.z() + m[12] * v.w()),
- static_cast<float> (m[ 1] * v.x() + m[ 5] * v.y() +
- m[ 9] * v.z() + m[13] * v.w()),
- static_cast<float> (m[ 2] * v.x() + m[ 6] * v.y() +
- m[10] * v.z() + m[14] * v.w()),
- static_cast<float> (m[ 3] * v.x() + m[ 7] * v.y() +
- m[11] * v.z() + m[15] * v.w()));
-}
-
// =======================================================================
// function : UpdateRaytraceGeometry
// purpose : Updates 3D scene geometry for ray tracing
std::set<const OpenGl_Structure*> anElements;
// Set of all currently visible and "raytracable" primitive arrays.
- std::set<const OpenGl_PrimitiveArray*> anArrays;
+ std::set<Standard_Size> anArrayIDs;
const OpenGl_LayerList& aList = myView->LayerList();
for (OpenGl_SequenceOfLayers::Iterator anLayerIt (aList.Layers()); anLayerIt.More(); anLayerIt.Next())
{
- const OpenGl_PriorityList& aPriorityList = anLayerIt.Value().PriorityList();
-
- if (aPriorityList.NbStructures() == 0)
+ const OpenGl_Layer& aLayer = anLayerIt.Value();
+ if (aLayer.NbStructures() == 0)
continue;
- const OpenGl_ArrayOfStructure& aStructArray = aPriorityList.ArrayOfStructures();
-
+ const OpenGl_ArrayOfStructure& aStructArray = aLayer.ArrayOfStructures();
for (Standard_Integer anIndex = 0; anIndex < aStructArray.Length(); ++anIndex)
{
- OpenGl_SequenceOfStructure::Iterator aStructIt;
-
- for (aStructIt.Init (aStructArray (anIndex)); aStructIt.More(); aStructIt.Next())
+ for (OpenGl_SequenceOfStructure::Iterator aStructIt (aStructArray (anIndex)); aStructIt.More(); aStructIt.Next())
{
- Standard_ShortReal* aTransform (NULL);
-
const OpenGl_Structure* aStructure = aStructIt.Value();
if (theMode == OpenGl_GUM_CHECK)
{
return UpdateRaytraceGeometry (OpenGl_GUM_PREPARE);
}
- }
+ }
else if (theMode == OpenGl_GUM_PREPARE)
{
if (!aStructure->IsRaytracable()
|| !aStructure->IsVisible())
+ {
continue;
+ }
for (OpenGl_Structure::GroupIterator aGroupIter (aStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
{
if (aPrimArray != NULL)
{
// Collect all primitive arrays in scene.
- anArrays.insert (aPrimArray);
+ anArrayIDs.insert (aPrimArray->GetUID());
}
}
}
- }
+ }
else if (theMode == OpenGl_GUM_UPDATE)
{
if (!aStructure->IsRaytracable())
continue;
- if (aStructure->Transformation()->mat != NULL)
- {
- if (aTransform == NULL)
- aTransform = new Standard_ShortReal[16];
-
- for (Standard_Integer i = 0; i < 4; ++i)
- for (Standard_Integer j = 0; j < 4; ++j)
- {
- aTransform[j * 4 + i] = aStructure->Transformation()->mat[i][j];
- }
- }
-
- AddRaytraceStructure (aStructure, aTransform, anElements);
+ AddRaytraceStructure (aStructure, anElements);
}
-
- delete [] aTransform;
}
}
}
if (theMode == OpenGl_GUM_PREPARE)
{
- BVH_ObjectSet<Standard_ShortReal, 4>::BVH_ObjectList anUnchangedObjects;
+ BVH_ObjectSet<Standard_ShortReal, 3>::BVH_ObjectList anUnchangedObjects;
// Leave only unchanged objects in myRaytraceGeometry so only their transforms and materials will be updated
// Objects which not in myArrayToTrianglesMap will be built from scratch.
// If primitive array of object not in "anArrays" set then it was hided or deleted.
// If primitive array present in "anArrays" set but we don't have associated object yet, then
// the object is new and still has to be built.
- if ((aTriangleSet != NULL) && ((anArrays.find (aTriangleSet->AssociatedPArray())) != anArrays.end()))
+ if ((aTriangleSet != NULL) && ((anArrayIDs.find (aTriangleSet->AssociatedPArrayID())) != anArrayIDs.end()))
{
anUnchangedObjects.Append (myRaytraceGeometry.Objects().Value (anObjectIdx));
- myArrayToTrianglesMap[aTriangleSet->AssociatedPArray()] = aTriangleSet;
+ myArrayToTrianglesMap[aTriangleSet->AssociatedPArrayID()] = aTriangleSet;
}
}
myRaytraceSceneRadius = 2.f /* scale factor */ * Max (aMinRadius, aMaxRadius);
- const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
+ const BVH_Vec3f aSize = myRaytraceGeometry.Box().Size();
- myRaytraceSceneEpsilon = Max (1e-7f, 1e-4f * sqrtf (
+ myRaytraceSceneEpsilon = Max (1e-6f, 1e-4f * sqrtf (
aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
return UploadRaytraceData();
// =======================================================================
// function : CheckRaytraceStructure
-// purpose : Checks to see if the structure is modified
+// purpose : Checks to see if the structure is modified
// =======================================================================
Standard_Boolean OpenGl_Workspace::CheckRaytraceStructure (const OpenGl_Structure* theStructure)
{
return Standard_True;
}
+// =======================================================================
+// function : BuildTexTransform
+// purpose : Constructs texture transformation matrix
+// =======================================================================
+void BuildTexTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
+{
+ theMatrix.InitIdentity();
+
+ // Apply scaling
+ const Graphic3d_Vec2& aScale = theParams->Scale();
+
+ theMatrix.ChangeValue (0, 0) *= aScale.x();
+ theMatrix.ChangeValue (1, 0) *= aScale.x();
+ theMatrix.ChangeValue (2, 0) *= aScale.x();
+ theMatrix.ChangeValue (3, 0) *= aScale.x();
+
+ theMatrix.ChangeValue (0, 1) *= aScale.y();
+ theMatrix.ChangeValue (1, 1) *= aScale.y();
+ theMatrix.ChangeValue (2, 1) *= aScale.y();
+ theMatrix.ChangeValue (3, 1) *= aScale.y();
+
+ // Apply translation
+ const Graphic3d_Vec2 aTrans = -theParams->Translation();
+
+ theMatrix.ChangeValue (0, 3) = theMatrix.GetValue (0, 0) * aTrans.x() +
+ theMatrix.GetValue (0, 1) * aTrans.y();
+
+ theMatrix.ChangeValue (1, 3) = theMatrix.GetValue (1, 0) * aTrans.x() +
+ theMatrix.GetValue (1, 1) * aTrans.y();
+
+ theMatrix.ChangeValue (2, 3) = theMatrix.GetValue (2, 0) * aTrans.x() +
+ theMatrix.GetValue (2, 1) * aTrans.y();
+
+ // Apply rotation
+ const Standard_ShortReal aSin = std::sin (
+ -theParams->Rotation() * static_cast<Standard_ShortReal> (M_PI / 180.0));
+ const Standard_ShortReal aCos = std::cos (
+ -theParams->Rotation() * static_cast<Standard_ShortReal> (M_PI / 180.0));
+
+ BVH_Mat4f aRotationMat;
+ aRotationMat.SetValue (0, 0, aCos);
+ aRotationMat.SetValue (1, 1, aCos);
+ aRotationMat.SetValue (0, 1, -aSin);
+ aRotationMat.SetValue (1, 0, aSin);
+
+ theMatrix = theMatrix * aRotationMat;
+}
+
// =======================================================================
// function : CreateMaterial
// purpose : Creates ray-tracing material properties
// =======================================================================
-void CreateMaterial (const OPENGL_SURF_PROP& theProp, OpenGl_RaytraceMaterial& theMaterial)
+Standard_Boolean OpenGl_Workspace::CreateMaterial (const OpenGl_AspectFace* theAspect, OpenGl_RaytraceMaterial& theMaterial)
{
- const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
- theMaterial.Ambient = BVH_Vec4f (aSrcAmb[0] * theProp.amb,
- aSrcAmb[1] * theProp.amb,
- aSrcAmb[2] * theProp.amb,
- 1.0f);
-
- const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
- theMaterial.Diffuse = BVH_Vec4f (aSrcDif[0] * theProp.diff,
- aSrcDif[1] * theProp.diff,
- aSrcDif[2] * theProp.diff,
- 1.0f);
-
- const float aDefSpecCol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : aDefSpecCol;
- theMaterial.Specular = BVH_Vec4f (aSrcSpe[0] * theProp.spec,
- aSrcSpe[1] * theProp.spec,
- aSrcSpe[2] * theProp.spec,
- theProp.shine);
-
- const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
- theMaterial.Emission = BVH_Vec4f (aSrcEms[0] * theProp.emsv,
- aSrcEms[1] * theProp.emsv,
- aSrcEms[2] * theProp.emsv,
- 1.0f);
+ const OPENGL_SURF_PROP& aProperties = theAspect->IntFront();
+
+ const Standard_ShortReal* aSrcAmbient =
+ aProperties.isphysic ? aProperties.ambcol.rgb : aProperties.matcol.rgb;
+
+ theMaterial.Ambient = BVH_Vec4f (aSrcAmbient[0] * aProperties.amb,
+ aSrcAmbient[1] * aProperties.amb,
+ aSrcAmbient[2] * aProperties.amb,
+ 1.f);
+
+ const Standard_ShortReal* aSrcDiffuse =
+ aProperties.isphysic ? aProperties.difcol.rgb : aProperties.matcol.rgb;
+
+ theMaterial.Diffuse = BVH_Vec4f (aSrcDiffuse[0] * aProperties.diff,
+ aSrcDiffuse[1] * aProperties.diff,
+ aSrcDiffuse[2] * aProperties.diff,
+ -1.f /* no texture */);
+
+ theMaterial.Specular = BVH_Vec4f (
+ (aProperties.isphysic ? aProperties.speccol.rgb[0] : 1.f) * aProperties.spec,
+ (aProperties.isphysic ? aProperties.speccol.rgb[1] : 1.f) * aProperties.spec,
+ (aProperties.isphysic ? aProperties.speccol.rgb[2] : 1.f) * aProperties.spec,
+ aProperties.shine);
+
+ const Standard_ShortReal* aSrcEmission =
+ aProperties.isphysic ? aProperties.emscol.rgb : aProperties.matcol.rgb;
+
+ theMaterial.Emission = BVH_Vec4f (aSrcEmission[0] * aProperties.emsv,
+ aSrcEmission[1] * aProperties.emsv,
+ aSrcEmission[2] * aProperties.emsv,
+ 1.f);
// Note: Here we use sub-linear transparency function
// to produce realistic-looking transparency effect
- theMaterial.Transparency = BVH_Vec4f (powf (theProp.trans, 0.75f),
- 1.f - theProp.trans,
- theProp.index == 0 ? 1.f : theProp.index,
- theProp.index == 0 ? 1.f : 1.f / theProp.index);
+ theMaterial.Transparency = BVH_Vec4f (powf (aProperties.trans, 0.75f),
+ 1.f - aProperties.trans,
+ aProperties.index == 0 ? 1.f : aProperties.index,
+ aProperties.index == 0 ? 1.f : 1.f / aProperties.index);
+
+ const Standard_ShortReal aMaxRefl = Max (theMaterial.Diffuse.x() + theMaterial.Specular.x(),
+ Max (theMaterial.Diffuse.y() + theMaterial.Specular.y(),
+ theMaterial.Diffuse.z() + theMaterial.Specular.z()));
- const float aMaxRefl = Max (theMaterial.Diffuse.x() + theMaterial.Specular.x(),
- Max (theMaterial.Diffuse.y() + theMaterial.Specular.y(),
- theMaterial.Diffuse.z() + theMaterial.Specular.z()));
+ const Standard_ShortReal aReflectionScale = 0.75f / aMaxRefl;
- const float aReflectionScale = 0.75f / aMaxRefl;
+ theMaterial.Reflection = BVH_Vec4f (
+ aProperties.speccol.rgb[0] * aProperties.spec * aReflectionScale,
+ aProperties.speccol.rgb[1] * aProperties.spec * aReflectionScale,
+ aProperties.speccol.rgb[2] * aProperties.spec * aReflectionScale,
+ 0.f);
+
+ if (theAspect->DoTextureMap())
+ {
+ if (myGlContext->arbTexBindless != NULL)
+ {
+ BuildTexTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
+ theMaterial.Diffuse.w() = static_cast<Standard_ShortReal> (
+ myRaytraceGeometry.AddTexture (theAspect->TextureRes (myGlContext)));
+ }
+ else if (!myIsRaytraceWarnTextures)
+ {
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
+ "Warning: texturing in Ray-Trace requires GL_ARB_bindless_texture extension which is missing. "
+ "Textures will be ignored.");
+ myIsRaytraceWarnTextures = Standard_True;
+ }
+ }
- theMaterial.Reflection = BVH_Vec4f (theProp.speccol.rgb[0] * theProp.spec * aReflectionScale,
- theProp.speccol.rgb[1] * theProp.spec * aReflectionScale,
- theProp.speccol.rgb[2] * theProp.spec * aReflectionScale,
- 0.f);
+ return Standard_True;
}
// =======================================================================
// function : AddRaytraceStructure
// purpose : Adds OpenGL structure to ray-traced scene geometry
// =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure* theStructure,
- const Standard_ShortReal* theTransform, std::set<const OpenGl_Structure*>& theElements)
+Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure* theStructure, std::set<const OpenGl_Structure*>& theElements)
{
theElements.insert (theStructure);
aStructMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
OpenGl_RaytraceMaterial aStructMaterial;
- CreateMaterial (theStructure->AspectFace()->IntFront(), aStructMaterial);
+ CreateMaterial (theStructure->AspectFace(), aStructMaterial);
myRaytraceGeometry.Materials.push_back (aStructMaterial);
}
+ Standard_ShortReal aStructTransformArr[16];
+ Standard_ShortReal* aStructTransform = NULL;
+ if (theStructure->Transformation()->mat != NULL)
+ {
+ aStructTransform = aStructTransformArr;
+ for (Standard_Integer i = 0; i < 4; ++i)
+ {
+ for (Standard_Integer j = 0; j < 4; ++j)
+ {
+ aStructTransform[j * 4 + i] = theStructure->Transformation()->mat[i][j];
+ }
+ }
+ }
+
+ AddRaytraceGroups (theStructure, aStructMatID, aStructTransform);
+
+ // Process all connected OpenGL structures
+ for (OpenGl_ListOfStructure::Iterator anIts (theStructure->ConnectedStructures()); anIts.More(); anIts.Next())
+ {
+ if (anIts.Value()->IsRaytracable())
+ AddRaytraceGroups (anIts.Value(), aStructMatID, aStructTransform);
+ }
+
+ myStructureStates[theStructure] = theStructure->ModificationState();
+ return Standard_True;
+}
+
+// =======================================================================
+// function : AddRaytraceGroups
+// purpose : Adds OpenGL groups to ray-traced scene geometry
+// =======================================================================
+Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure* theStructure,
+ const Standard_Integer theStructMatId,
+ const Standard_ShortReal* theTransform)
+{
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
{
// Get group material
aGroupMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
OpenGl_RaytraceMaterial aGroupMaterial;
- CreateMaterial (aGroupIter.Value()->AspectFace()->IntFront(), aGroupMaterial);
+ CreateMaterial (aGroupIter.Value()->AspectFace(), aGroupMaterial);
myRaytraceGeometry.Materials.push_back (aGroupMaterial);
}
- Standard_Integer aMatID = aGroupMatID < 0 ? aStructMatID : aGroupMatID;
+ Standard_Integer aMatID = aGroupMatID < 0 ? theStructMatId : aGroupMatID;
if (aMatID < 0)
{
aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
OpenGl_RaytraceMaterial aMaterial;
- CreateMaterial (anAspect->IntFront(), aMaterial);
+ CreateMaterial (anAspect, aMaterial);
myRaytraceGeometry.Materials.push_back (aMaterial);
}
{
OpenGl_PrimitiveArray* aPrimArray = dynamic_cast<OpenGl_PrimitiveArray*> (aNode->elem);
- std::map<const OpenGl_PrimitiveArray*, OpenGl_TriangleSet*>::iterator aSetIter = myArrayToTrianglesMap.find (aPrimArray);
-
if (aPrimArray != NULL)
{
+ std::map<Standard_Size, OpenGl_TriangleSet*>::iterator aSetIter = myArrayToTrianglesMap.find (aPrimArray->GetUID());
+
if (aSetIter != myArrayToTrianglesMap.end())
{
OpenGl_TriangleSet* aSet = aSetIter->second;
-
+
BVH_Transform<Standard_ShortReal, 4>* aTransform = new BVH_Transform<Standard_ShortReal, 4>();
if (theTransform != NULL)
aSet->SetProperties (aTransform);
- if (aSet->MaterialIndex() != OpenGl_TriangleSet::INVALID_MATERIAL && aSet->MaterialIndex() != aMatID )
+ if (aSet->MaterialIndex() != OpenGl_TriangleSet::INVALID_MATERIAL && aSet->MaterialIndex() != aMatID)
{
aSet->SetMaterialIndex (aMatID);
}
}
else
{
- NCollection_Handle<BVH_Object<Standard_ShortReal, 4> > aSet =
+ NCollection_Handle<BVH_Object<Standard_ShortReal, 3> > aSet =
AddRaytracePrimitiveArray (aPrimArray, aMatID, 0);
if (!aSet.IsNull())
}
}
- Standard_ShortReal* aTransform = NULL;
-
- // Process all connected OpenGL structures
- for (OpenGl_ListOfStructure::Iterator anIts (theStructure->ConnectedStructures()); anIts.More(); anIts.Next())
- {
- if (anIts.Value()->Transformation()->mat != NULL)
- {
- if (aTransform == NULL)
- aTransform = new Standard_ShortReal[16];
-
- for (Standard_Integer i = 0; i < 4; ++i)
- for (Standard_Integer j = 0; j < 4; ++j)
- {
- aTransform[j * 4 + i] =
- anIts.Value()->Transformation()->mat[i][j];
- }
- }
-
- if (anIts.Value()->IsRaytracable())
- AddRaytraceStructure (anIts.Value(), aTransform != NULL ? aTransform : theTransform, theElements);
- }
-
- delete[] aTransform;
-
- myStructureStates[theStructure] = theStructure->ModificationState();
-
return Standard_True;
}
// =======================================================================
OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
Standard_Integer theMatID,
- const Standard_ShortReal* theTransform)
+ const OpenGl_Mat4* theTransform)
{
const Handle(Graphic3d_IndexBuffer)& anIndices = theArray->Indices();
const Handle(Graphic3d_Buffer)& anAttribs = theArray->Attributes();
const Handle(Graphic3d_BoundBuffer)& aBounds = theArray->Bounds();
if (theArray->DrawMode() < GL_TRIANGLES
+ #if !defined(GL_ES_VERSION_2_0)
|| theArray->DrawMode() > GL_POLYGON
+ #else
+ || theArray->DrawMode() > GL_TRIANGLE_FAN
+ #endif
|| anAttribs.IsNull())
{
return NULL;
#ifdef RAY_TRACE_PRINT_INFO
switch (theArray->DrawMode())
{
- case GL_POLYGON: std::cout << "\tAdding GL_POLYGON\n"; break;
case GL_TRIANGLES: std::cout << "\tAdding GL_TRIANGLES\n"; break;
- case GL_QUADS: std::cout << "\tAdding GL_QUADS\n"; break;
case GL_TRIANGLE_FAN: std::cout << "\tAdding GL_TRIANGLE_FAN\n"; break;
case GL_TRIANGLE_STRIP: std::cout << "\tAdding GL_TRIANGLE_STRIP\n"; break;
+ #if !defined(GL_ES_VERSION_2_0)
+ case GL_QUADS: std::cout << "\tAdding GL_QUADS\n"; break;
case GL_QUAD_STRIP: std::cout << "\tAdding GL_QUAD_STRIP\n"; break;
+ case GL_POLYGON: std::cout << "\tAdding GL_POLYGON\n"; break;
+ #endif
}
#endif
- OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray);
+ OpenGl_Mat4 aNormalMatrix;
+
+ if (theTransform != NULL)
+ {
+ Standard_ASSERT_RETURN (theTransform->Inverted (aNormalMatrix),
+ "Error: Failed to compute normal transformation matrix", NULL);
+
+ aNormalMatrix.Transpose();
+ }
+
+ OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray->GetUID());
{
aSet->Vertices.reserve (anAttribs->NbElements);
aSet->Normals .reserve (anAttribs->NbElements);
+ aSet->TexCrds .reserve (anAttribs->NbElements);
+
const size_t aVertFrom = aSet->Vertices.size();
for (Standard_Integer anAttribIter = 0; anAttribIter < anAttribs->NbAttributes; ++anAttribIter)
{
{
for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
{
- const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset);
- aSet->Vertices.push_back (BVH_Vec4f (aVert.x(), aVert.y(), aVert.z(), 1.0f));
+ aSet->Vertices.push_back (
+ *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset));
}
}
else if (anAttrib.DataType == Graphic3d_TOD_VEC2)
for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
{
const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(anAttribs->value (aVertIter) + anOffset);
- aSet->Vertices.push_back (BVH_Vec4f (aVert.x(), aVert.y(), 0.0f, 1.0f));
+ aSet->Vertices.push_back (BVH_Vec3f (aVert.x(), aVert.y(), 0.0f));
}
}
}
{
for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
{
- const Graphic3d_Vec3& aNorm = *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset);
- aSet->Normals.push_back (BVH_Vec4f (aNorm.x(), aNorm.y(), aNorm.z(), 0.0f));
+ aSet->Normals.push_back (
+ *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset));
+ }
+ }
+ }
+ else if (anAttrib.Id == Graphic3d_TOA_UV)
+ {
+ if (anAttrib.DataType == Graphic3d_TOD_VEC2)
+ {
+ for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
+ {
+ aSet->TexCrds.push_back (
+ *reinterpret_cast<const Graphic3d_Vec2* >(anAttribs->value (aVertIter) + anOffset));
}
}
}
{
for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
{
- aSet->Normals.push_back (BVH_Vec4f());
+ aSet->Normals.push_back (BVH_Vec3f());
+ }
+ }
+
+ if (aSet->TexCrds.size() != aSet->Vertices.size())
+ {
+ for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
+ {
+ aSet->TexCrds.push_back (BVH_Vec2f());
}
}
- if (theTransform)
+ if (theTransform != NULL)
{
for (size_t aVertIter = aVertFrom; aVertIter < aSet->Vertices.size(); ++aVertIter)
{
- BVH_Vec4f& aVertex = aSet->Vertices[aVertIter];
- aVertex = MatVecMult (theTransform, aVertex);
+ BVH_Vec3f& aVertex = aSet->Vertices[aVertIter];
+
+ BVH_Vec4f aTransVertex =
+ *theTransform * BVH_Vec4f (aVertex.x(), aVertex.y(), aVertex.z(), 1.f);
+
+ aVertex = BVH_Vec3f (aTransVertex.x(), aTransVertex.y(), aTransVertex.z());
}
for (size_t aVertIter = aVertFrom; aVertIter < aSet->Normals.size(); ++aVertIter)
{
- BVH_Vec4f& aNorm = aSet->Normals[aVertIter];
- aNorm = MatVecMult (theTransform, aNorm);
+ BVH_Vec3f& aNormal = aSet->Normals[aVertIter];
+
+ BVH_Vec4f aTransNormal =
+ aNormalMatrix * BVH_Vec4f (aNormal.x(), aNormal.y(), aNormal.z(), 0.f);
+
+ aNormal = BVH_Vec3f (aTransNormal.x(), aTransNormal.y(), aTransNormal.z());
}
}
if (!aBounds.IsNull())
{
- #ifdef RAY_TRACE_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
std::cout << "\tNumber of bounds = " << aBounds->NbBounds << std::endl;
- #endif
+#endif
Standard_Integer aBoundStart = 0;
for (Standard_Integer aBound = 0; aBound < aBounds->NbBounds; ++aBound)
{
const Standard_Integer aVertNum = aBounds->Bounds[aBound];
- #ifdef RAY_TRACE_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
std::cout << "\tAdding indices from bound " << aBound << ": " <<
aBoundStart << " .. " << aVertNum << std::endl;
- #endif
+#endif
if (!AddRaytraceVertexIndices (*aSet, *theArray, aBoundStart, aVertNum, theMatID))
{
switch (theArray.DrawMode())
{
case GL_TRIANGLES: return AddRaytraceTriangleArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
- case GL_QUADS: return AddRaytraceQuadrangleArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
case GL_TRIANGLE_FAN: return AddRaytraceTriangleFanArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
case GL_TRIANGLE_STRIP: return AddRaytraceTriangleStripArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+ #if !defined(GL_ES_VERSION_2_0)
+ case GL_QUADS: return AddRaytraceQuadrangleArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
case GL_QUAD_STRIP: return AddRaytraceQuadrangleStripArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
case GL_POLYGON: return AddRaytracePolygonArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+ #endif
}
return Standard_False;
}
// function : UpdateRaytraceLightSources
// purpose : Updates 3D scene light sources for ray-tracing
// =======================================================================
-Standard_Boolean OpenGl_Workspace::UpdateRaytraceLightSources (const GLdouble theInvModelView[16])
+Standard_Boolean OpenGl_Workspace::UpdateRaytraceLightSources (const OpenGl_Mat4& theInvModelView)
{
myRaytraceGeometry.Sources.clear();
}
if (aLight.IsHeadlight)
- aPosition = MatVecMult (theInvModelView, aPosition);
+ {
+ aPosition = theInvModelView * aPosition;
+ }
-
myRaytraceGeometry.Sources.push_back (OpenGl_RaytraceLight (aDiffuse, aPosition));
}
if (!aProgram.IsNull())
{
- aProgram->Bind (myGlContext);
+ myGlContext->BindProgram (aProgram);
if (!myView->TextureEnv().IsNull() && myView->SurfaceDetail() != Visual3d_TOD_NONE)
{
myGlContext, GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
aProgram->SetUniform (myGlContext,
- myUniformLocations[anIdx][OpenGl_RT_uEnvironmentEnable], 1);
+ myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 1);
}
else
{
aProgram->SetUniform (myGlContext,
- myUniformLocations[anIdx][OpenGl_RT_uEnvironmentEnable], 0);
+ myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 0);
}
}
}
- OpenGl_ShaderProgram::Unbind (myGlContext);
-
+ myGlContext->BindProgram (NULL);
myViewModificationStatus = myView->ModificationState();
-
return Standard_True;
}
return Standard_False;
}
+// =======================================================================
+// function : GenerateShaderPrefix
+// purpose : Generates shader prefix based on current ray-tracing options
+// =======================================================================
+TCollection_AsciiString OpenGl_Workspace::GenerateShaderPrefix()
+{
+ TCollection_AsciiString aPrefixString =
+ TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
+ TCollection_AsciiString ("#define NB_BOUNCES ") + TCollection_AsciiString (myRaytraceParameters.NbBounces);
+
+ if (myRaytraceParameters.TransparentShadows)
+ {
+ aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
+ }
+
+ // If OpenGL driver supports bindless textures
+ // activate texturing in ray-tracing mode
+ if (myGlContext->arbTexBindless != NULL)
+ {
+ aPrefixString += TCollection_AsciiString ("\n#define USE_TEXTURES") +
+ TCollection_AsciiString ("\n#define MAX_TEX_NUMBER ") + TCollection_AsciiString (OpenGl_RaytraceGeometry::MAX_TEX_NUMBER);
+ }
+
+ return aPrefixString;
+}
+
// =======================================================================
// function : InitRaytraceResources
// purpose : Initializes OpenGL/GLSL shader programs
}
}
- if (theCView.RenderParams.RaytracingDepth != myRaytraceParameters.TraceDepth)
+ if (theCView.RenderParams.RaytracingDepth != myRaytraceParameters.NbBounces)
{
- myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth;
+ myRaytraceParameters.NbBounces = theCView.RenderParams.RaytracingDepth;
aToRebuildShaders = Standard_True;
}
// Change state to force update all uniforms
++myViewModificationStatus;
- TCollection_AsciiString aPrefixString =
- TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
- TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth);
-
- if (myRaytraceParameters.TransparentShadows)
- {
- aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
- }
+ TCollection_AsciiString aPrefixString = GenerateShaderPrefix();
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
return Standard_False;
}
+ myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
+ myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
if (!myRaytraceProgram->Link (myGlContext)
|| !myPostFSAAProgram->Link (myGlContext))
{
{
if (!myGlContext->IsGlGreaterEqual (3, 1))
{
- const TCollection_ExtendedString aMessage = "Ray-tracing requires OpenGL 3.1 and higher";
-
myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMessage);
-
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
+ "Ray-tracing requires OpenGL 3.1 and higher");
+ return Standard_False;
+ }
+ else if (!myGlContext->arbTboRGB32)
+ {
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
+ "Ray-tracing requires OpenGL 4.0+ or GL_ARB_texture_buffer_object_rgb32 extension");
return Standard_False;
}
- myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth;
+ myRaytraceParameters.NbBounces = theCView.RenderParams.RaytracingDepth;
TCollection_AsciiString aFolder = Graphic3d_ShaderProgram::ShadersFolder();
myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth());
}
- TCollection_AsciiString aPrefixString =
- TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
- TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth);
-
- if (myRaytraceParameters.TransparentShadows)
- {
- aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
- }
+ TCollection_AsciiString aPrefixString = GenerateShaderPrefix();
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
return SafeFailBack ("Failed to attach ray-trace shader objects");
}
+ myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
if (!myRaytraceProgram->Link (myGlContext))
{
TCollection_AsciiString aLinkLog;
return SafeFailBack ("Failed to attach FSAA shader objects");
}
+ myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
if (!myPostFSAAProgram->Link (myGlContext))
{
TCollection_AsciiString aLinkLog;
Handle(OpenGl_ShaderProgram)& aShaderProgram =
(anIndex == 0) ? myRaytraceProgram : myPostFSAAProgram;
- aShaderProgram->Bind (myGlContext);
+ myGlContext->BindProgram (aShaderProgram);
aShaderProgram->SetSampler (myGlContext,
"uSceneMinPointTexture", OpenGl_RT_SceneMinPointTexture);
"uSceneMaxPointTexture", OpenGl_RT_SceneMaxPointTexture);
aShaderProgram->SetSampler (myGlContext,
"uSceneNodeInfoTexture", OpenGl_RT_SceneNodeInfoTexture);
- aShaderProgram->SetSampler (myGlContext,
- "uObjectMinPointTexture", OpenGl_RT_ObjectMinPointTexture);
- aShaderProgram->SetSampler (myGlContext,
- "uObjectMaxPointTexture", OpenGl_RT_ObjectMaxPointTexture);
- aShaderProgram->SetSampler (myGlContext,
- "uObjectNodeInfoTexture", OpenGl_RT_ObjectNodeInfoTexture);
aShaderProgram->SetSampler (myGlContext,
"uGeometryVertexTexture", OpenGl_RT_GeometryVertexTexture);
aShaderProgram->SetSampler (myGlContext,
"uGeometryNormalTexture", OpenGl_RT_GeometryNormalTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uGeometryTexCrdTexture", OpenGl_RT_GeometryTexCrdTexture);
aShaderProgram->SetSampler (myGlContext,
"uGeometryTriangTexture", OpenGl_RT_GeometryTriangTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uSceneTransformTexture", OpenGl_RT_SceneTransformTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
aShaderProgram->SetSampler (myGlContext,
"uRaytraceMaterialTexture", OpenGl_RT_RaytraceMaterialTexture);
aShaderProgram->SetSampler (myGlContext,
"uRaytraceLightSrcTexture", OpenGl_RT_RaytraceLightSrcTexture);
- aShaderProgram->SetSampler (myGlContext,
- "uSceneTransformTexture", OpenGl_RT_SceneTransformTexture);
+
aShaderProgram->SetSampler (myGlContext,
- "uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
+ "uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uOpenGlDepthTexture", OpenGl_RT_OpenGlDepthTexture);
if (anIndex == 1)
{
}
myUniformLocations[anIndex][OpenGl_RT_aPosition] =
- aShaderProgram->GetAttributeLocation (myGlContext, "aPosition");
+ aShaderProgram->GetAttributeLocation (myGlContext, "occVertex");
myUniformLocations[anIndex][OpenGl_RT_uOriginLB] =
aShaderProgram->GetUniformLocation (myGlContext, "uOriginLB");
aShaderProgram->GetUniformLocation (myGlContext, "uDirectLT");
myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
aShaderProgram->GetUniformLocation (myGlContext, "uDirectRT");
-
- myUniformLocations[anIndex][OpenGl_RT_uLightCount] =
- aShaderProgram->GetUniformLocation (myGlContext, "uLightCount");
- myUniformLocations[anIndex][OpenGl_RT_uLightAmbnt] =
- aShaderProgram->GetUniformLocation (myGlContext, "uGlobalAmbient");
+ myUniformLocations[anIndex][OpenGl_RT_uUnviewMat] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uUnviewMat");
myUniformLocations[anIndex][OpenGl_RT_uSceneRad] =
aShaderProgram->GetUniformLocation (myGlContext, "uSceneRadius");
myUniformLocations[anIndex][OpenGl_RT_uSceneEps] =
aShaderProgram->GetUniformLocation (myGlContext, "uSceneEpsilon");
-
- myUniformLocations[anIndex][OpenGl_RT_uShadEnabled] =
- aShaderProgram->GetUniformLocation (myGlContext, "uShadowsEnable");
- myUniformLocations[anIndex][OpenGl_RT_uReflEnabled] =
- aShaderProgram->GetUniformLocation (myGlContext, "uReflectionsEnable");
+ myUniformLocations[anIndex][OpenGl_RT_uLightCount] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uLightCount");
+ myUniformLocations[anIndex][OpenGl_RT_uLightAmbnt] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uGlobalAmbient");
myUniformLocations[anIndex][OpenGl_RT_uOffsetX] =
aShaderProgram->GetUniformLocation (myGlContext, "uOffsetX");
aShaderProgram->GetUniformLocation (myGlContext, "uOffsetY");
myUniformLocations[anIndex][OpenGl_RT_uSamples] =
aShaderProgram->GetUniformLocation (myGlContext, "uSamples");
+ myUniformLocations[anIndex][OpenGl_RT_uWinSizeX] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uWinSizeX");
+ myUniformLocations[anIndex][OpenGl_RT_uWinSizeY] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uWinSizeY");
+
+ myUniformLocations[anIndex][OpenGl_RT_uTextures] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uTextureSamplers");
- myUniformLocations[anIndex][OpenGl_RT_uEnvironmentEnable] =
+ myUniformLocations[anIndex][OpenGl_RT_uShadEnabled] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uShadowsEnable");
+ myUniformLocations[anIndex][OpenGl_RT_uReflEnabled] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uReflectionsEnable");
+ myUniformLocations[anIndex][OpenGl_RT_uEnvMapEnable] =
aShaderProgram->GetUniformLocation (myGlContext, "uEnvironmentEnable");
}
- OpenGl_ShaderProgram::Unbind (myGlContext);
+ myGlContext->BindProgram (NULL);
}
if (myComputeInitStatus != OpenGl_RT_NONE)
myRaytraceScreenQuad.Init (myGlContext, 3, 6, aVertices);
myComputeInitStatus = OpenGl_RT_INIT; // initialized in normal way
-
+
return Standard_True;
}
// =======================================================================
void OpenGl_Workspace::ReleaseRaytraceResources()
{
+ NullifyResource (myGlContext, myOpenGlFBO);
NullifyResource (myGlContext, myRaytraceFBO1);
NullifyResource (myGlContext, myRaytraceFBO2);
NullifyResource (myGlContext, mySceneMinPointTexture);
NullifyResource (myGlContext, mySceneMaxPointTexture);
- NullifyResource (myGlContext, myObjectNodeInfoTexture);
- NullifyResource (myGlContext, myObjectMinPointTexture);
- NullifyResource (myGlContext, myObjectMaxPointTexture);
-
NullifyResource (myGlContext, myGeometryVertexTexture);
NullifyResource (myGlContext, myGeometryNormalTexture);
+ NullifyResource (myGlContext, myGeometryTexCrdTexture);
NullifyResource (myGlContext, myGeometryTriangTexture);
NullifyResource (myGlContext, mySceneTransformTexture);
}
/////////////////////////////////////////////////////////////////////////////
- // Create OpenGL texture buffers
+ // Prepare OpenGL textures
- if (mySceneNodeInfoTexture.IsNull()) // create hight-level BVH buffers
+ if (myGlContext->arbTexBindless != NULL)
{
- mySceneNodeInfoTexture = new OpenGl_TextureBufferArb;
- mySceneMinPointTexture = new OpenGl_TextureBufferArb;
- mySceneMaxPointTexture = new OpenGl_TextureBufferArb;
- mySceneTransformTexture = new OpenGl_TextureBufferArb;
-
- if (!mySceneNodeInfoTexture->Create (myGlContext)
- || !mySceneMinPointTexture->Create (myGlContext)
- || !mySceneMaxPointTexture->Create (myGlContext)
- || !mySceneTransformTexture->Create (myGlContext))
+ // If OpenGL driver supports bindless textures we need
+ // to get unique 64- bit handles for using on the GPU
+ if (!myRaytraceGeometry.UpdateTextureHandles (myGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to create buffers for high-level scene BVH" << std::endl;
+ std::cout << "Error: Failed to get OpenGL texture handles" << std::endl;
#endif
return Standard_False;
}
}
- if (myObjectNodeInfoTexture.IsNull()) // create bottom-level BVH buffers
+ /////////////////////////////////////////////////////////////////////////////
+ // Create OpenGL BVH buffers
+
+ if (mySceneNodeInfoTexture.IsNull()) // create scene BVH buffers
{
- myObjectNodeInfoTexture = new OpenGl_TextureBufferArb;
- myObjectMinPointTexture = new OpenGl_TextureBufferArb;
- myObjectMaxPointTexture = new OpenGl_TextureBufferArb;
+ mySceneNodeInfoTexture = new OpenGl_TextureBufferArb;
+ mySceneMinPointTexture = new OpenGl_TextureBufferArb;
+ mySceneMaxPointTexture = new OpenGl_TextureBufferArb;
+ mySceneTransformTexture = new OpenGl_TextureBufferArb;
- if (!myObjectNodeInfoTexture->Create (myGlContext)
- || !myObjectMinPointTexture->Create (myGlContext)
- || !myObjectMaxPointTexture->Create (myGlContext))
+ if (!mySceneNodeInfoTexture->Create (myGlContext)
+ || !mySceneMinPointTexture->Create (myGlContext)
+ || !mySceneMaxPointTexture->Create (myGlContext)
+ || !mySceneTransformTexture->Create (myGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to create buffers for bottom-level scene BVH" << std::endl;
+ std::cout << "Error: Failed to create scene BVH buffers" << std::endl;
#endif
return Standard_False;
}
}
- if (myGeometryVertexTexture.IsNull()) // create geometry buffers
+ if (myGeometryVertexTexture.IsNull()) // create geometry buffers
{
myGeometryVertexTexture = new OpenGl_TextureBufferArb;
myGeometryNormalTexture = new OpenGl_TextureBufferArb;
+ myGeometryTexCrdTexture = new OpenGl_TextureBufferArb;
myGeometryTriangTexture = new OpenGl_TextureBufferArb;
if (!myGeometryVertexTexture->Create (myGlContext)
- || !myGeometryNormalTexture->Create (myGlContext)
- || !myGeometryTriangTexture->Create (myGlContext))
+ || !myGeometryNormalTexture->Create (myGlContext)
+ || !myGeometryTexCrdTexture->Create (myGlContext)
+ || !myGeometryTriangTexture->Create (myGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffers for triangulation data" << std::endl;
}
}
- if (myRaytraceMaterialTexture.IsNull()) // create material buffer
+ if (myRaytraceMaterialTexture.IsNull()) // create material buffer
{
myRaytraceMaterialTexture = new OpenGl_TextureBufferArb;
return Standard_False;
}
}
-
- /////////////////////////////////////////////////////////////////////////////
- // Write top-level BVH buffers
-
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = myRaytraceGeometry.BVH();
-
- bool aResult = true;
- if (!aBVH->NodeInfoBuffer().empty())
- {
- aResult &= mySceneNodeInfoTexture->Init (myGlContext, 4, GLsizei (aBVH->NodeInfoBuffer().size()),
- reinterpret_cast<const GLuint*> (&aBVH->NodeInfoBuffer().front()));
- aResult &= mySceneMinPointTexture->Init (myGlContext, 4, GLsizei (aBVH->MinPointBuffer().size()),
- reinterpret_cast<const GLfloat*> (&aBVH->MinPointBuffer().front()));
- aResult &= mySceneMaxPointTexture->Init (myGlContext, 4, GLsizei (aBVH->MaxPointBuffer().size()),
- reinterpret_cast<const GLfloat*> (&aBVH->MaxPointBuffer().front()));
- }
- if (!aResult)
- {
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to upload buffers for high-level scene BVH" << std::endl;
-#endif
- return Standard_False;
- }
-
+
/////////////////////////////////////////////////////////////////////////////
// Write transform buffer
BVH_Mat4f* aNodeTransforms = new BVH_Mat4f[myRaytraceGeometry.Size()];
- BVH_Mat4f anIdentity;
+
+ bool aResult = true;
for (Standard_Integer anElemIndex = 0; anElemIndex < myRaytraceGeometry.Size(); ++anElemIndex)
{
"OpenGl_TriangleSet does not contain transform", Standard_False);
aNodeTransforms[anElemIndex] = aTransform->Inversed();
-
}
aResult &= mySceneTransformTexture->Init (myGlContext, 4,
myRaytraceGeometry.Size() * 4, reinterpret_cast<const GLfloat*> (aNodeTransforms));
- delete[] aNodeTransforms;
+ delete [] aNodeTransforms;
/////////////////////////////////////////////////////////////////////////////
// Write geometry and bottom-level BVH buffers
aTotalBVHNodesNb += aTriangleSet->BVH()->NodeInfoBuffer().size();
}
+ aTotalBVHNodesNb += myRaytraceGeometry.BVH()->NodeInfoBuffer().size();
+
if (aTotalBVHNodesNb != 0)
{
- aResult &= myObjectNodeInfoTexture->Init (myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLuint*> (NULL));
- aResult &= myObjectMinPointTexture->Init (myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
- aResult &= myObjectMaxPointTexture->Init (myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= mySceneNodeInfoTexture->Init (
+ myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLuint*> (NULL));
+ aResult &= mySceneMinPointTexture->Init (
+ myGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= mySceneMaxPointTexture->Init (
+ myGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
}
if (!aResult)
if (aTotalElementsNb != 0)
{
- aResult &= myGeometryTriangTexture->Init (myGlContext, 4, GLsizei (aTotalElementsNb), static_cast<const GLuint*> (NULL));
+ aResult &= myGeometryTriangTexture->Init (
+ myGlContext, 4, GLsizei (aTotalElementsNb), static_cast<const GLuint*> (NULL));
}
if (aTotalVerticesNb != 0)
{
- aResult &= myGeometryVertexTexture->Init (myGlContext, 4, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
- aResult &= myGeometryNormalTexture->Init (myGlContext, 4, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= myGeometryVertexTexture->Init (
+ myGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= myGeometryNormalTexture->Init (
+ myGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= myGeometryTexCrdTexture->Init (
+ myGlContext, 2, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
}
if (!aResult)
return Standard_False;
}
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = myRaytraceGeometry.BVH();
+ const Standard_Integer aBvhLength = aBVH->Length();
+ if (aBvhLength > 0)
+ {
+ aResult &= mySceneNodeInfoTexture->SubData (myGlContext, 0, aBVH->Length(),
+ reinterpret_cast<const GLuint*> (&aBVH->NodeInfoBuffer().front()));
+ aResult &= mySceneMinPointTexture->SubData (myGlContext, 0, aBVH->Length(),
+ reinterpret_cast<const GLfloat*> (&aBVH->MinPointBuffer().front()));
+ aResult &= mySceneMaxPointTexture->SubData (myGlContext, 0, aBVH->Length(),
+ reinterpret_cast<const GLfloat*> (&aBVH->MaxPointBuffer().front()));
+ }
+
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx)
{
if (!aBVH->IsOuter (aNodeIdx))
Standard_ASSERT_RETURN (aTriangleSet != NULL,
"Error: Failed to get triangulation of OpenGL element", Standard_False);
- const Standard_Integer aBVHOffset = myRaytraceGeometry.AccelerationOffset (aNodeIdx);
+ Standard_Integer aBVHOffset = myRaytraceGeometry.AccelerationOffset (aNodeIdx);
Standard_ASSERT_RETURN (aBVHOffset != OpenGl_RaytraceGeometry::INVALID_OFFSET,
"Error: Failed to get offset for bottom-level BVH", Standard_False);
- const size_t aBVHBuffserSize = aTriangleSet->BVH()->NodeInfoBuffer().size();
+ const Standard_Integer aBvhBuffersSize = aTriangleSet->BVH()->Length();
- if (aBVHBuffserSize != 0)
+ if (aBvhBuffersSize != 0)
{
- aResult &= myObjectNodeInfoTexture->SubData (myGlContext, aBVHOffset, GLsizei (aBVHBuffserSize),
+ aResult &= mySceneNodeInfoTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
reinterpret_cast<const GLuint*> (&aTriangleSet->BVH()->NodeInfoBuffer().front()));
- aResult &= myObjectMinPointTexture->SubData (myGlContext, aBVHOffset, GLsizei (aBVHBuffserSize),
+ aResult &= mySceneMinPointTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MinPointBuffer().front()));
- aResult &= myObjectMaxPointTexture->SubData (myGlContext, aBVHOffset, GLsizei (aBVHBuffserSize),
+ aResult &= mySceneMaxPointTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MaxPointBuffer().front()));
if (!aResult)
{
{
aResult &= myGeometryNormalTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->Normals.size()),
reinterpret_cast<const GLfloat*> (&aTriangleSet->Normals.front()));
+ aResult &= myGeometryTexCrdTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->TexCrds.size()),
+ reinterpret_cast<const GLfloat*> (&aTriangleSet->TexCrds.front()));
aResult &= myGeometryVertexTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->Vertices.size()),
reinterpret_cast<const GLfloat*> (&aTriangleSet->Vertices.front()));
}
}
}
+ /////////////////////////////////////////////////////////////////////////////
+ // Write material buffer
+
if (myRaytraceGeometry.Materials.size() != 0)
{
- const GLfloat* aDataPtr = myRaytraceGeometry.Materials.front().Packed();
- aResult &= myRaytraceMaterialTexture->Init (myGlContext, 4, GLsizei (myRaytraceGeometry.Materials.size() * 7), aDataPtr);
+ aResult &= myRaytraceMaterialTexture->Init (myGlContext, 4,
+ GLsizei (myRaytraceGeometry.Materials.size() * 11), myRaytraceGeometry.Materials.front().Packed());
+
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
myRaytraceGeometry.Objects().ChangeValue (anElemIdx).operator->());
aMemUsed += static_cast<Standard_ShortReal> (
- aTriangleSet->Vertices.size() * sizeof (BVH_Vec4f));
+ aTriangleSet->Vertices.size() * sizeof (BVH_Vec3f));
+ aMemUsed += static_cast<Standard_ShortReal> (
+ aTriangleSet->Normals.size() * sizeof (BVH_Vec3f));
aMemUsed += static_cast<Standard_ShortReal> (
- aTriangleSet->Normals.size() * sizeof (BVH_Vec4f));
+ aTriangleSet->TexCrds.size() * sizeof (BVH_Vec2f));
aMemUsed += static_cast<Standard_ShortReal> (
aTriangleSet->Elements.size() * sizeof (BVH_Vec4i));
aMemUsed += static_cast<Standard_ShortReal> (
aTriangleSet->BVH()->NodeInfoBuffer().size() * sizeof (BVH_Vec4i));
aMemUsed += static_cast<Standard_ShortReal> (
- aTriangleSet->BVH()->MinPointBuffer().size() * sizeof (BVH_Vec4f));
+ aTriangleSet->BVH()->MinPointBuffer().size() * sizeof (BVH_Vec3f));
aMemUsed += static_cast<Standard_ShortReal> (
- aTriangleSet->BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec4f));
+ aTriangleSet->BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec3f));
}
aMemUsed += static_cast<Standard_ShortReal> (
myRaytraceGeometry.BVH()->NodeInfoBuffer().size() * sizeof (BVH_Vec4i));
aMemUsed += static_cast<Standard_ShortReal> (
- myRaytraceGeometry.BVH()->MinPointBuffer().size() * sizeof (BVH_Vec4f));
+ myRaytraceGeometry.BVH()->MinPointBuffer().size() * sizeof (BVH_Vec3f));
aMemUsed += static_cast<Standard_ShortReal> (
- myRaytraceGeometry.BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec4f));
+ myRaytraceGeometry.BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec3f));
std::cout << "GPU Memory Used (MB): ~" << aMemUsed / 1048576 << std::endl;
// function : UpdateCamera
// purpose : Generates viewing rays for corners of screen quad
// =======================================================================
-void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
- const NCollection_Mat4<GLdouble>& theViewMapping,
- OpenGl_Vec3 theOrigins[4],
- OpenGl_Vec3 theDirects[4])
+void OpenGl_Workspace::UpdateCamera (const OpenGl_Mat4& theOrientation,
+ const OpenGl_Mat4& theViewMapping,
+ OpenGl_Vec3 theOrigins[4],
+ OpenGl_Vec3 theDirects[4],
+ OpenGl_Mat4& theInvModelProj)
{
- NCollection_Mat4<GLdouble> aInvModelProj;
-
// compute inverse model-view-projection matrix
- (theViewMapping * theOrientation).Inverted (aInvModelProj);
+ (theViewMapping * theOrientation).Inverted (theInvModelProj);
Standard_Integer aOriginIndex = 0;
Standard_Integer aDirectIndex = 0;
{
for (Standard_Integer aX = -1; aX <= 1; aX += 2)
{
- OpenGl_Vec4d aOrigin (GLdouble(aX),
- GLdouble(aY),
- -1.0,
- 1.0);
+ OpenGl_Vec4 aOrigin (GLfloat(aX),
+ GLfloat(aY),
+ -1.0f,
+ 1.0f);
- aOrigin = aInvModelProj * aOrigin;
+ aOrigin = theInvModelProj * aOrigin;
aOrigin.x() = aOrigin.x() / aOrigin.w();
aOrigin.y() = aOrigin.y() / aOrigin.w();
aOrigin.z() = aOrigin.z() / aOrigin.w();
- OpenGl_Vec4d aDirect (GLdouble(aX),
- GLdouble(aY),
- 1.0,
- 1.0);
+ OpenGl_Vec4 aDirect (GLfloat(aX),
+ GLfloat(aY),
+ 1.0f,
+ 1.0f);
- aDirect = aInvModelProj * aDirect;
+ aDirect = theInvModelProj * aDirect;
aDirect.x() = aDirect.x() / aDirect.w();
aDirect.y() = aDirect.y() / aDirect.w();
}
}
+// =======================================================================
+// function : SetUniformState
+// purpose : Sets uniform state for the given ray-tracing shader program
+// =======================================================================
+Standard_Boolean OpenGl_Workspace::SetUniformState (const Graphic3d_CView& theCView,
+ const Standard_Integer theSizeX,
+ const Standard_Integer theSizeY,
+ const OpenGl_Vec3* theOrigins,
+ const OpenGl_Vec3* theDirects,
+ const OpenGl_Mat4& theUnviewMat,
+ const Standard_Integer theProgramIndex,
+ Handle(OpenGl_ShaderProgram)& theRaytraceProgram)
+{
+ if (theRaytraceProgram.IsNull())
+ {
+ return Standard_False;
+ }
+
+ Standard_Integer aLightSourceBufferSize =
+ static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
+
+ Standard_Boolean aResult = Standard_True;
+
+ // Set camera state
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uOriginLB], theOrigins[0]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uOriginRB], theOrigins[1]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uOriginLT], theOrigins[2]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uOriginRT], theOrigins[3]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uDirectLB], theDirects[0]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uDirectRB], theDirects[1]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uDirectLT], theDirects[2]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uDirectRT], theDirects[3]);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uUnviewMat], theUnviewMat);
+
+ // Set window size
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uWinSizeX], theSizeX);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uWinSizeY], theSizeY);
+
+ // Set scene parameters
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uLightCount], aLightSourceBufferSize);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
+
+ // Set rendering options
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
+ aResult &= theRaytraceProgram->SetUniform (myGlContext,
+ myUniformLocations[theProgramIndex][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
+
+ // Set array of 64-bit texture handles
+ if (myGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
+ {
+ aResult &= theRaytraceProgram->SetUniform (myGlContext, "uTextureSamplers",
+ static_cast<GLsizei> (myRaytraceGeometry.TextureHandles().size()), &myRaytraceGeometry.TextureHandles()[0]);
+ }
+
+ if (!aResult)
+ {
+#ifdef RAY_TRACE_PRINT_INFO
+ std::cout << "Info: Not all uniforms were detected (for program " << theProgramIndex << ")" << std::endl;
+#endif
+ }
+
+ return aResult;
+}
+
// =======================================================================
// function : RunRaytraceShaders
// purpose : Runs ray-tracing shader programs
const Standard_Integer theSizeY,
const OpenGl_Vec3 theOrigins[4],
const OpenGl_Vec3 theDirects[4],
+ const OpenGl_Mat4& theUnviewMat,
OpenGl_FrameBuffer* theFrameBuffer)
{
mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
mySceneMaxPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
mySceneNodeInfoTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
- myObjectMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
- myObjectMaxPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
- myObjectNodeInfoTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
myGeometryVertexTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
myGeometryNormalTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+ myGeometryTexCrdTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
myGeometryTriangTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myRaytraceMaterialTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
- mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+ myOpenGlFBO->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
{
glDisable (GL_BLEND);
}
- myRaytraceProgram->Bind (myGlContext);
-
- Standard_Integer aLightSourceBufferSize =
- static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
+ myGlContext->BindProgram (myRaytraceProgram);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uOriginLB], theOrigins[0]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uOriginRB], theOrigins[1]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uOriginLT], theOrigins[2]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uOriginRT], theOrigins[3]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uDirectLB], theDirects[0]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uDirectRB], theDirects[1]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uDirectLT], theDirects[2]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uDirectRT], theDirects[3]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uLightCount], aLightSourceBufferSize);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
-
- myGlContext->core20fwd->glEnableVertexAttribArray (
- myUniformLocations[0][OpenGl_RT_aPosition]);
- {
- myGlContext->core20fwd->glVertexAttribPointer (
- myUniformLocations[0][OpenGl_RT_aPosition], 3, GL_FLOAT, GL_FALSE, 0, NULL);
+ SetUniformState (theCView,
+ theSizeX,
+ theSizeY,
+ theOrigins,
+ theDirects,
+ theUnviewMat,
+ 0, // ID of RT program
+ myRaytraceProgram);
+ myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
+ {
+ myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
}
- myGlContext->core20fwd->glDisableVertexAttribArray (
- myUniformLocations[0][OpenGl_RT_aPosition]);
-
+ myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS);
+
if (!theCView.RenderParams.IsAntialiasingEnabled)
{
- myRaytraceProgram->Unbind (myGlContext);
+ myGlContext->BindProgram (NULL);
+
+ myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+ mySceneMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+ myGeometryVertexTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+ myGeometryTexCrdTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
+ myGeometryTriangTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+ myRaytraceMaterialTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+ myRaytraceLightSrcTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+
+ myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
return Standard_True;
}
myRaytraceFBO1->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
- myPostFSAAProgram->Bind (myGlContext);
-
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uOriginLB], theOrigins[0]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uOriginRB], theOrigins[1]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uOriginLT], theOrigins[2]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uOriginRT], theOrigins[3]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uDirectLB], theDirects[0]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uDirectRB], theDirects[1]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uDirectLT], theDirects[2]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uDirectRT], theDirects[3]);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uLightCount], aLightSourceBufferSize);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
- myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
-
- const Standard_ShortReal aMaxOffset = 0.559017f;
- const Standard_ShortReal aMinOffset = 0.186339f;
-
- myGlContext->core20fwd->glEnableVertexAttribArray (
- myUniformLocations[1][OpenGl_RT_aPosition]);
-
- myGlContext->core20fwd->glVertexAttribPointer (
- myUniformLocations[1][OpenGl_RT_aPosition], 3, GL_FLOAT, GL_FALSE, 0, NULL);
+ myGlContext->BindProgram (myPostFSAAProgram);
+
+ SetUniformState (theCView,
+ theSizeX,
+ theSizeY,
+ theOrigins,
+ theDirects,
+ theUnviewMat,
+ 1, // ID of FSAA program
+ myPostFSAAProgram);
- // Perform multi-pass adaptive FSAA using ping-pong technique
- // rotated grid AA always uses 4 samples
- for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
+ myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
+ myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+
+ // Perform multi-pass adaptive FSAA using ping-pong technique.
+ // We use 'FLIPTRI' sampling pattern changing for every pixel
+ // (3 additional samples per pixel, the 1st sample is already
+ // available from initial ray-traced image).
+ for (Standard_Integer anIt = 1; anIt < 4; ++anIt)
{
GLfloat aOffsetX = 1.f / theSizeX;
GLfloat aOffsetY = 1.f / theSizeY;
- if (anIt < 2)
+ if (anIt == 1)
{
- aOffsetX *= anIt < 1 ? aMinOffset : -aMaxOffset;
- aOffsetY *= anIt < 1 ? aMaxOffset : aMinOffset;
+ aOffsetX *= -0.55f;
+ aOffsetY *= 0.55f;
}
- else
+ else if (anIt == 2)
{
- aOffsetX *= anIt > 2 ? aMaxOffset : -aMinOffset;
- aOffsetY *= anIt > 2 ? -aMinOffset : -aMaxOffset;
+ aOffsetX *= 0.00f;
+ aOffsetY *= -0.55f;
}
-
+ else if (anIt == 3)
+ {
+ aOffsetX *= 0.55f;
+ aOffsetY *= 0.00f;
+ }
+
myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uSamples], anIt + 2);
+ myUniformLocations[1][OpenGl_RT_uSamples], anIt + 1);
myPostFSAAProgram->SetUniform (myGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetX], aOffsetX);
myPostFSAAProgram->SetUniform (myGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetY], aOffsetY);
- Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO1 : myRaytraceFBO2;
+ Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
if (anIt == 3) // disable FBO on last iteration
{
{
aFramebuffer->BindBuffer (myGlContext);
}
-
+
myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
if (anIt != 3) // set input for the next pass
}
}
- myGlContext->core20fwd->glDisableVertexAttribArray (
- myUniformLocations[1][OpenGl_RT_aPosition]);
+ myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS);
+
+ myGlContext->BindProgram (NULL);
+ myRaytraceFBO1->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+ myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+ mySceneMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+ myGeometryVertexTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+ myGeometryTexCrdTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
+ myGeometryTriangTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+ myRaytraceMaterialTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+ myRaytraceLightSrcTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
- myPostFSAAProgram->Unbind (myGlContext);
+ myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
return Standard_True;
}
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Standard_Boolean theToSwap,
+ const Aspect_CLayer2d& theCOverLayer,
+ const Aspect_CLayer2d& theCUnderLayer,
OpenGl_FrameBuffer* theFrameBuffer)
{
- if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK))
- return Standard_False;
-
if (!InitRaytraceResources (theCView))
return Standard_False;
return Standard_False;
// Get model-view and projection matrices
- TColStd_Array2OfReal theOrientation (0, 3, 0, 3);
- TColStd_Array2OfReal theViewMapping (0, 3, 0, 3);
-
- myView->GetMatrices (theOrientation, theViewMapping);
+ OpenGl_Mat4 aOrientationMatrix;
+ OpenGl_Mat4 aViewMappingMatrix;
- NCollection_Mat4<GLdouble> aOrientationMatrix;
- NCollection_Mat4<GLdouble> aViewMappingMatrix;
+ myView->GetMatrices (aOrientationMatrix,
+ aViewMappingMatrix);
- for (Standard_Integer j = 0; j < 4; ++j)
- {
- for (Standard_Integer i = 0; i < 4; ++i)
- {
- aOrientationMatrix [4 * j + i] = theOrientation (i, j);
- aViewMappingMatrix [4 * j + i] = theViewMapping (i, j);
- }
- }
-
- NCollection_Mat4<GLdouble> aInvOrientationMatrix;
+ OpenGl_Mat4 aInvOrientationMatrix;
aOrientationMatrix.Inverted (aInvOrientationMatrix);
if (!UpdateRaytraceLightSources (aInvOrientationMatrix))
OpenGl_Vec3 aOrigins[4];
OpenGl_Vec3 aDirects[4];
+ OpenGl_Mat4 anUnviewMat;
UpdateCamera (aOrientationMatrix,
aViewMappingMatrix,
aOrigins,
- aDirects);
+ aDirects,
+ anUnviewMat);
Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
glDisable (GL_DEPTH_TEST);
+ if (theFrameBuffer != NULL)
+ {
+ theFrameBuffer->BindBuffer (myGlContext);
+ }
+
if (NamedStatus & OPENGL_NS_WHITEBACK)
{
glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
glClear (GL_COLOR_BUFFER_BIT);
- if (theFrameBuffer != NULL)
- theFrameBuffer->BindBuffer (myGlContext);
+ myView->DrawBackground (this);
- myView->DrawBackground (*this);
+ myView->RedrawLayer2d (myPrintContext, this, theCView, theCUnderLayer);
- // Generate ray-traced image
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity();
+ myGlContext->WorldViewState.Push();
+ myGlContext->ProjectionState.Push();
+
+ myGlContext->WorldViewState.SetIdentity();
+ myGlContext->ProjectionState.SetIdentity();
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity();
+ myGlContext->ApplyProjectionMatrix();
+ myGlContext->ApplyWorldViewMatrix();
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_SRC_ALPHA);
+ // Generate ray-traced image
if (myIsRaytraceDataValid)
{
myRaytraceScreenQuad.Bind (myGlContext);
+ if (!myRaytraceGeometry.AcquireTextures (myGlContext))
+ {
+ const TCollection_ExtendedString aMessage = "Error: Failed to acquire OpenGL image textures";
+
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_MEDIUM_ARB, aMessage);
+ }
+
RunRaytraceShaders (theCView,
theSizeX,
theSizeY,
aOrigins,
aDirects,
+ anUnviewMat,
theFrameBuffer);
+ if (!myRaytraceGeometry.ReleaseTextures (myGlContext))
+ {
+ const TCollection_ExtendedString aMessage = "Error: Failed to release OpenGL image textures";
+
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_MEDIUM_ARB, aMessage);
+ }
+
myRaytraceScreenQuad.Unbind (myGlContext);
}
if (wasDepthTestEnabled)
glEnable (GL_DEPTH_TEST);
+ myGlContext->WorldViewState.Pop();
+ myGlContext->ProjectionState.Pop();
+
+ myGlContext->ApplyProjectionMatrix();
+
+ // Redraw trihedron
+ myView->RedrawTrihedron (this);
+
+ // Redraw overlay
+ const int aMode = 0;
+ DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
+ myView->RedrawLayer2d (myPrintContext, this, theCView, theCOverLayer);
+ DisplayCallback (theCView, aMode);
+
// Swap the buffers
if (theToSwap)
{
return Standard_True;
}
+
+IMPLEMENT_STANDARD_HANDLE(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+// =======================================================================
+// function : CanRender
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
+{
+ Standard_Boolean aPrevFilterResult = Standard_True;
+ if (!myPrevRenderFilter.IsNull())
+ {
+ aPrevFilterResult = myPrevRenderFilter->CanRender(theElement);
+ }
+ return aPrevFilterResult &&
+ !OpenGl_Raytrace::IsRaytracedElement (theElement);
+}