const Standard_Integer /*width*/,
const Standard_Integer /*height*/)
{
- if (!myCaps->vboDisable && ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING)
+ if (ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING
+ && !myCaps->vboDisable
+ && !myCaps->keepArrayData)
{
if (ACView.WasRedrawnGL)
{
&& anArray->DrawMode() >= GL_TRIANGLES;
}
+ // =======================================================================
+ // function : IsRaytracedElement
+ // purpose : Checks to see if the element contains ray-trace geometry
+ // =======================================================================
+ Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement)
+ {
+ const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
+ return anArray != NULL
+ && anArray->DrawMode() >= GL_TRIANGLES;
+ }
+
// =======================================================================
// function : IsRaytracedGroup
// purpose : Checks to see if the group contains ray-trace geometry
#include <BVH_Triangulation.hxx>
#include <NCollection_StdAllocator.hxx>
+class OpenGl_Element;
struct OpenGl_ElementNode;
class OpenGl_Group;
class OpenGl_Structure;
//! Checks to see if the element contains ray-trace geometry.
Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode);
+ //! Checks to see if the element contains ray-trace geometry.
+ Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement);
+
//! Checks to see if the structure contains ray-trace geometry.
Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure);
}
void RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
const Graphic3d_CView& theCView,
const Aspect_CLayer2d& theCLayer);
+ void RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);
//! Redraw contents of model scene: clipping planes,
//! lights, structures. The peculiar properties of "scene" is that
DEFINE_STANDARD_ALLOC
DEFINE_STANDARD_RTTI(OpenGl_View) // Type definition
+ friend class OpenGl_Workspace;
+
};
#endif // _OpenGl_View_Header
// ====================================
// Render background
- DrawBackground (*theWorkspace);
+ if (theWorkspace->ToRedrawGL())
+ {
+ DrawBackground (*theWorkspace);
+ }
// Switch off lighting by default
glDisable(GL_LIGHTING);
OpenGl_ShaderProgram::Unbind (aContext);
}
- // display global trihedron
- if (myTrihedron != NULL)
- {
- myTrihedron->Render (theWorkspace);
- }
- if (myGraduatedTrihedron != NULL)
+ // Render trihedron
+ if (theWorkspace->ToRedrawGL())
{
- myGraduatedTrihedron->Render (theWorkspace);
- }
+ RedrawTrihedron (theWorkspace);
- // Restore face culling
- if ( myBackfacing )
- {
- if ( isCullFace )
+ // Restore face culling
+ if ( myBackfacing )
{
- glEnable ( GL_CULL_FACE );
- glCullFace ( GL_BACK );
+ if ( isCullFace )
+ {
+ glEnable ( GL_CULL_FACE );
+ glCullFace ( GL_BACK );
+ }
+ else
+ glDisable ( GL_CULL_FACE );
}
- else
- glDisable ( GL_CULL_FACE );
}
// ===============================
/*----------------------------------------------------------------------*/
+void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
+{
+ // display global trihedron
+ if (myTrihedron != NULL)
+ {
+ myTrihedron->Render (theWorkspace);
+ }
+ if (myGraduatedTrihedron != NULL)
+ {
+ myGraduatedTrihedron->Render (theWorkspace);
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
//call_togl_create_bg_texture
void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
const Aspect_FillMethod theFillStyle)
myViewModificationStatus (0),
myLayersModificationStatus (0),
//
+ myRaytraceFilter (new OpenGl_RaytraceFilter()),
+ myToRedrawGL (Standard_True),
myAntiAliasingMode (3),
myTransientDrawToFront (Standard_True),
myBackBufferRestored (Standard_False),
myUseDepthTest (Standard_True),
myUseGLLight (Standard_True),
myIsCullingEnabled (Standard_False),
+ myFrameCounter (0),
//
AspectLine_set (&myDefaultAspectLine),
AspectLine_applied (NULL),
return;
}
+ ++myFrameCounter;
myIsCullingEnabled = theCView.IsCullingEnabled;
// release pending GL resources
{
glGetIntegerv (GL_VIEWPORT, aViewPortBack);
aFrameBuffer->SetupViewport (aGlCtx);
- aFrameBuffer->BindBuffer (aGlCtx);
toSwap = 0; // no need to swap buffers
}
- if (theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myComputeInitStatus == OpenGl_RT_FAIL)
+ myToRedrawGL = Standard_True;
+ if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
+ && myComputeInitStatus != OpenGl_RT_FAIL)
{
+ if (UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid)
+ {
+ myToRedrawGL = Standard_False;
+
+ // Only non-raytracable structures should be rendered in OpenGL mode.
+ Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter();
+ myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
+ SetRenderFilter (myRaytraceFilter);
+
+ Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
+ Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
+
+ if (myOpenGlFBO.IsNull())
+ {
+ myOpenGlFBO = new OpenGl_FrameBuffer();
+ }
+ if (myOpenGlFBO->GetVPSizeX() != aSizeX
+ || myOpenGlFBO->GetVPSizeY() != aSizeY)
+ {
+ myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY);
+ }
+
+ // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
+ // They will be drawn during ray-tracing.
+ Aspect_CLayer2d anEmptyCLayer;
+ anEmptyCLayer.ptrLayer = NULL;
+
+ myOpenGlFBO->BindBuffer (aGlCtx);
+ redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
+ myOpenGlFBO->UnbindBuffer (aGlCtx);
+
+ const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
+ Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
+ theCOverLayer, theCUnderLayer, aFrameBuffer);
+
+ if (isImmediate)
+ {
+ RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+ }
+
+ SetRenderFilter (aRenderFilter);
+
+ theCView.WasRedrawnGL = Standard_False;
+ }
+ }
+
+ if (myToRedrawGL)
+ {
+ // draw entire frame using normal OpenGL pipeline
+ if (aFrameBuffer != NULL)
+ {
+ aFrameBuffer->BindBuffer (aGlCtx);
+ }
+
const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
if (isImmediate)
theCView.WasRedrawnGL = Standard_True;
}
- else
- {
- int aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
- int aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
-
- Raytrace (theCView, aSizeX, aSizeY, toSwap, aFrameBuffer);
-
- theCView.WasRedrawnGL = Standard_False;
- }
if (aFrameBuffer != NULL)
{
glDisable (GL_DEPTH_TEST);
}
- if (NamedStatus & OPENGL_NS_WHITEBACK)
+ if (!ToRedrawGL())
{
- // set background to white
- glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
- toClear |= GL_DEPTH_BUFFER_BIT;
+ // set background to black
+ glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
+ toClear |= GL_DEPTH_BUFFER_BIT; //
}
else
{
- glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
+ if (NamedStatus & OPENGL_NS_WHITEBACK)
+ {
+ // set background to white
+ glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+ toClear |= GL_DEPTH_BUFFER_BIT;
+ }
+ else
+ {
+ glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
+ }
}
glClear (toClear);
}
else
{
- glFlush();
- myBackBufferRestored = Standard_True;
- myIsImmediateDrawn = Standard_False;
+ glFlush(); //
+ myBackBufferRestored = Standard_True;//
+ myIsImmediateDrawn = Standard_False;//
}
}
};
+DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+//! Graphical raytracing filter.
+//! Filters out all raytracable structures.
+class OpenGl_RaytraceFilter : public OpenGl_RenderFilter
+{
+public:
+
+ //! Default constructor.
+ OpenGl_RaytraceFilter() {}
+
+ //! Remembers the previously set filter.
+ inline void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
+ {
+ myPrevRenderFilter = theFilter;
+ }
+
+ //! Checks whether the element can be rendered or not.
+ //! @param theElement [in] the element to check.
+ //! @return True if element can be rendered.
+ virtual Standard_Boolean CanRender (const OpenGl_Element* theElement);
+
+private:
+
+ Handle(OpenGl_RenderFilter) myPrevRenderFilter;
+
+public:
+
+ DEFINE_STANDARD_RTTI(OpenGl_RaytraceFilter)
+};
+
//! Represents window with GL context.
//! Provides methods to render primitives and maintain GL state.
class OpenGl_Workspace : public OpenGl_Window
//! @return true if clipping algorithm enabled
inline Standard_Boolean IsCullingEnabled() const { return myIsCullingEnabled; }
+ //! Returns a flag whether to redraw the scene using OpenGL rasterization
+ Standard_Boolean ToRedrawGL() const { return myToRedrawGL; }
+
protected:
//! Copy content of Back buffer to the Front buffer
OpenGl_RT_uDirectLB,
OpenGl_RT_uDirectRT,
OpenGl_RT_uDirectRB,
+ OpenGl_RT_uInvModelProj,
OpenGl_RT_uSceneRad,
OpenGl_RT_uSceneEps,
OpenGl_RT_FSAAInputTexture = 12,
- OpenGl_RT_SceneTransformTexture = 13
+ OpenGl_RT_SceneTransformTexture = 13,
+
+ OpenGl_RT_OpenGlColorTexture = 14,
+ OpenGl_RT_OpenGlDepthTexture = 15
};
//! Tool class for management of shader sources.
void UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
const NCollection_Mat4<GLdouble>& theViewMapping,
OpenGl_Vec3 theOrigins[4],
- OpenGl_Vec3 theDirects[4]);
+ OpenGl_Vec3 theDirects[4],
+ NCollection_Mat4<GLdouble>& theInvModelProj);
//! 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,
OpenGl_FrameBuffer* theFrameBuffer);
//! Redraws the window using OpenGL/GLSL ray-tracing.
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Standard_Boolean theToSwap,
+ const Aspect_CLayer2d& theCOverLayer,
+ const Aspect_CLayer2d& theCUnderLayer,
OpenGl_FrameBuffer* theFrameBuffer);
protected: //! @name fields related to ray-tracing
Handle(OpenGl_FrameBuffer) myRaytraceFBO1;
//! Framebuffer (FBO) to perform adaptive FSAA.
Handle(OpenGl_FrameBuffer) myRaytraceFBO2;
+ //! Framebuffer (FBO) for pre-raytrace rendering by OpenGL.
+ Handle(OpenGl_FrameBuffer) myOpenGlFBO;
//! State of OpenGL view.
Standard_Size myViewModificationStatus;
//! Cached locations of frequently used uniform variables.
Standard_Integer myUniformLocations[2][OpenGl_RT_NbVariables];
+ //! Graphical raytracing filter to filter out all raytracable structures.
+ Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
+
+ //! Redraw the scene using OpenGL rasterization or raytracing?
+ Standard_Boolean myToRedrawGL;
+
protected: //! @name protected fields
Handle(OpenGl_PrinterContext) myPrintContext;
Standard_Boolean myUseGLLight;
Standard_Boolean myIsCullingEnabled; //!< frustum culling flag
+ unsigned int myFrameCounter; //!< redraw counter, for debugging
+
protected: //! @name fields related to status
Handle(OpenGl_RenderFilter) myRenderFilter;
const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
- myRaytraceSceneEpsilon = Max (1e-7f, 1e-4f * sqrtf (
+ myRaytraceSceneEpsilon = Max (1e-6f, 1e-4f * sqrtf (
aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
return UploadRaytraceData();
aShaderProgram->SetSampler (myGlContext,
"uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
+ aShaderProgram->SetSampler (myGlContext,
+ "uOpenGlDepthTexture", OpenGl_RT_OpenGlDepthTexture);
+
if (anIndex == 1)
{
aShaderProgram->SetSampler (myGlContext,
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");
// =======================================================================
void OpenGl_Workspace::ReleaseRaytraceResources()
{
+ NullifyResource (myGlContext, myOpenGlFBO);
NullifyResource (myGlContext, myRaytraceFBO1);
NullifyResource (myGlContext, myRaytraceFBO2);
void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
const NCollection_Mat4<GLdouble>& theViewMapping,
OpenGl_Vec3 theOrigins[4],
- OpenGl_Vec3 theDirects[4])
+ OpenGl_Vec3 theDirects[4],
+ NCollection_Mat4<GLdouble>& theInvModelProj)
{
- NCollection_Mat4<GLdouble> aInvModelProj;
-
// compute inverse model-view-projection matrix
- (theViewMapping * theOrientation).Inverted (aInvModelProj);
+ (theViewMapping * theOrientation).Inverted (theInvModelProj);
Standard_Integer aOriginIndex = 0;
Standard_Integer aDirectIndex = 0;
-1.0,
1.0);
- aOrigin = aInvModelProj * aOrigin;
+ aOrigin = theInvModelProj * aOrigin;
aOrigin.x() = aOrigin.x() / aOrigin.w();
aOrigin.y() = aOrigin.y() / aOrigin.w();
1.0,
1.0);
- aDirect = aInvModelProj * aDirect;
+ aDirect = theInvModelProj * aDirect;
aDirect.x() = aDirect.x() / aDirect.w();
aDirect.y() = aDirect.y() / aDirect.w();
const Standard_Integer theSizeY,
const OpenGl_Vec3 theOrigins[4],
const OpenGl_Vec3 theDirects[4],
+ const OpenGl_Matrix& theInvModelProj,
OpenGl_FrameBuffer* theFrameBuffer)
{
mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
myGeometryVertexTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
myGeometryNormalTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
myGeometryTriangTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myRaytraceMaterialTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
- mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+ myOpenGlFBO->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
{
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,
{
myRaytraceProgram->Unbind (myGlContext);
+ myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+ mySceneMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+ myObjectMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+ myObjectMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+ myObjectNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+ myGeometryVertexTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+ myGeometryTriangTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ 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_True;
}
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_aPosition]);
myPostFSAAProgram->Unbind (myGlContext);
+ myRaytraceFBO1->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+ myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+ myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+ mySceneMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+ myObjectMinPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+ myObjectMaxPointTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+ myObjectNodeInfoTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+ myGeometryVertexTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+ myGeometryTriangTexture->UnbindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+ 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_True;
}
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Standard_Boolean theToSwap,
+ const Aspect_CLayer2d& theCOverLayer,
+ const Aspect_CLayer2d& theCUnderLayer,
OpenGl_FrameBuffer* theFrameBuffer)
{
- if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK))
- return Standard_False;
-
if (!InitRaytraceResources (theCView))
return Standard_False;
OpenGl_Vec3 aOrigins[4];
OpenGl_Vec3 aDirects[4];
+ NCollection_Mat4<GLdouble> anInvModelProj;
UpdateCamera (aOrientationMatrix,
aViewMappingMatrix,
aOrigins,
- aDirects);
+ 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));
+ }
+ }
Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
glDisable (GL_DEPTH_TEST);
+ if (theFrameBuffer != NULL)
+ {
+ theFrameBuffer->BindBuffer (myGlContext);
+ }
+
if (NamedStatus & OPENGL_NS_WHITEBACK)
{
glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
glClear (GL_COLOR_BUFFER_BIT);
- if (theFrameBuffer != NULL)
- theFrameBuffer->BindBuffer (myGlContext);
-
myView->DrawBackground (*this);
+ myView->RedrawLayer2d (myPrintContext, theCView, theCUnderLayer);
+
// Generate ray-traced image
glMatrixMode (GL_PROJECTION);
+ glPushMatrix();
glLoadIdentity();
glMatrixMode (GL_MODELVIEW);
+ glPushMatrix();
glLoadIdentity();
glEnable (GL_BLEND);
theSizeY,
aOrigins,
aDirects,
+ anInvModelProjMatrix,
theFrameBuffer);
myRaytraceScreenQuad.Unbind (myGlContext);
if (wasDepthTestEnabled)
glEnable (GL_DEPTH_TEST);
+ glMatrixMode (GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode (GL_MODELVIEW);
+ glPopMatrix();
+
+ // Redraw trihedron
+ myView->RedrawTrihedron (this);
+
+ // Redraw overlay
+ const int aMode = 0;
+ DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
+ myView->RedrawLayer2d (myPrintContext, theCView, theCOverLayer);
+ DisplayCallback (theCView, aMode);
+
// Swap the buffers
if (theToSwap)
{
return Standard_True;
}
+
+IMPLEMENT_STANDARD_HANDLE(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+// =======================================================================
+// function : CanRender
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
+{
+ Standard_Boolean aPrevFilterResult = Standard_True;
+ if (!myPrevRenderFilter.IsNull())
+ {
+ aPrevFilterResult = myPrevRenderFilter->CanRender(theElement);
+ }
+ return aPrevFilterResult &&
+ !OpenGl_Raytrace::IsRaytracedElement (theElement);
+}
//! Direction of viewing ray in right-bottom corner.
uniform vec3 uDirectRB;
+//! Inverse model-view-projection matrix.
+uniform mat4 uInvModelProj;
//! Texture buffer of data records of high-level BVH nodes.
uniform isamplerBuffer uSceneNodeInfoTexture;
//! Texture buffer of minimum points of high-level BVH nodes.
//! Environment map texture.
uniform sampler2D uEnvironmentMapTexture;
+//! Input pre-raytracing image rendered by OpenGL.
+uniform sampler2D uOpenGlColorTexture;
+//! Input pre-raytracing depth image rendered by OpenGL.
+uniform sampler2D uOpenGlDepthTexture;
+
//! Total number of light sources.
uniform int uLightCount;
//! Intensity of global ambient light.
vec3 aD0 = mix (uDirectLB, uDirectRB, thePixel.x);
vec3 aD1 = mix (uDirectLT, uDirectRT, thePixel.x);
-
- return SRay (mix (aP0, aP1, thePixel.y),
- mix (aD0, aD1, thePixel.y));
+
+ vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
+
+ return SRay (mix (aP0, aP1, thePixel.y), aDirection);
+
+}
+
+// =======================================================================
+// function : ComputeOpenGlDepth
+// purpose :
+// =======================================================================
+float ComputeOpenGlDepth (in SRay theRay)
+{
+ // a depth in range [0,1]
+ float anOpenGlDepth = texelFetch (uOpenGlDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
+ // pixel point in NDC-space [-1,1]
+ vec4 aPoint = vec4 (2.0f * vPixel.x - 1.0f,
+ 2.0f * vPixel.y - 1.0f,
+ 2.0f * anOpenGlDepth - 1.0f,
+ 1.0f);
+ vec4 aFinal = uInvModelProj * aPoint;
+ aFinal.xyz *= 1.f / aFinal.w;
+
+ return (anOpenGlDepth < 1.f) ? length (aFinal.xyz - theRay.Origin) : MAXFLOAT;
+}
+
+// =======================================================================
+// function : ComputeOpenGlColor
+// purpose :
+// =======================================================================
+vec4 ComputeOpenGlColor (in SRay theRay)
+{
+ vec4 anOpenGlColor = texelFetch (uOpenGlColorTexture, ivec2 (gl_FragCoord.xy), 0);
+ // During blending with factors GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA (for text and markers)
+ // the alpha channel (written in the color buffer) was squared.
+ anOpenGlColor.a = 1.f - sqrt (anOpenGlColor.a);
+
+ return anOpenGlColor;
}
// =======================================================================
if (aTime < theHit.Time)
{
aTriIndex = aTriangle;
-
+
theHit = SIntersect (aTime, aParams, aNormal);
}
}
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
}
+#define MIN_SLOPE 0.0001f
+#define EPS_SCALE 8.0000f
+
#define THRESHOLD vec3 (0.1f)
#define LIGHT_POS(index) (2 * index + 1)
vec4 aWeight = vec4 (1.0f);
int anObjectId;
-
+
+ float anOpenGlDepth = ComputeOpenGlDepth (theRay);
+
+ vec3 aViewDir = theRay.Direct;
+
for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth)
{
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
-
+
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
if (aTriIndex.x == -1)
{
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,
aResult.z,
aWeight.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);
+ }
+ }
+ }
+
vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
vec3 aAmbient = texelFetch (
aNormal = normalize (MatrixRowMultiplyDir (
aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
-
- aHit.Normal = normalize (aHit.Normal);
-
+
for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
{
vec4 aLight = texelFetch (
if (aOpacity.x != 1.0f)
{
aWeight *= aOpacity.y;
-
+
if (aOpacity.z != 1.0f)
{
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);
+
+ aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
+
+ // Disable combining image with OpenGL output
+ anOpenGlDepth = MAXFLOAT;
+ }
+ else
+ {
+ anOpenGlDepth -= aHit.Time + uSceneEpsilon;
}
}
else
if (dot (theRay.Direct, aHit.Normal) < 0.0f)
{
- theRay.Direct = reflect (theRay.Direct, aHit.Normal);
+ theRay.Direct = reflect (theRay.Direct, aHit.Normal);
}
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
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;
}
- if (MyGraphicDriver->IsDeviceLost())
- {
- MyViewManager->RecomputeStructures();
- MyViewManager->RecomputeStructures (myImmediateStructures);
- MyGraphicDriver->ResetDeviceLostFlag();
- }
+ Aspect_CLayer2d anOverCLayer, anUnderCLayer;
+ anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
+ if (!theOverLayer .IsNull()) anOverCLayer = theOverLayer ->CLayer();
+ if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
- // set up Z buffer state before redrawing
- if (MyViewManager->ZBufferAuto())
+ for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
{
- const Standard_Boolean hasFacet = ContainsFacet();
- const Standard_Boolean hasZBuffer = ZBufferIsActivated();
- // if the view contains facets and if ZBuffer is not active
- if (hasFacet && !hasZBuffer)
+ if (MyGraphicDriver->IsDeviceLost())
{
- SetZBufferActivity (1);
+ MyViewManager->RecomputeStructures();
+ MyViewManager->RecomputeStructures (myImmediateStructures);
+ MyGraphicDriver->ResetDeviceLostFlag();
}
- // if the view contains only facets and if ZBuffer is active
- if (!hasFacet && hasZBuffer)
+
+ // set up Z buffer state before redrawing
+ if (MyViewManager->ZBufferAuto())
{
- SetZBufferActivity (0);
+ const Standard_Boolean hasFacet = ContainsFacet();
+ const Standard_Boolean hasZBuffer = ZBufferIsActivated();
+ // if the view contains facets and if ZBuffer is not active
+ if (hasFacet && !hasZBuffer)
+ {
+ SetZBufferActivity (1);
+ }
+ // if the view contains only facets and if ZBuffer is active
+ if (!hasFacet && hasZBuffer)
+ {
+ SetZBufferActivity (0);
+ }
}
- }
- Aspect_CLayer2d anOverCLayer, anUnderCLayer;
- anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
- if (!theOverLayer .IsNull()) anOverCLayer = theOverLayer ->CLayer();
- if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
- MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
+ MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
+ if (!MyGraphicDriver->IsDeviceLost())
+ {
+ return;
+ }
+ }
}
void Visual3d_View::RedrawImmediate()
--- /dev/null
+puts "========"
+puts "OCC24819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and point sprites"
+puts "========"
+
+# setup 3D viewer content
+vinit name=View1 w=512 h=512
+vglinfo
+
+vvbo 0
+vsetdispmode 1
+vsetgradientbg 180 200 255 180 180 180 2
+# boxes
+box b1 1 1 1
+vdisplay b1
+vsetlocation b1 0 0 0.001
+vsetmaterial b1 Silver
+vsettransparency b1 0.5
+box b2 3 2 2 1 2 1
+vdisplay b2
+vsetmaterial b2 Pewter
+vsettransparency b2 0.8
+
+# brep text
+text2brep t "text" "Arial" 8
+vdisplay t
+
+# overlay objects
+voverlaytext "Overlay text!" 200 440 40
+
+# markers
+vpoint p 1 1 1
+vdisplay p
+vmarkerstest mTest 7 -3 0 PointsOnSide=5 MarkerType=5
+
+# 3d text
+vdrawtext 3D_Text 1 2 2 255 0 0 0 0 0 0 20 0
+
+vlight change 0 pos -1 1 1
+
+vfit
+
+# trihedron
+vzbufftrihedron
+
+# activate ray-tracing
+vrenderparams -raytrace
+
+# orthogonal projection
+set aModeNum 0
+foreach aFSAAMode {on off} {
+ foreach aReflMode {on off} {
+ foreach aShadMode {on off} {
+ vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode
+ vdump $imagedir/${casename}_${aModeNum}.png
+ incr aModeNum
+ }
+ }
+}
+
+# perspective projection
+vchangecamera proj persp
+set aModeNum 0
+foreach aFSAAMode {on off} {
+ foreach aReflMode {on off} {
+ foreach aShadMode {on off} {
+ vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode
+ vdump $imagedir/${casename}_${aModeNum}.png
+ incr aModeNum
+ }
+ }
+}
+