Fix bug with overlay OpenGL text.
OpenGl_BVHTreeSelector.cxx
OpenGl_BVHClipPrimitiveSet.cxx
OpenGl_BVHClipPrimitiveSet.hxx
+OpenGl_ArbTexBindless.hxx
+Handle_OpenGl_Sampler.hxx
+OpenGl_Sampler.hxx
+OpenGl_Sampler.cxx
--- /dev/null
+// Created on: 2014-10-17
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Handle_OpenGl_Sampler_HeaderFile
+#define _Handle_OpenGl_Sampler_HeaderFile
+
+#include <OpenGl_Resource.hxx>
+
+class OpenGl_Sampler;
+DEFINE_STANDARD_HANDLE(OpenGl_Sampler, OpenGl_Resource)
+
+#endif
--- /dev/null
+// Created on: 2014-10-07
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_ArbTexBindless_H__
+#define _OpenGl_ArbTexBindless_H__
+
+#include <OpenGl_GlFunctions.hxx>
+
+//! Provides bindless textures.
+//! This extension allows OpenGL applications to access texture objects in
+//! shaders without first binding each texture to one of a limited number of
+//! texture image units.
+struct OpenGl_ArbTexBindless : protected OpenGl_GlFunctions
+{
+#if !defined(GL_ES_VERSION_2_0)
+ using OpenGl_GlFunctions::glGetTextureHandleARB;
+ using OpenGl_GlFunctions::glGetTextureSamplerHandleARB;
+ using OpenGl_GlFunctions::glMakeTextureHandleResidentARB;
+ using OpenGl_GlFunctions::glMakeTextureHandleNonResidentARB;
+ using OpenGl_GlFunctions::glGetImageHandleARB;
+ using OpenGl_GlFunctions::glMakeImageHandleResidentARB;
+ using OpenGl_GlFunctions::glMakeImageHandleNonResidentARB;
+ using OpenGl_GlFunctions::glUniformHandleui64ARB;
+ using OpenGl_GlFunctions::glUniformHandleui64vARB;
+ using OpenGl_GlFunctions::glProgramUniformHandleui64ARB;
+ using OpenGl_GlFunctions::glProgramUniformHandleui64vARB;
+ using OpenGl_GlFunctions::glIsTextureHandleResidentARB;
+ using OpenGl_GlFunctions::glIsImageHandleResidentARB;
+ using OpenGl_GlFunctions::glVertexAttribL1ui64ARB;
+ using OpenGl_GlFunctions::glVertexAttribL1ui64vARB;
+ using OpenGl_GlFunctions::glGetVertexAttribLui64vARB;
+#endif
+};
+
+#endif // _OpenGl_ArbTexBindless_H__
#include <OpenGl_ArbDbg.hxx>
#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_ExtGS.hxx>
+#include <OpenGl_ArbTexBindless.hxx>
#include <OpenGl_GlCore20.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <Message_Messenger.hxx>
core20fwd (NULL),
core32 (NULL),
core32back (NULL),
+ core33 (NULL),
+ core33back (NULL),
core41 (NULL),
core41back (NULL),
core42 (NULL),
hasHighp (Standard_True),
hasTexRGBA8(Standard_True),
#endif
- arbNPTW(Standard_False),
+ arbNPTW (Standard_False),
+ arbTexRG (Standard_False),
+ arbTexBindless (NULL),
arbTBO (NULL),
+ arbTboRGB32 (Standard_False),
arbIns (NULL),
arbDbg (NULL),
arbFBO (NULL),
mySharedResources.Nullify();
myDelayed.Nullify();
+ // release sampler object
+ if (!myTexSampler.IsNull())
+ {
+ myTexSampler->Release (this);
+ }
+
#if !defined(GL_ES_VERSION_2_0)
if (arbDbg != NULL
&& caps->contextDebug
core20fwd = NULL;
core32 = NULL;
core32back = NULL;
+ core33 = NULL;
+ core33back = NULL;
core41 = NULL;
core41back = NULL;
core42 = NULL;
core44 = NULL;
core44back = NULL;
arbTBO = NULL;
+ arbTboRGB32 = Standard_False;
arbIns = NULL;
arbDbg = NULL;
arbFBO = NULL;
{
arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
}
+ arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
// initialize hardware instancing extension (ARB)
if (!has31
extGS = (OpenGl_ExtGS* )(&(*myFuncs));
}
+ // initialize bindless texture extension (ARB)
+ if (CheckExtension ("GL_ARB_bindless_texture")
+ && FindProcShort (glGetTextureHandleARB)
+ && FindProcShort (glGetTextureSamplerHandleARB)
+ && FindProcShort (glMakeTextureHandleResidentARB)
+ && FindProcShort (glMakeTextureHandleNonResidentARB)
+ && FindProcShort (glGetImageHandleARB)
+ && FindProcShort (glMakeImageHandleResidentARB)
+ && FindProcShort (glMakeImageHandleNonResidentARB)
+ && FindProcShort (glUniformHandleui64ARB)
+ && FindProcShort (glUniformHandleui64vARB)
+ && FindProcShort (glProgramUniformHandleui64ARB)
+ && FindProcShort (glProgramUniformHandleui64vARB)
+ && FindProcShort (glIsTextureHandleResidentARB)
+ && FindProcShort (glIsImageHandleResidentARB)
+ && FindProcShort (glVertexAttribL1ui64ARB)
+ && FindProcShort (glVertexAttribL1ui64vARB)
+ && FindProcShort (glGetVertexAttribLui64vARB))
+ {
+ arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
+ }
+
if (!has12)
{
myGlVerMajor = 1;
myGlVerMinor = 2;
return;
}
+ core33 = (OpenGl_GlCore33* )(&(*myFuncs));
+ core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
+
+ // initialize sampler object
+ myTexSampler = new OpenGl_Sampler();
+ myTexSampler->Init (*this);
if (!has40)
{
myGlVerMinor = 3;
return;
}
+ arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
if (!has41)
{
#include <Aspect_Display.hxx>
#include <Aspect_RenderingContext.hxx>
#include <Handle_OpenGl_Context.hxx>
+#include <Handle_OpenGl_Sampler.hxx>
#include <Handle_OpenGl_ShaderManager.hxx>
#include <Handle_OpenGl_ShaderProgram.hxx>
#include <NCollection_DataMap.hxx>
struct OpenGl_ArbDbg;
struct OpenGl_ArbFBO;
struct OpenGl_ExtGS;
+struct OpenGl_ArbTexBindless;
template<typename theBaseClass_t> struct OpenGl_TmplCore12;
typedef OpenGl_TmplCore12<OpenGl_GlCore11> OpenGl_GlCore12;
return myActiveProgram;
}
+ //! @return OpenGL sampler object used to override default texture parameters
+ const Handle(OpenGl_Sampler)& TextureSampler()
+ {
+ return myTexSampler;
+ }
+
//! Bind specified program to current context,
//! or unbind previous one when NULL specified.
//! @return true if some program is bound to context
OpenGl_GlCore20Fwd* core20fwd; //!< OpenGL 2.0 without deprecated entry points
OpenGl_GlCore32* core32; //!< OpenGL 3.2 core profile
OpenGl_GlCore32Back* core32back; //!< OpenGL 3.2 backward compatibility profile
+ OpenGl_GlCore33* core33; //!< OpenGL 3.3 core profile
+ OpenGl_GlCore33Back* core33back; //!< OpenGL 3.3 backward compatibility profile
OpenGl_GlCore41* core41; //!< OpenGL 4.1 core profile
OpenGl_GlCore41Back* core41back; //!< OpenGL 4.1 backward compatibility profile
OpenGl_GlCore42* core42; //!< OpenGL 4.2 core profile
public: //! @name extensions
- Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
- Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
- Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two
- Standard_Boolean arbTexRG; //!< GL_ARB_texture_rg
- OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object
- OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced
- OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output
- OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
- OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4
- Standard_Boolean extBgra; //!< GL_EXT_bgra or GL_EXT_texture_format_BGRA8888 on OpenGL ES
- Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic
- Standard_Boolean extPDS; //!< GL_EXT_packed_depth_stencil
- Standard_Boolean atiMem; //!< GL_ATI_meminfo
- Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info
+ Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
+ Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
+ Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two
+ Standard_Boolean arbTexRG; //!< GL_ARB_texture_rg
+ OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
+ OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object
+ Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
+ OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced
+ OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output
+ OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
+ OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4
+ Standard_Boolean extBgra; //!< GL_EXT_bgra or GL_EXT_texture_format_BGRA8888 on OpenGL ES
+ Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic
+ Standard_Boolean extPDS; //!< GL_EXT_packed_depth_stencil
+ Standard_Boolean atiMem; //!< GL_ATI_meminfo
+ Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info
private: // system-dependent fields
private: //! @name fields tracking current state
Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program
+ Handle(OpenGl_Sampler) myTexSampler; //!< currently active sampler object
Standard_Integer myRenderMode; //!< value for active rendering mode
Standard_Integer myDrawBuffer; //!< current draw buffer
typedef double GLdouble;
typedef double GLclampd;
+ typedef uint64_t GLuint64;
#define GL_NONE 0
// OpenGL ES 3.0+ or GL_OES_element_index_uint extension
PFNGLPROGRAMPARAMETERIEXTPROC glProgramParameteriEXT;
+public: //! @name GL_ARB_bindless_texture
+
+ PFNGLGETTEXTUREHANDLEARBPROC glGetTextureHandleARB;
+ PFNGLGETTEXTURESAMPLERHANDLEARBPROC glGetTextureSamplerHandleARB;
+ PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glMakeTextureHandleResidentARB;
+ PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glMakeTextureHandleNonResidentARB;
+ PFNGLGETIMAGEHANDLEARBPROC glGetImageHandleARB;
+ PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glMakeImageHandleResidentARB;
+ PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glMakeImageHandleNonResidentARB;
+ PFNGLUNIFORMHANDLEUI64ARBPROC glUniformHandleui64ARB;
+ PFNGLUNIFORMHANDLEUI64VARBPROC glUniformHandleui64vARB;
+ PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glProgramUniformHandleui64ARB;
+ PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glProgramUniformHandleui64vARB;
+ PFNGLISTEXTUREHANDLERESIDENTARBPROC glIsTextureHandleResidentARB;
+ PFNGLISIMAGEHANDLERESIDENTARBPROC glIsImageHandleResidentARB;
+ PFNGLVERTEXATTRIBL1UI64ARBPROC glVertexAttribL1ui64ARB;
+ PFNGLVERTEXATTRIBL1UI64VARBPROC glVertexAttribL1ui64vARB;
+ PFNGLGETVERTEXATTRIBLUI64VARBPROC glGetVertexAttribLui64vARB;
+
#if defined(_WIN32)
public: //! @name wgl extensions
--- /dev/null
+// Created on: 2014-10-08
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OpenGl_Sampler.hxx>
+#include <OpenGl_GlCore33.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_Sampler, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Sampler, OpenGl_Resource)
+
+// =======================================================================
+// function : OpenGl_Sampler
+// purpose :
+// =======================================================================
+OpenGl_Sampler::OpenGl_Sampler()
+: mySamplerID (NO_SAMPLER)
+{
+ //
+}
+
+// =======================================================================
+// function : ~OpenGl_Sampler
+// purpose :
+// =======================================================================
+OpenGl_Sampler::~OpenGl_Sampler()
+{
+ Release (NULL);
+}
+
+// =======================================================================
+// function : Release
+// purpose :
+// =======================================================================
+void OpenGl_Sampler::Release (OpenGl_Context* theContext)
+{
+ if (isValidSampler())
+ {
+ // application can not handle this case by exception - this is bug in code
+ Standard_ASSERT_RETURN (theContext != NULL,
+ "OpenGl_Sampler destroyed without GL context! Possible GPU memory leakage...",);
+
+ if (theContext->IsValid())
+ {
+ #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
+ theContext->core33->glDeleteSamplers (1, &mySamplerID);
+ #endif
+ }
+
+ mySamplerID = NO_SAMPLER;
+ }
+}
+
+// =======================================================================
+// function : Init
+// purpose : Initializes sampler object
+// =======================================================================
+Standard_Boolean OpenGl_Sampler::Init (OpenGl_Context& theContext)
+{
+ if (theContext.core33 == NULL)
+ {
+ return Standard_False;
+ }
+
+ if (isValidSampler())
+ {
+ Release (&theContext);
+ }
+
+#if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
+ theContext.core33->glGenSamplers (1, &mySamplerID);
+ return Standard_True;
+#else
+ return Standard_False;
+#endif
+}
+
+// =======================================================================
+// function : Bind
+// purpose : Binds sampler object to the given texture unit
+// =======================================================================
+void OpenGl_Sampler::Bind (OpenGl_Context& theContext,
+ const GLuint theUnit)
+{
+ if (isValidSampler())
+ {
+ #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
+ theContext.core33->glBindSampler (theUnit, mySamplerID);
+ #endif
+ }
+}
+
+// =======================================================================
+// function : Unbind
+// purpose : Unbinds sampler object from the given texture unit
+// =======================================================================
+void OpenGl_Sampler::Unbind (OpenGl_Context& theContext,
+ const GLuint theUnit)
+{
+ if (isValidSampler())
+ {
+ #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
+ theContext.core33->glBindSampler (theUnit, NO_SAMPLER);
+ #endif
+ }
+}
+
+// =======================================================================
+// function : SetParameter
+// purpose : Sets sampler parameters
+// =======================================================================
+void OpenGl_Sampler::SetParameter (OpenGl_Context& theContext,
+ const GLenum theParam,
+ const GLint theValue)
+{
+ if (isValidSampler())
+ {
+ #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
+ theContext.core33->glSamplerParameteri (mySamplerID, theParam, theValue);
+ #endif
+ }
+}
--- /dev/null
+// Created on: 2014-10-08
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef OPENGL_SAMPLER_H
+#define OPENGL_SAMPLER_H
+
+#include <OpenGl_Context.hxx>
+#include <Handle_OpenGl_Sampler.hxx>
+
+//! Class implements OpenGL sampler object resource that
+//! stores the sampling parameters for a texture access.
+class OpenGl_Sampler : public OpenGl_Resource
+{
+public:
+
+ //! Helpful constant defining invalid sampler identifier
+ static const GLuint NO_SAMPLER = 0;
+
+public:
+
+ //! Creates new sampler object.
+ Standard_EXPORT OpenGl_Sampler();
+
+ //! Releases resources of sampler object.
+ Standard_EXPORT virtual ~OpenGl_Sampler();
+
+ //! Destroys object - will release GPU memory if any.
+ Standard_EXPORT virtual void Release (OpenGl_Context* theContext);
+
+ //! Initializes sampler object.
+ Standard_EXPORT Standard_Boolean Init (OpenGl_Context& theContext);
+
+ //! Returns true if current object was initialized.
+ Standard_Boolean IsValid() const
+ {
+ return isValidSampler();
+ }
+
+ //! Binds sampler object to the given texture unit.
+ Standard_EXPORT void Bind (OpenGl_Context& theContext, const GLuint theUnit = 0);
+
+ //! Unbinds sampler object from the given texture unit.
+ Standard_EXPORT void Unbind (OpenGl_Context& theContext, const GLuint theUnit = 0);
+
+ //! Sets specific sampler parameter.
+ Standard_EXPORT void SetParameter (OpenGl_Context& theContext, const GLenum theParam, const GLint theValue);
+
+ //! Returns OpenGL sampler ID.
+ GLuint SamplerID() const
+ {
+ return mySamplerID;
+ }
+
+protected:
+
+ //! Checks if sampler object is valid.
+ Standard_Boolean isValidSampler() const
+ {
+ return mySamplerID != NO_SAMPLER;
+ }
+
+protected:
+
+ GLuint mySamplerID; //!< OpenGL sampler object ID
+
+public:
+
+ DEFINE_STANDARD_RTTI(OpenGl_Sampler)
+
+};
+
+#endif // OPENGL_SAMPLER_H
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <Standard_Assert.hxx>
-
#ifdef HAVE_TBB
// On Windows, function TryEnterCriticalSection has appeared in Windows NT
// and is surrounded by #ifdef in MS VC++ 7.1 headers.
#include <OpenGl_SceneGeometry.hxx>
+#include <OpenGl_ArbTexBindless.hxx>
#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_Structure.hxx>
+#include <OSD_Timer.hxx>
+#include <Standard_Assert.hxx>
//! Use this macro to output BVH profiling info
-//#define BVH_PRINT_INFO
-
-#ifdef BVH_PRINT_INFO
- #include <OSD_Timer.hxx>
-#endif
+// #define RAY_TRACE_PRINT_INFO
namespace
{
//! Useful constant for null floating-point 4D vector.
static const BVH_Vec4f ZERO_VEC_4F;
-};
+}
// =======================================================================
// function : OpenGl_RaytraceMaterial
//
}
+// =======================================================================
+// function : Box
+// purpose : Returns AABB of primitive set
+// =======================================================================
+OpenGl_TriangleSet::BVH_BoxNt OpenGl_TriangleSet::Box() const
+{
+ const BVH_Transform<Standard_ShortReal, 4>* aTransform =
+ dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->());
+
+ BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 3>::Box();
+
+ if (aTransform != NULL)
+ {
+ BVH_BoxNt aTransformedBox;
+
+ for (Standard_Integer aX = 0; aX <= 1; ++aX)
+ {
+ for (Standard_Integer aY = 0; aY <= 1; ++aY)
+ {
+ for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
+ {
+ BVH_Vec4f aCorner = aTransform->Transform() * BVH_Vec4f (
+ aX == 0 ? aBox.CornerMin().x() : aBox.CornerMax().x(),
+ aY == 0 ? aBox.CornerMin().y() : aBox.CornerMax().y(),
+ aZ == 0 ? aBox.CornerMin().z() : aBox.CornerMax().z(),
+ 1.f);
+
+ aTransformedBox.Add (reinterpret_cast<BVH_Vec3f&> (aCorner));
+ }
+ }
+ }
+
+ return aTransformedBox;
+ }
+
+ return aBox;
+}
+
// =======================================================================
// function : Clear
// purpose : Clears ray-tracing geometry
// =======================================================================
void OpenGl_RaytraceGeometry::Clear()
{
- BVH_Geometry<Standard_ShortReal, 4>::BVH_Geometry::Clear();
+ BVH_Geometry<Standard_ShortReal, 3>::BVH_Geometry::Clear();
std::vector<OpenGl_RaytraceLight,
NCollection_StdAllocator<OpenGl_RaytraceLight> > anEmptySources;
struct OpenGL_BVHParallelBuilder
{
- BVH_ObjectSet<Standard_ShortReal, 4>* Set;
+ BVH_ObjectSet<Standard_ShortReal, 3>* Set;
- OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 4>* theSet)
+ OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 3>* theSet)
: Set (theSet)
{
//
// =======================================================================
Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration()
{
-#ifdef BVH_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
OSD_Timer aTimer;
#endif
MarkDirty(); // force BVH rebuilding
-#ifdef BVH_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
aTimer.Reset();
aTimer.Start();
#endif
myBottomLevelTreeDepth = Max (myBottomLevelTreeDepth, aTriangleSet->BVH()->Depth());
}
-#ifdef BVH_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
aTimer.Stop();
std::cout << "Updating bottom-level BVHs (sec): " <<
aTimer.ElapsedTime() << std::endl;
#endif
-#ifdef BVH_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
aTimer.Reset();
aTimer.Start();
#endif
- NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> > aBVH = BVH();
+ NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> > aBVH = BVH();
-#ifdef BVH_PRINT_INFO
+#ifdef RAY_TRACE_PRINT_INFO
aTimer.Stop();
std::cout << "Updating high-level BVH (sec): " <<
// =======================================================================
Standard_Integer OpenGl_RaytraceGeometry::AccelerationOffset (Standard_Integer theNodeIdx)
{
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = BVH();
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH();
if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
return INVALID_OFFSET;
// =======================================================================
Standard_Integer OpenGl_RaytraceGeometry::VerticesOffset (Standard_Integer theNodeIdx)
{
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = BVH();
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH();
if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
return INVALID_OFFSET;
// =======================================================================
Standard_Integer OpenGl_RaytraceGeometry::ElementsOffset (Standard_Integer theNodeIdx)
{
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = BVH();
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH();
if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
return INVALID_OFFSET;
// =======================================================================
OpenGl_TriangleSet* OpenGl_RaytraceGeometry::TriangleSet (Standard_Integer theNodeIdx)
{
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = BVH();
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = BVH();
if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
return NULL;
aBVH->NodeInfoBuffer().at (theNodeIdx).x() - 1).operator->());
}
+// =======================================================================
+// function : AcquireTextures
+// purpose : Makes the OpenGL texture handles resident
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext) const
+{
+ if (theContext->arbTexBindless == NULL)
+ {
+ return Standard_True;
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ {
+ theContext->arbTexBindless->glMakeTextureHandleResidentARB (myTextureHandles[anIdx]);
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+#ifdef RAY_TRACE_PRINT_INFO
+ std::cout << "Error: Failed to make OpenGL texture resident" << std::endl;
+#endif
+ return Standard_False;
+ }
+ }
+#endif
+
+ return Standard_True;
+}
+
+// =======================================================================
+// function : ReleaseTextures
+// purpose : Makes the OpenGL texture handles non-resident
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceGeometry::ReleaseTextures (const Handle(OpenGl_Context)& theContext) const
+{
+ if (theContext->arbTexBindless == NULL)
+ {
+ return Standard_True;
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ {
+ theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[anIdx]);
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+#ifdef RAY_TRACE_PRINT_INFO
+ std::cout << "Error: Failed to make OpenGL texture non-resident" << std::endl;
+#endif
+ return Standard_False;
+ }
+ }
+#endif
+
+ return Standard_True;
+}
+
+// =======================================================================
+// function : AddTexture
+// purpose : Adds new OpenGL texture to the scene and returns its index
+// =======================================================================
+Standard_Integer OpenGl_RaytraceGeometry::AddTexture (const Handle(OpenGl_Texture)& theTexture)
+{
+ NCollection_Vector<Handle (OpenGl_Texture)>::iterator anIter =
+ std::find (myTextures.begin(), myTextures.end(), theTexture);
+
+ if (anIter == myTextures.end())
+ {
+ if (myTextures.Size() >= MAX_TEX_NUMBER)
+ {
+ return -1;
+ }
+
+ myTextures.Append (theTexture);
+ }
+
+ return static_cast<Standard_Integer> (anIter - myTextures.begin());
+}
+
+// =======================================================================
+// function : UpdateTextureHandles
+// purpose : Updates unique 64-bit texture handles to use in shaders
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(OpenGl_Context)& theContext)
+{
+ if (theContext->arbTexBindless == NULL)
+ {
+ return Standard_False;
+ }
+
+ myTextureHandles.clear();
+
+#if !defined(GL_ES_VERSION_2_0)
+ for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ {
+ const GLuint64 aHandle = theContext->arbTexBindless->glGetTextureHandleARB (
+ myTextures.Value (anIdx)->TextureId());
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+#ifdef RAY_TRACE_PRINT_INFO
+ std::cout << "Error: Failed to get 64-bit handle of OpenGL texture" << std::endl;
+#endif
+ return Standard_False;
+ }
+
+ myTextureHandles.push_back (aHandle);
+ }
+#endif
+
+ return Standard_True;
+}
+
namespace OpenGl_Raytrace
{
// =======================================================================
// =======================================================================
Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode)
{
- OpenGl_PrimitiveArray* anArray = dynamic_cast< OpenGl_PrimitiveArray* > (theNode->elem);
+ OpenGl_PrimitiveArray* anArray = dynamic_cast<OpenGl_PrimitiveArray*> (theNode->elem);
return anArray != NULL
&& anArray->DrawMode() >= GL_TRIANGLES;
}
#include <BVH_Geometry.hxx>
#include <BVH_Triangulation.hxx>
#include <NCollection_StdAllocator.hxx>
+#include <OpenGl_TextureBufferArb.hxx>
+#include <OpenGl_Texture.hxx>
class OpenGl_Element;
struct OpenGl_ElementNode;
//! Material transparency.
BVH_Vec4f Transparency;
+ //! Texture transformation matrix.
+ BVH_Mat4f TextureTransform;
+
public:
//! Creates new default material.
};
//! Triangulation of single OpenGL primitive array.
-class OpenGl_TriangleSet : public BVH_Triangulation<Standard_ShortReal, 4>
+class OpenGl_TriangleSet : public BVH_Triangulation<Standard_ShortReal, 3>
{
public:
//! Creates new OpenGL element triangulation.
OpenGl_TriangleSet (const Standard_Size theArrayID)
- : BVH_Triangulation<Standard_ShortReal, 4>(),
+ : BVH_Triangulation<Standard_ShortReal, 3> (),
myArrayID (theArrayID)
- {
- //
- }
+ {
+ //
+ }
//! Releases resources of OpenGL element triangulation.
~OpenGl_TriangleSet()
Standard_Integer MaterialIndex() const
{
if (Elements.size() == 0)
+ {
return INVALID_MATERIAL;
+ }
return Elements.front().w();
}
//! Sets material index for entire triangle set.
- void SetMaterialIndex (Standard_Integer aMatID)
+ void SetMaterialIndex (Standard_Integer theMatID)
{
for (Standard_Size anIdx = 0; anIdx < Elements.size(); ++anIdx)
- Elements[anIdx].w() = aMatID;
- }
-
- //! Returns AABB of primitive set.
- BVH_BoxNt Box() const
- {
- const BVH_Transform<Standard_ShortReal, 4>* aTransform =
- dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->());
-
- BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 4>::Box();
-
- if (aTransform)
{
- return aTransform->Apply (aBox);
+ Elements[anIdx].w() = theMatID;
}
-
- return aBox;
}
+ //! Returns AABB of primitive set.
+ BVH_BoxNt Box() const;
+
public:
- BVH_Array4f Normals; //!< Array of vertex normals.
-
+ BVH_Array3f Normals; //!< Array of vertex normals.
+
+ BVH_Array2f TexCrds; //!< Array of vertex UV coords.
+
private:
Standard_Size myArrayID; //!< Id of associated primitive array.
};
//! Stores geometry of ray-tracing scene.
-class OpenGl_RaytraceGeometry : public BVH_Geometry<Standard_ShortReal, 4>
+class OpenGl_RaytraceGeometry : public BVH_Geometry<Standard_ShortReal, 3>
{
public:
//! Value of invalid offset to return in case of errors.
static const Standard_Integer INVALID_OFFSET = -1;
+ //! Maximum number of textures used in ray-tracing shaders.
+ //! This is not restriction of the solution implemented, but
+ //! rather the reasonable limit of the number of textures in
+ //! various applications (can be increased if needed).
+ static const Standard_Integer MAX_TEX_NUMBER = 32;
+
public:
//! Array of properties of light sources.
//! Creates uninitialized ray-tracing geometry.
OpenGl_RaytraceGeometry()
- : BVH_Geometry<Standard_ShortReal, 4>(),
+ : BVH_Geometry<Standard_ShortReal, 3>(),
myHighLevelTreeDepth (0),
myBottomLevelTreeDepth (0)
{
//
}
- //! Clears ray-tracing geometry.
- void Clear();
-
//! Clears only ray-tracing materials.
void ClearMaterials()
{
std::vector<OpenGl_RaytraceMaterial,
NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials;
-
+
Materials.swap (anEmptyMaterials);
+
+ myTextures.Clear();
}
-public:
+ //! Clears ray-tracing geometry.
+ void Clear();
+
+public: //! @name methods related to acceleration structure
//! Performs post-processing of high-level scene BVH.
Standard_Boolean ProcessAcceleration();
//! @note Can be used after processing acceleration structure.
OpenGl_TriangleSet* TriangleSet (Standard_Integer theNodeIdx);
+public: //! @name methods related to texture management
+
+ //! Adds new OpenGL texture to the scene and returns its index.
+ Standard_Integer AddTexture (const Handle(OpenGl_Texture)& theTexture);
+
+ //! Updates unique 64-bit texture handles to use in shaders.
+ Standard_Boolean UpdateTextureHandles (const Handle(OpenGl_Context)& theContext);
+
+ //! Makes the OpenGL texture handles resident (must be called before using).
+ Standard_Boolean AcquireTextures (const Handle(OpenGl_Context)& theContext) const;
+
+ //! Makes the OpenGL texture handles non-resident (must be called after using).
+ Standard_Boolean ReleaseTextures (const Handle(OpenGl_Context)& theContext) const;
+
+ //! Returns array of texture handles.
+ const std::vector<GLuint64>& TextureHandles() const
+ {
+ return myTextureHandles;
+ }
+
+ //! Checks if scene contains textured objects.
+ Standard_Integer HasTextures() const
+ {
+ return !myTextures.IsEmpty();
+ }
+
+public: //! @name auxiliary methods
+
//! Returns depth of high-level scene BVH from last build.
Standard_Integer HighLevelTreeDepth() const
{
protected:
- Standard_Integer myHighLevelTreeDepth; //!< Depth of high-level scene BVH from last build
- Standard_Integer myBottomLevelTreeDepth; //!< Maximum depth of bottom-level scene BVHs from last build
+ NCollection_Vector<Handle(OpenGl_Texture)> myTextures; //!< Array of texture maps shared between rendered objects
+ std::vector<GLuint64> myTextureHandles; //!< Array of unique 64-bit texture handles obtained from OpenGL
+ Standard_Integer myHighLevelTreeDepth; //!< Depth of high-level scene BVH from last build
+ Standard_Integer myBottomLevelTreeDepth; //!< Maximum depth of bottom-level scene BVHs from last build
};
#include <OpenGl_Context.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ArbTexBindless.hxx>
IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
return Standard_True;
}
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the 64-bit unsigned uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ GLuint64 theValue)
+{
+ return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the 64-bit unsigned uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ GLuint64 theValue)
+{
+ if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+ {
+ return Standard_False;
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ theCtx->arbTexBindless->glUniformHandleui64ARB (theLocation, theValue);
+#endif
+
+ return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the 64-bit unsigned uniform array
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ const GLsizei theCount,
+ const GLuint64* theValue)
+{
+ return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the 64-bit unsigned uniform array
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ const GLsizei theCount,
+ const GLuint64* theValue)
+{
+ if (theCtx->arbTexBindless == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+ {
+ return Standard_False;
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ theCtx->arbTexBindless->glUniformHandleui64vARB (theLocation, theCount, theValue);
+#endif
+
+ return Standard_True;
+}
+
// =======================================================================
// function : SetUniform
// purpose : Specifies the value of the floating-point uniform variable
return Standard_True;
}
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ const OpenGl_Mat4& theValue,
+ GLboolean theTranspose)
+{
+ return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ const OpenGl_Mat4& theValue,
+ GLboolean theTranspose)
+{
+ if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+ {
+ return Standard_False;
+ }
+
+ theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, theValue);
+ return Standard_True;
+}
+
// =======================================================================
// function : SetUniform
// purpose : Specifies the value of the floating-point uniform 4x4 matrix
GLint theLocation,
const OpenGl_Vec4i& theValue);
+public:
+
+ //! Specifies the value of the 64-bit unsigned integer uniform variable.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ GLuint64 theValue);
+
+ //! Specifies the value of the 64-bit unsigned integer uniform variable.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ GLuint64 theValue);
+
+ //! Specifies the value of the 64-bit unsigned integer uniform array.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ const GLsizei theCount,
+ const GLuint64* theValue);
+
+ //! Specifies the value of the 64-bit unsigned integer uniform array.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ const GLsizei theCount,
+ const GLuint64* theValue);
+
public:
//! Specifies the value of the float uniform variable.
public:
+ //! Specifies the value of the float uniform 4x4 matrix.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ const GLchar* theName,
+ const OpenGl_Mat4& theValue,
+ GLboolean theTranspose = GL_FALSE);
+
+ //! Specifies the value of the float uniform 4x4 matrix.
+ Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+ GLint theLocation,
+ const OpenGl_Mat4& theValue,
+ GLboolean theTranspose = GL_FALSE);
+
//! Specifies the value of the float uniform 4x4 matrix.
Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_ShaderStates.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_Text.hxx>
#include <OpenGl_Workspace.hxx>
// =======================================================================
void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
- const OpenGl_AspectText* aTextAspect = theWorkspace->AspectText (Standard_True);
- const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
-
- const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ const OpenGl_AspectText* aTextAspect = theWorkspace->AspectText (Standard_True);
+ const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ const Handle(OpenGl_Sampler)& aSampler = aCtx->TextureSampler();
+ if (!aSampler.IsNull())
+ {
+ aSampler->Unbind (*aCtx);
+ }
if (aCtx->IsGlGreaterEqual (2, 0))
{
}
// restore aspects
+ if (!aSampler.IsNull())
+ {
+ aSampler->Bind (*aCtx);
+ }
if (!aPrevTexture.IsNull())
{
theWorkspace->EnableTexture (aPrevTexture);
theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
}
+ // unbind current OpenGL sampler
+ const Handle(OpenGl_Sampler)& aSampler = theCtx->TextureSampler();
+ if (!aSampler.IsNull() && aSampler->IsValid())
+ {
+ aSampler->Unbind (*theCtx);
+ }
+
// extra drawings
switch (theTextAspect.DisplayType())
{
// revert OpenGL state
glPopAttrib(); // enable bit
glPopMatrix(); // model view matrix was modified
+
+ // revert custom OpenGL sampler
+ if (!aSampler.IsNull() && aSampler->IsValid())
+ {
+ aSampler->Bind (*theCtx);
+ }
#endif
}
const GLfloat* theData)
{
#if !defined(GL_ES_VERSION_2_0)
- if (theComponentsNb != 1
- && theComponentsNb != 2
- && theComponentsNb != 4)
+ if (theComponentsNb < 1
+ || theComponentsNb > 4)
{
// unsupported format
return false;
}
+ else if (theComponentsNb == 3
+ && !theGlCtx->arbTboRGB32)
+ {
+ return false;
+ }
else if (!Create (theGlCtx)
|| !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
{
{
case 1: myTexFormat = GL_R32F; break;
case 2: myTexFormat = GL_RG32F; break;
- //case 3: myTexFormat = GL_RGB32F; break; // GL_ARB_texture_buffer_object_rgb32
+ case 3: myTexFormat = GL_RGB32F; break; // GL_ARB_texture_buffer_object_rgb32
case 4: myTexFormat = GL_RGBA32F; break;
}
const GLuint* theData)
{
#if !defined(GL_ES_VERSION_2_0)
- if (theComponentsNb != 1
- && theComponentsNb != 2
- && theComponentsNb != 3
- && theComponentsNb != 4)
+ if (theComponentsNb < 1
+ || theComponentsNb > 4)
{
// unsupported format
return false;
}
+ else if (theComponentsNb == 3
+ && !theGlCtx->arbTboRGB32)
+ {
+ return false;
+ }
else if (!Create (theGlCtx)
|| !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
{
/*----------------------------------------------------------------------*/
-void OpenGl_View::GetMatrices (TColStd_Array2OfReal& theMatOrient,
- TColStd_Array2OfReal& theMatMapping) const
+void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
+ OpenGl_Mat4& theViewMapping) const
{
- const Graphic3d_Mat4d& aProj = myCamera->ProjectionMatrix();
- const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
-
- for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
- {
- for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
- {
- theMatOrient (aRow, aCol) = aOrient.GetValue (aRow, aCol);
- theMatMapping (aRow, aCol) = aProj .GetValue (aRow, aCol);
- }
- }
+ theViewMapping = myCamera->ProjectionMatrixF();
+ theOrientation = myCamera->OrientationMatrixF();
}
/*----------------------------------------------------------------------*/
//! marks primitive set for rebuild.
void InvalidateBVHData (const Standard_Integer theLayerId);
- void GetMatrices (TColStd_Array2OfReal& theMatOrient,
- TColStd_Array2OfReal& theMatMapping) const;
+ //! Returns view-mapping and orientation matrices.
+ void GetMatrices (OpenGl_Mat4& theOrientation,
+ OpenGl_Mat4& theViewMapping) const;
//! Returns list of immediate structures rendered on top of main presentation
const OpenGl_SequenceOfStructure& ImmediateStructures() const
#include <OpenGl_Element.hxx>
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_Structure.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_Texture.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
//
myComputeInitStatus (OpenGl_RT_NONE),
myIsRaytraceDataValid (Standard_False),
+ myIsRaytraceWarnTextures (Standard_False),
myViewModificationStatus (0),
myLayersModificationStatus (0),
//
}
#endif
+ // get active sampler object to override default texture parameters
+ const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
+
// setup texture filtering and wrapping
//if (theTexture->GetParams() != theParams)
const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
#if !defined(GL_ES_VERSION_2_0)
case GL_TEXTURE_1D:
{
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
+ if (aSampler.IsNull() || !aSampler->IsValid())
+ {
+ glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
+ glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
+ glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
+ }
+ else
+ {
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
+ }
+
break;
}
#endif
{
// setup degree of anisotropy filter
const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
+ GLint aDegree;
switch (aParams->AnisoFilter())
{
case Graphic3d_LOTA_QUALITY:
{
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
+ aDegree = aMaxDegree;
break;
}
case Graphic3d_LOTA_MIDDLE:
{
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
+ aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
break;
}
case Graphic3d_LOTA_FAST:
{
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
+ aDegree = 2;
break;
}
case Graphic3d_LOTA_OFF:
default:
{
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
+ aDegree = 1;
break;
}
}
+
+ if (aSampler.IsNull() || !aSampler->IsValid())
+ {
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
+ }
+ else
+ {
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
+ }
}
}
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
+
+ if (aSampler.IsNull() || !aSampler->IsValid())
+ {
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
+ }
+ else
+ {
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
+ aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
+ }
+
break;
}
default: break;
myTextureBound->Bind (myGlContext);
setTextureParams (myTextureBound, theParams);
+ // If custom sampler object is available it will be
+ // used for overriding default texture parameters
+ const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
+
+ if (!aSampler.IsNull() && aSampler->IsValid())
+ {
+ aSampler->Bind (*myGlContext);
+ }
+
return aPrevTexture;
}
DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
-//! Graphical raytracing filter.
+//! Graphical ray-tracing filter.
//! Filters out all raytracable structures.
class OpenGl_RaytraceFilter : public OpenGl_RenderFilter
{
OpenGl_RT_uOriginLB,
OpenGl_RT_uOriginRT,
OpenGl_RT_uOriginRB,
-
OpenGl_RT_uDirectLT,
OpenGl_RT_uDirectLB,
OpenGl_RT_uDirectRT,
OpenGl_RT_uDirectRB,
- OpenGl_RT_uInvModelProj,
-
+ OpenGl_RT_uUnviewMat,
+
OpenGl_RT_uSceneRad,
OpenGl_RT_uSceneEps,
-
OpenGl_RT_uLightAmbnt,
OpenGl_RT_uLightCount,
OpenGl_RT_uShadEnabled,
OpenGl_RT_uReflEnabled,
-
- OpenGl_RT_uInputTexture,
+ OpenGl_RT_uEnvMapEnable,
OpenGl_RT_uOffsetX,
OpenGl_RT_uOffsetY,
OpenGl_RT_uSamples,
- OpenGl_RT_uEnvironmentEnable,
+ OpenGl_RT_uTextures,
OpenGl_RT_NbVariables // special field
};
OpenGl_RT_GeometryVertexTexture = 6,
OpenGl_RT_GeometryNormalTexture = 7,
- OpenGl_RT_GeometryTriangTexture = 8,
+ OpenGl_RT_GeometryTexCrdTexture = 8,
+ OpenGl_RT_GeometryTriangTexture = 9,
- OpenGl_RT_EnvironmentMapTexture = 9,
+ OpenGl_RT_EnvironmentMapTexture = 10,
- OpenGl_RT_RaytraceMaterialTexture = 10,
- OpenGl_RT_RaytraceLightSrcTexture = 11,
+ OpenGl_RT_RaytraceMaterialTexture = 11,
+ OpenGl_RT_RaytraceLightSrcTexture = 12,
- OpenGl_RT_FSAAInputTexture = 12,
+ OpenGl_RT_FSAAInputTexture = 13,
- OpenGl_RT_SceneTransformTexture = 13,
+ OpenGl_RT_SceneTransformTexture = 14,
- OpenGl_RT_OpenGlColorTexture = 14,
- OpenGl_RT_OpenGlDepthTexture = 15
+ OpenGl_RT_OpenGlColorTexture = 15,
+ OpenGl_RT_OpenGlDepthTexture = 16
};
//! Tool class for management of shader sources.
};
//! Default ray-tracing depth.
- static const Standard_Integer THE_DEFAULT_RAY_DEPTH = 3;
+ static const Standard_Integer THE_DEFAULT_NB_BOUNCES = 3;
//! Default size of traversal stack.
static const Standard_Integer THE_DEFAULT_STACK_SIZE = 24;
Standard_Integer StackSize;
//! Actual ray-tracing depth (number of ray bounces).
- Standard_Integer TraceDepth;
+ Standard_Integer NbBounces;
//! Sets light propagation through transparent media.
Standard_Boolean TransparentShadows;
//! Creates default compile-time ray-tracing parameters.
RaytracingParams()
: StackSize (THE_DEFAULT_STACK_SIZE),
- TraceDepth (THE_DEFAULT_RAY_DEPTH),
+ NbBounces (THE_DEFAULT_NB_BOUNCES),
TransparentShadows (Standard_False)
{
//
//! Checks to see if the structure is modified.
Standard_Boolean CheckRaytraceStructure (const OpenGl_Structure* theStructure);
+ //! Creates ray-tracing material properties.
+ Standard_Boolean CreateMaterial (const OpenGl_AspectFace* theAspect, OpenGl_RaytraceMaterial& theMaterial);
+
//! Updates 3D scene light sources for ray-tracing.
- Standard_Boolean UpdateRaytraceLightSources (const GLdouble theInvModelView[16]);
+ Standard_Boolean UpdateRaytraceLightSources (const OpenGl_Mat4& theInvModelView);
//! Updates environment map for ray-tracing.
Standard_Boolean UpdateRaytraceEnvironmentMap();
//! Adds OpenGL primitive array to ray-traced scene geometry.
OpenGl_TriangleSet* AddRaytracePrimitiveArray (
- const OpenGl_PrimitiveArray* theArray, int theMatID, const Standard_ShortReal* theTrans);
+ const OpenGl_PrimitiveArray* theArray, int theMatID, const OpenGl_Mat4* theTrans);
//! Adds vertex indices from OpenGL primitive array to ray-traced scene geometry.
Standard_Boolean AddRaytraceVertexIndices (OpenGl_TriangleSet& theSet,
//! Performs safe exit when shaders initialization fails.
Standard_Boolean SafeFailBack (const TCollection_ExtendedString& theMessage);
+ //! Generates shader prefix based on current ray-tracing options.
+ TCollection_AsciiString GenerateShaderPrefix();
+
//! Initializes OpenGL/GLSL shader programs.
Standard_Boolean InitRaytraceResources (const Graphic3d_CView& theCView);
const Standard_Integer theSizeY);
//! Generates viewing rays for corners of screen quad.
- void UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
- const NCollection_Mat4<GLdouble>& theViewMapping,
- OpenGl_Vec3 theOrigins[4],
- OpenGl_Vec3 theDirects[4],
- NCollection_Mat4<GLdouble>& theInvModelProj);
+ void UpdateCamera (const OpenGl_Mat4& theOrientation,
+ const OpenGl_Mat4& theViewMapping,
+ OpenGl_Vec3 theOrigins[4],
+ OpenGl_Vec3 theDirects[4],
+ OpenGl_Mat4& theInvModelProj);
+
+ //! Sets uniform state for the given ray-tracing shader program.
+ Standard_Boolean SetUniformState (const Graphic3d_CView& theCView,
+ const OpenGl_Vec3* theOrigins,
+ const OpenGl_Vec3* theDirects,
+ const OpenGl_Mat4& theUnviewMat,
+ const Standard_Integer theProgramIndex,
+ Handle(OpenGl_ShaderProgram)& theRaytraceProgram);
//! Runs ray-tracing shader programs.
Standard_Boolean RunRaytraceShaders (const Graphic3d_CView& theCView,
const Standard_Integer theSizeY,
const OpenGl_Vec3 theOrigins[4],
const OpenGl_Vec3 theDirects[4],
- const OpenGl_Matrix& theInvModelProj,
+ const OpenGl_Mat4& theUnviewMat,
OpenGl_FrameBuffer* theFrameBuffer);
//! Redraws the window using OpenGL/GLSL ray-tracing.
//! Is geometry data valid?
Standard_Boolean myIsRaytraceDataValid;
+ //! Warning about missing extension GL_ARB_bindless_texture has been displayed?
+ Standard_Boolean myIsRaytraceWarnTextures;
+
//! 3D scene geometry data for ray-tracing.
OpenGl_RaytraceGeometry myRaytraceGeometry;
Handle(OpenGl_TextureBufferArb) myGeometryVertexTexture;
//! Texture buffer of vertex normals.
Handle(OpenGl_TextureBufferArb) myGeometryNormalTexture;
+ //! Texture buffer of vertex UV coords.
+ Handle(OpenGl_TextureBufferArb) myGeometryTexCrdTexture;
//! Texture buffer of triangle indices.
Handle(OpenGl_TextureBufferArb) myGeometryTriangTexture;
-
+
//! Texture buffer of material properties.
Handle(OpenGl_TextureBufferArb) myRaytraceMaterialTexture;
//! Texture buffer of light source properties.
//! Cached locations of frequently used uniform variables.
Standard_Integer myUniformLocations[2][OpenGl_RT_NbVariables];
- //! Graphical raytracing filter to filter out all raytracable structures.
+ //! Graphical ray-tracing filter to filter out all raytracable structures.
Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
- //! Redraw the scene using OpenGL rasterization or raytracing?
+ //! Redraw the scene using OpenGL rasterization or ray-tracing?
Standard_Boolean myToRedrawGL;
protected: //! @name protected fields
#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
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.
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-6f, 1e-4f * sqrtf (
aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
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 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 aMaxRefl = Max (theMaterial.Diffuse.x() + theMaterial.Specular.x(),
+ Max (theMaterial.Diffuse.y() + theMaterial.Specular.y(),
+ theMaterial.Diffuse.z() + theMaterial.Specular.z()));
- const float aReflectionScale = 0.75f / aMaxRefl;
+ const Standard_ShortReal 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;
}
// =======================================================================
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);
}
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);
}
aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
OpenGl_RaytraceMaterial aMaterial;
- CreateMaterial (anAspect->IntFront(), aMaterial);
+ CreateMaterial (anAspect, aMaterial);
myRaytraceGeometry.Materials.push_back (aMaterial);
}
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())
// =======================================================================
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();
}
#endif
+ 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());
}
}
// 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));
}
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);
}
}
}
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;
{
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;
aShaderProgram->SetSampler (myGlContext,
"uGeometryNormalTexture", OpenGl_RT_GeometryNormalTexture);
aShaderProgram->SetSampler (myGlContext,
- "uGeometryTriangTexture", OpenGl_RT_GeometryTriangTexture);
+ "uGeometryTexCrdTexture", OpenGl_RT_GeometryTexCrdTexture);
aShaderProgram->SetSampler (myGlContext,
- "uRaytraceMaterialTexture", OpenGl_RT_RaytraceMaterialTexture);
- aShaderProgram->SetSampler (myGlContext,
- "uRaytraceLightSrcTexture", OpenGl_RT_RaytraceLightSrcTexture);
+ "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,
"uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
aShaderProgram->GetUniformLocation (myGlContext, "uDirectLT");
myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
aShaderProgram->GetUniformLocation (myGlContext, "uDirectRT");
- myUniformLocations[anIndex][OpenGl_RT_uInvModelProj] =
- aShaderProgram->GetUniformLocation (myGlContext, "uInvModelProj");
-
- 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");
myUniformLocations[anIndex][OpenGl_RT_uSamples] =
aShaderProgram->GetUniformLocation (myGlContext, "uSamples");
- myUniformLocations[anIndex][OpenGl_RT_uEnvironmentEnable] =
+ myUniformLocations[anIndex][OpenGl_RT_uTextures] =
+ aShaderProgram->GetUniformLocation (myGlContext, "uTextureSamplers");
+
+ 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");
}
NullifyResource (myGlContext, myGeometryVertexTexture);
NullifyResource (myGlContext, myGeometryNormalTexture);
+ NullifyResource (myGlContext, myGeometryTexCrdTexture);
NullifyResource (myGlContext, myGeometryTriangTexture);
NullifyResource (myGlContext, mySceneTransformTexture);
return Standard_False;
}
+ /////////////////////////////////////////////////////////////////////////////
+ // Prepare OpenGL textures
+
+ if (myGlContext->arbTexBindless != NULL)
+ {
+ // 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 get OpenGL texture handles" << std::endl;
+#endif
+ return Standard_False;
+ }
+ }
+
/////////////////////////////////////////////////////////////////////////////
// Create OpenGL texture buffers
myObjectMaxPointTexture = new OpenGl_TextureBufferArb;
if (!myObjectNodeInfoTexture->Create (myGlContext)
- || !myObjectMinPointTexture->Create (myGlContext)
- || !myObjectMaxPointTexture->Create (myGlContext))
+ || !myObjectMinPointTexture->Create (myGlContext)
+ || !myObjectMaxPointTexture->Create (myGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffers for bottom-level scene BVH" << std::endl;
{
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;
/////////////////////////////////////////////////////////////////////////////
// Write top-level BVH buffers
- const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = myRaytraceGeometry.BVH();
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& 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()),
+ aResult &= mySceneMinPointTexture->Init (myGlContext, 3, GLsizei (aBVH->MinPointBuffer().size()),
reinterpret_cast<const GLfloat*> (&aBVH->MinPointBuffer().front()));
- aResult &= mySceneMaxPointTexture->Init (myGlContext, 4, GLsizei (aBVH->MaxPointBuffer().size()),
+ aResult &= mySceneMaxPointTexture->Init (myGlContext, 3, GLsizei (aBVH->MaxPointBuffer().size()),
reinterpret_cast<const GLfloat*> (&aBVH->MaxPointBuffer().front()));
}
if (!aResult)
// Write transform buffer
BVH_Mat4f* aNodeTransforms = new BVH_Mat4f[myRaytraceGeometry.Size()];
- BVH_Mat4f anIdentity;
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
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 &= myObjectNodeInfoTexture->Init (
+ myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLuint*> (NULL));
+ aResult &= myObjectMinPointTexture->Init (
+ myGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
+ aResult &= myObjectMaxPointTexture->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)
{
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_Vec4f));
+ aTriangleSet->Normals.size() * sizeof (BVH_Vec3f));
+ aMemUsed += static_cast<Standard_ShortReal> (
+ 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],
- NCollection_Mat4<GLdouble>& theInvModelProj)
+void OpenGl_Workspace::UpdateCamera (const OpenGl_Mat4& theOrientation,
+ const OpenGl_Mat4& theViewMapping,
+ OpenGl_Vec3 theOrigins[4],
+ OpenGl_Vec3 theDirects[4],
+ OpenGl_Mat4& theInvModelProj)
{
// compute inverse model-view-projection matrix
(theViewMapping * theOrientation).Inverted (theInvModelProj);
{
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 = theInvModelProj * aOrigin;
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 = theInvModelProj * aDirect;
}
}
+// =======================================================================
+// function : SetUniformState
+// purpose : Sets uniform state for the given ray-tracing shader program
+// =======================================================================
+Standard_Boolean OpenGl_Workspace::SetUniformState (const Graphic3d_CView& theCView,
+ 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 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 << "Error: Failed to set uniform state for ray-tracing 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_Matrix& theInvModelProj,
+ const OpenGl_Mat4& theUnviewMat,
OpenGl_FrameBuffer* theFrameBuffer)
{
mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
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);
myGlContext->BindProgram (myRaytraceProgram);
- Standard_Integer aLightSourceBufferSize =
- static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
-
- 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_uInvModelProj], theInvModelProj);
- 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);
+ SetUniformState (theCView,
+ theOrigins,
+ theDirects,
+ theUnviewMat,
+ 0, // ID of RT program
+ myRaytraceProgram);
myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
{
myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
}
myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS);
-
+
if (!theCView.RenderParams.IsAntialiasingEnabled)
{
myGlContext->BindProgram (NULL);
myObjectNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
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);
- mySceneTransformTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
myGlContext->BindProgram (myPostFSAAProgram);
- 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]);
- myRaytraceProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uInvModelProj], theInvModelProj);
- 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);
+ SetUniformState (theCView,
+ theOrigins,
+ theDirects,
+ theUnviewMat,
+ 1, // ID of FSAA program
+ myPostFSAAProgram);
const Standard_ShortReal aMaxOffset = 0.559017f;
const Standard_ShortReal aMinOffset = 0.186339f;
myObjectNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
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);
- mySceneTransformTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
return Standard_False;
// Get model-view and projection matrices
- TColStd_Array2OfReal theOrientation (0, 3, 0, 3);
- TColStd_Array2OfReal theViewMapping (0, 3, 0, 3);
+ OpenGl_Mat4 aOrientationMatrix;
+ OpenGl_Mat4 aViewMappingMatrix;
- myView->GetMatrices (theOrientation, theViewMapping);
+ myView->GetMatrices (aOrientationMatrix,
+ aViewMappingMatrix);
- NCollection_Mat4<GLdouble> aOrientationMatrix;
- NCollection_Mat4<GLdouble> 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];
- NCollection_Mat4<GLdouble> anInvModelProj;
+ OpenGl_Mat4 anUnviewMat;
UpdateCamera (aOrientationMatrix,
aViewMappingMatrix,
aOrigins,
aDirects,
- anInvModelProj);
-
- OpenGl_Matrix anInvModelProjMatrix;
- for (Standard_Integer j = 0; j < 4; ++j)
- {
- for (Standard_Integer i = 0; i < 4; ++i)
- {
- anInvModelProjMatrix.mat[j][i] = static_cast<GLfloat>(anInvModelProj.GetValue(i,j));
- }
- }
+ anUnviewMat);
Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
{
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,
- anInvModelProjMatrix,
+ 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);
}
+#ifdef USE_TEXTURES
+ #extension GL_ARB_bindless_texture : require
+#endif
+
//! Normalized pixel coordinates.
in vec2 vPixel;
uniform vec3 uDirectRB;
//! Inverse model-view-projection matrix.
-uniform mat4 uInvModelProj;
+uniform mat4 uUnviewMat;
+
//! Texture buffer of data records of high-level BVH nodes.
uniform isamplerBuffer uSceneNodeInfoTexture;
//! Texture buffer of minimum points of high-level BVH nodes.
uniform samplerBuffer uGeometryVertexTexture;
//! Texture buffer of vertex normals.
uniform samplerBuffer uGeometryNormalTexture;
+#ifdef USE_TEXTURES
+ //! Texture buffer of per-vertex UV-coordinates.
+ uniform samplerBuffer uGeometryTexCrdTexture;
+#endif
//! Texture buffer of triangle indices.
uniform isamplerBuffer uGeometryTriangTexture;
//! Scene epsilon to prevent self-intersections.
uniform float uSceneEpsilon;
+#ifdef USE_TEXTURES
+ //! Unique 64-bit handles of OpenGL textures.
+ uniform sampler2D uTextureSamplers[MAX_TEX_NUMBER];
+#endif
+
/////////////////////////////////////////////////////////////////////////////////////////
// Specific data types
#define AXIS_Y vec3 (0.0f, 1.0f, 0.0f)
#define AXIS_Z vec3 (0.0f, 0.0f, 1.0f)
-
// =======================================================================
// function : MatrixRowMultiplyDir
// purpose : Multiplies a vector by matrix
vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
return SRay (mix (aP0, aP1, thePixel.y), aDirection);
-
}
// =======================================================================
2.0f * vPixel.y - 1.0f,
2.0f * anOpenGlDepth - 1.0f,
1.0f);
- vec4 aFinal = uInvModelProj * aPoint;
+ vec4 aFinal = uUnviewMat * aPoint;
aFinal.xyz *= 1.f / aFinal.w;
return (anOpenGlDepth < 1.f) ? length (aFinal.xyz - theRay.Origin) : MAXFLOAT;
{
if (aHead == theSentinel)
return aTriIndex;
-
+
aNode = Stack[aHead--];
}
}
return aTriIndex;
}
-#define MATERIAL_AMBN(index) (7 * index + 0)
-#define MATERIAL_DIFF(index) (7 * index + 1)
-#define MATERIAL_SPEC(index) (7 * index + 2)
-#define MATERIAL_EMIS(index) (7 * index + 3)
-#define MATERIAL_REFL(index) (7 * index + 4)
-#define MATERIAL_REFR(index) (7 * index + 5)
-#define MATERIAL_TRAN(index) (7 * index + 6)
+#define MATERIAL_AMBN(index) (11 * index + 0)
+#define MATERIAL_DIFF(index) (11 * index + 1)
+#define MATERIAL_SPEC(index) (11 * index + 2)
+#define MATERIAL_EMIS(index) (11 * index + 3)
+#define MATERIAL_REFL(index) (11 * index + 4)
+#define MATERIAL_REFR(index) (11 * index + 5)
+#define MATERIAL_TRAN(index) (11 * index + 6)
+#define MATERIAL_TRS1(index) (11 * index + 7)
+#define MATERIAL_TRS2(index) (11 * index + 8)
+#define MATERIAL_TRS3(index) (11 * index + 9)
// =======================================================================
// function : ObjectAnyHit
float aTimeOut;
float aTimeLft;
float aTimeRgh;
-
+
aData.y += theBVHOffset;
aData.z += theBVHOffset;
{
vec3 aNormal;
vec2 aParams;
-
+
for (int anIdx = aData.y; anIdx <= aData.z; ++anIdx)
{
ivec4 aTriangle = texelFetch (uGeometryTriangTexture, anIdx + theTrgOffset);
return 0.0f;
#endif
}
-
+
#ifdef TRANSPARENT_SHADOWS
if (aHead == theSentinel || aFactor < 0.1f)
return aFactor;
{
vec3 aNodeMin = texelFetch (uSceneMinPointTexture, aNode).xyz;
vec3 aNodeMax = texelFetch (uSceneMaxPointTexture, aNode).xyz;
-
+
vec3 aTime0 = (aNodeMin - theRay.Origin) * theInverse;
vec3 aTime1 = (aNodeMax - theRay.Origin) * theInverse;
-
+
vec3 aTimes = min (aTime0, aTime1);
-
+
if (max (aTimes.x, max (aTimes.y, aTimes.z)) < theHit.Time)
{
// fetch object transformation
if (aHead < 0)
return aHitObject;
-
+
aNode = Stack[aHead--];
}
else // if inner node
#else
bool isShadow = 0.0f == ObjectAnyHit (
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
-
+
if (aHead < 0 || isShadow)
return isShadow ? 0.0f : 1.0f;
#endif
-
+
aNode = Stack[aHead--];
}
else // if inner node
}
}
}
-
+
#ifdef TRANSPARENT_SHADOWS
return aFactor;
#else
vec2 Latlong (in vec3 thePoint, in float theRadius)
{
float aPsi = acos (-thePoint.z / theRadius);
-
+
float aPhi = atan (thePoint.y, thePoint.x) + PI;
-
+
return vec2 (aPhi * 0.1591549f,
aPsi * 0.3183098f);
}
vec3 aNormal0 = texelFetch (uGeometryNormalTexture, theTriangle.x).xyz;
vec3 aNormal1 = texelFetch (uGeometryNormalTexture, theTriangle.y).xyz;
vec3 aNormal2 = texelFetch (uGeometryNormalTexture, theTriangle.z).xyz;
-
+
return normalize (aNormal1 * theUV.x +
aNormal2 * theUV.y +
aNormal0 * (1.0f - theUV.x - theUV.y));
}
+// =======================================================================
+// function : SmoothUV
+// purpose : Interpolates UV coordinates across the triangle
+// =======================================================================
+#ifdef USE_TEXTURES
+vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle)
+{
+ vec2 aTexCrd0 = texelFetch (uGeometryTexCrdTexture, theTriangle.x).st;
+ vec2 aTexCrd1 = texelFetch (uGeometryTexCrdTexture, theTriangle.y).st;
+ vec2 aTexCrd2 = texelFetch (uGeometryTexCrdTexture, theTriangle.z).st;
+
+ return aTexCrd1 * theUV.x +
+ aTexCrd2 * theUV.y +
+ aTexCrd0 * (1.0f - theUV.x - theUV.y);
+}
+#endif
+
// =======================================================================
// function : Refract
// purpose : Computes refraction ray (also handles TIR)
in float theRefractIndex,
in float theInvRefractIndex)
{
- float aNdotI = dot (theInput, theNormal);
-
+ float aNdotI = dot (theInput, theNormal);
+
float anIndex = aNdotI < 0.0f
? theInvRefractIndex
: theRefractIndex;
-
+
float aSquare = anIndex * anIndex * (1.0f - aNdotI * aNdotI);
-
+
if (aSquare > 1.0f)
{
return reflect (theInput, theNormal);
}
-
+
float aNdotT = sqrt (1.0f - aSquare);
-
+
return normalize (anIndex * theInput -
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
}
// =======================================================================
// function : Radiance
-// purpose : Computes color of specified ray
+// purpose : Computes color along the given ray
// =======================================================================
vec4 Radiance (in SRay theRay, in vec3 theInverse)
{
float anOpenGlDepth = ComputeOpenGlDepth (theRay);
- vec3 aViewDir = theRay.Direct;
-
- for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth)
+ for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
{
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
if (aTriIndex.x == -1)
{
+ vec4 aColor = vec4 (0.0f, 0.0f, 0.0f, 1.0f);
+
if (aWeight.w != 0.0f)
{
- if (anOpenGlDepth < MAXFLOAT)
- {
- vec4 anOpenGlColor = ComputeOpenGlColor (theRay);
- aResult.xyz += aWeight.xyz * anOpenGlColor.xyz;
- aWeight.w *= anOpenGlColor.w;
- }
- return vec4 (aResult.x,
- aResult.y,
- aResult.z,
- aWeight.w);
+ if (anOpenGlDepth != MAXFLOAT)
+ aColor = ComputeOpenGlColor (theRay);
}
-
- if (bool(uEnvironmentEnable))
+ else if (bool(uEnvironmentEnable))
{
float aTime = IntersectSphere (theRay, uSceneRadius);
-
- aResult.xyz += aWeight.xyz * textureLod (uEnvironmentMapTexture,
- Latlong (theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f).xyz;
+
+ aColor = textureLod (uEnvironmentMapTexture, Latlong (
+ theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f);
}
-
- return vec4 (aResult.x,
- aResult.y,
- aResult.z,
- aWeight.w);
+
+ return vec4 (aResult.xyz + aWeight.xyz * aColor.xyz, aWeight.w * aColor.w);
}
aHit.Normal = normalize (aHit.Normal);
-
- if (anOpenGlDepth != MAXFLOAT)
- {
- float aDepthSlope = dot (theRay.Direct, aHit.Normal);
-
- // For polygons that are parallel to the screen plane, the depth slope
- // is equal to 1, resulting in small polygon offset. For polygons that
- // that are at a large angle to the screen, the depth slope tends to 1,
- // resulting in a larger polygon offset
- float aPolygonOffset = uSceneEpsilon * EPS_SCALE / max (MIN_SLOPE, abs (aDepthSlope));
- if (anOpenGlDepth - aPolygonOffset < aHit.Time)
- {
- vec4 aColor = ComputeOpenGlColor (theRay);
-
- aResult.xyz += aWeight.xyz * aColor.xyz;
- aWeight *= aColor.w;
-
- if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
- {
- return vec4 (aResult.x,
- aResult.y,
- aResult.z,
- aWeight.w);
- }
- }
+ // For polygons that are parallel to the screen plane, the depth slope
+ // is equal to 1, resulting in small polygon offset. For polygons that
+ // that are at a large angle to the screen, the depth slope tends to 1,
+ // resulting in a larger polygon offset
+ float aPolygonOffset = uSceneEpsilon * min (
+ EPS_SCALE / abs (dot (theRay.Direct, aHit.Normal)), EPS_SCALE / MIN_SLOPE);
+
+ if (anOpenGlDepth - aPolygonOffset < aHit.Time)
+ {
+ vec4 aColor = ComputeOpenGlColor (theRay);
+
+ aResult += aWeight.xyz * aColor.xyz;
+ aWeight *= aColor.w;
}
vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
-
+
vec3 aAmbient = texelFetch (
uRaytraceMaterialTexture, MATERIAL_AMBN (aTriIndex.w)).rgb;
- vec3 aDiffuse = texelFetch (
- uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w)).rgb;
+ vec4 aDiffuse = texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w));
vec4 aSpecular = texelFetch (
uRaytraceMaterialTexture, MATERIAL_SPEC (aTriIndex.w));
vec4 aOpacity = texelFetch (
uRaytraceMaterialTexture, MATERIAL_TRAN (aTriIndex.w));
vec3 aEmission = texelFetch (
uRaytraceMaterialTexture, MATERIAL_EMIS (aTriIndex.w)).rgb;
-
- vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
+
+#ifdef USE_TEXTURES
+ if (aDiffuse.w >= 0.f)
+ {
+ vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriIndex), 0.f, 1.f);
+
+ vec4 aTrsfRow1 = texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriIndex.w));
+ vec4 aTrsfRow2 = texelFetch (
+ uRaytraceMaterialTexture, MATERIAL_TRS2 (aTriIndex.w));
+
+ aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),
+ dot (aTrsfRow2, aTexCoord));
+
+ vec3 aTexColor = textureLod (
+ uTextureSamplers[int(aDiffuse.w)], aTexCoord.st, 0.f).rgb;
+
+ aDiffuse.rgb *= aTexColor;
+ aAmbient.rgb *= aTexColor;
+ }
+#endif
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
+ vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
+
aNormal = normalize (MatrixRowMultiplyDir (
aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
if (bool(uShadowsEnable))
{
vec3 aInverse = 1.0f / max (abs (aLight.xyz), SMALL);
-
+
aInverse.x = aLight.x < 0.0f ? -aInverse.x : aInverse.x;
aInverse.y = aLight.y < 0.0f ? -aInverse.y : aInverse.y;
aInverse.z = aLight.z < 0.0f ? -aInverse.z : aInverse.z;
-
+
aVisibility = SceneAnyHit (aShadow, aInverse, aDistance);
}
{
vec3 aIntensity = vec3 (texelFetch (
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx)));
-
+
float aLdotN = dot (aShadow.Direct, aNormal);
-
+
if (aOpacity.y > 0.0f) // force two-sided lighting
aLdotN = abs (aLdotN); // for transparent surfaces
-
+
if (aLdotN > 0.0f)
{
float aRdotV = dot (reflect (aShadow.Direct, aNormal), theRay.Direct);
-
+
aResult.xyz += aWeight.xyz * (aOpacity.x * aVisibility) * aIntensity *
- (aDiffuse * aLdotN + aSpecular.xyz * pow (max (0.0f, aRdotV), aSpecular.w));
+ (aDiffuse.rgb * aLdotN + aSpecular.xyz * pow (max (0.0f, aRdotV), aSpecular.w));
}
}
}
-
- aResult.xyz += aWeight.xyz * uGlobalAmbient.xyz *
- aAmbient * aOpacity.x * max (abs (dot (aNormal, theRay.Direct)), 0.5f);
- aResult.xyz += aWeight.xyz * aOpacity.x * aEmission;
-
+ aResult.xyz += aWeight.xyz * aOpacity.x * (uGlobalAmbient.xyz *
+ aAmbient * max (abs (dot (aNormal, theRay.Direct)), 0.5f) + aEmission);
+
if (aOpacity.x != 1.0f)
{
aWeight *= aOpacity.y;
theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
-
+
theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
-
+
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
-
+
// Disable combining image with OpenGL output
anOpenGlDepth = MAXFLOAT;
}
{
aWeight *= bool(uReflectionsEnable) ?
texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.0f);
-
+
theRay.Direct = reflect (theRay.Direct, aNormal);
-
+
if (dot (theRay.Direct, aHit.Normal) < 0.0f)
{
theRay.Direct = reflect (theRay.Direct, aHit.Normal);
}
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
-
+
theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
-
+
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
// Disable combining image with OpenGL output
anOpenGlDepth = MAXFLOAT;
}
-
+
if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
{
return vec4 (aResult.x,
aResult.z,
aWeight.w);
}
-
+
theRay.Origin = theRay.Direct * uSceneEpsilon + aPoint;
}
--- /dev/null
+puts "========"
+puts "Ray Tracing - check refraction"
+puts "========"
+
+vinit View1
+vclear
+vrenderparams -rasterization
+vsetdispmode 1
+vsetgradientbg 180 200 255 180 180 180 2
+
+box wall1 1 8 8
+box wall2 1 8 8
+box wall3 16 8 1
+
+psphere S1 1.5
+psphere S2 1.5
+psphere S3 1.5
+
+box B1 -1.5 -1.5 -1.5 2.5 2 3
+box B2 -1.5 -1.5 -1.5 2.5 2 3
+box B3 -1.5 -1.5 -1.5 2.5 2 3
+
+vdisplay S1
+vdisplay S2
+vdisplay S3
+
+vdisplay B1
+vdisplay B2
+vdisplay B3
+
+vdisplay wall1
+vdisplay wall2
+vdisplay wall3
+
+vtexture S1 8
+vtexture S2 2
+vtexture S3 3
+
+vtexture B1 4
+vtexture B2 5
+vtexture B3 6
+
+vsetlocation S1 2 2 4
+vsetlocation S2 -2 2 4
+vsetlocation S3 -6 2 4
+
+vsetlocation B1 2 6 4
+vsetlocation B2 -2 6 4
+vsetlocation B3 -6 6 4
+
+vsetlocation wall1 -10 0 0
+vsetlocation wall2 5 0 0
+vsetlocation wall3 -10 0 -1
+
+vsetmaterial S1 gold
+vsetmaterial S2 silver
+vsetmaterial S3 copper
+
+vsetmaterial B1 steel
+vsetmaterial B2 pewter
+vsetmaterial B3 chrome
+
+vsetmaterial wall1 stone
+vsetmaterial wall2 stone
+vsetmaterial wall3 pewter
+
+vsetcolor wall1 red
+vsetcolor wall2 green
+
+vright
+vturnview 0 -0.3 0
+vfit
+vlight change 0 pos 1 1 1
+vlight add directional
+vrenderparams -raytrace -raydepth 3 -shadows on -reflections -fsaa