1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0024819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and point sprites

OpenGl_GraphicDriver::Redraw() - do not recompute structures more than required
OpenGl_Workspace::Raytrace() - bind proper FBO before clearing it
Visual3d_View::Redraw() - perform automatic 2nd redraw on device lost
This commit is contained in:
osa 2014-07-03 15:49:48 +04:00 committed by apn
parent 8d3865d870
commit a89742cf17
11 changed files with 508 additions and 93 deletions

View File

@ -103,7 +103,9 @@ void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView,
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)
{

View File

@ -352,6 +352,17 @@ namespace OpenGl_Raytrace
&& 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

View File

@ -20,6 +20,7 @@
#include <BVH_Triangulation.hxx>
#include <NCollection_StdAllocator.hxx>
class OpenGl_Element;
struct OpenGl_ElementNode;
class OpenGl_Group;
class OpenGl_Structure;
@ -33,6 +34,9 @@ namespace OpenGl_Raytrace
//! 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);
}

View File

@ -221,6 +221,7 @@ protected:
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
@ -296,6 +297,8 @@ public:
DEFINE_STANDARD_ALLOC
DEFINE_STANDARD_RTTI(OpenGl_View) // Type definition
friend class OpenGl_Workspace;
};
#endif // _OpenGl_View_Header

View File

@ -453,7 +453,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
// ====================================
// Render background
DrawBackground (*theWorkspace);
if (theWorkspace->ToRedrawGL())
{
DrawBackground (*theWorkspace);
}
// Switch off lighting by default
glDisable(GL_LIGHTING);
@ -600,26 +603,22 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
OpenGl_ShaderProgram::Unbind (aContext);
}
// display global trihedron
if (myTrihedron != NULL)
// Render trihedron
if (theWorkspace->ToRedrawGL())
{
myTrihedron->Render (theWorkspace);
}
if (myGraduatedTrihedron != NULL)
{
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 );
}
// ===============================
@ -846,6 +845,21 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
/*----------------------------------------------------------------------*/
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)

View File

@ -151,6 +151,8 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
myViewModificationStatus (0),
myLayersModificationStatus (0),
//
myRaytraceFilter (new OpenGl_RaytraceFilter()),
myToRedrawGL (Standard_True),
myAntiAliasingMode (3),
myTransientDrawToFront (Standard_True),
myBackBufferRestored (Standard_False),
@ -160,6 +162,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
myUseDepthTest (Standard_True),
myUseGLLight (Standard_True),
myIsCullingEnabled (Standard_False),
myFrameCounter (0),
//
AspectLine_set (&myDefaultAspectLine),
AspectLine_applied (NULL),
@ -561,6 +564,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
return;
}
++myFrameCounter;
myIsCullingEnabled = theCView.IsCullingEnabled;
// release pending GL resources
@ -577,12 +581,67 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
{
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)
@ -592,15 +651,6 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
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)
{
@ -670,15 +720,24 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
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);
@ -694,9 +753,9 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
}
else
{
glFlush();
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
glFlush(); //
myBackBufferRestored = Standard_True;//
myIsImmediateDrawn = Standard_False;//
}
}

View File

@ -93,6 +93,37 @@ struct OpenGl_Material
};
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
@ -228,6 +259,9 @@ public:
//! @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
@ -277,6 +311,7 @@ protected:
OpenGl_RT_uDirectLB,
OpenGl_RT_uDirectRT,
OpenGl_RT_uDirectRB,
OpenGl_RT_uInvModelProj,
OpenGl_RT_uSceneRad,
OpenGl_RT_uSceneEps,
@ -320,7 +355,10 @@ protected:
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.
@ -489,7 +527,8 @@ protected: //! @name methods related to ray-tracing
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,
@ -497,6 +536,7 @@ protected: //! @name methods related to ray-tracing
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.
@ -504,6 +544,8 @@ protected: //! @name methods related to 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
@ -575,6 +617,8 @@ 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;
@ -590,6 +634,12 @@ protected: //! @name fields related to ray-tracing
//! 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;
@ -605,6 +655,8 @@ protected: //! @name protected fields
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;

View File

@ -221,7 +221,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
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();
@ -1402,6 +1402,11 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
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,
@ -1427,6 +1432,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
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");
@ -1506,6 +1513,7 @@ inline void NullifyResource (const Handle(OpenGl_Context)& theContext,
// =======================================================================
void OpenGl_Workspace::ReleaseRaytraceResources()
{
NullifyResource (myGlContext, myOpenGlFBO);
NullifyResource (myGlContext, myRaytraceFBO1);
NullifyResource (myGlContext, myRaytraceFBO2);
@ -1869,12 +1877,11 @@ Standard_Boolean OpenGl_Workspace::ResizeRaytraceBuffers (const Standard_Integer
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;
@ -1888,7 +1895,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
-1.0,
1.0);
aOrigin = aInvModelProj * aOrigin;
aOrigin = theInvModelProj * aOrigin;
aOrigin.x() = aOrigin.x() / aOrigin.w();
aOrigin.y() = aOrigin.y() / aOrigin.w();
@ -1899,7 +1906,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
1.0,
1.0);
aDirect = aInvModelProj * aDirect;
aDirect = theInvModelProj * aDirect;
aDirect.x() = aDirect.x() / aDirect.w();
aDirect.y() = aDirect.y() / aDirect.w();
@ -1931,6 +1938,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
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);
@ -1942,9 +1950,12 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
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
{
@ -1974,6 +1985,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
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,
@ -2002,6 +2015,23 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
{
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;
}
@ -2025,6 +2055,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
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,
@ -2099,6 +2131,23 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
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;
}
@ -2111,11 +2160,10 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
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;
@ -2151,17 +2199,33 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
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);
@ -2176,16 +2240,17 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
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);
@ -2200,6 +2265,7 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
theSizeY,
aOrigins,
aDirects,
anInvModelProjMatrix,
theFrameBuffer);
myRaytraceScreenQuad.Unbind (myGlContext);
@ -2211,6 +2277,20 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
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)
{
@ -2224,3 +2304,21 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
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);
}

View File

@ -19,6 +19,8 @@ uniform vec3 uDirectRT;
//! 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.
@ -49,6 +51,11 @@ uniform samplerBuffer uRaytraceLightSrcTexture;
//! 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.
@ -160,9 +167,44 @@ SRay GenerateRay (in vec2 thePixel)
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;
}
// =======================================================================
@ -320,7 +362,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
if (aTime < theHit.Time)
{
aTriIndex = aTriangle;
theHit = SIntersect (aTime, aParams, aNormal);
}
}
@ -776,6 +818,9 @@ vec3 Refract (in vec3 theInput,
(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)
@ -791,17 +836,27 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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,
@ -821,7 +876,36 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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 (
@ -841,9 +925,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
aNormal = normalize (MatrixRowMultiplyDir (
aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
aHit.Normal = normalize (aHit.Normal);
for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
{
vec4 aLight = texelFetch (
@ -902,18 +984,25 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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
@ -925,7 +1014,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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);
@ -935,6 +1024,9 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
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)))

View File

@ -1051,35 +1051,43 @@ void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
return;
}
if (MyGraphicDriver->IsDeviceLost())
{
MyViewManager->RecomputeStructures();
MyViewManager->RecomputeStructures (myImmediateStructures);
MyGraphicDriver->ResetDeviceLostFlag();
}
// set up Z buffer state before redrawing
if (MyViewManager->ZBufferAuto())
{
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);
for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
{
if (MyGraphicDriver->IsDeviceLost())
{
MyViewManager->RecomputeStructures();
MyViewManager->RecomputeStructures (myImmediateStructures);
MyGraphicDriver->ResetDeviceLostFlag();
}
// set up Z buffer state before redrawing
if (MyViewManager->ZBufferAuto())
{
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);
}
}
MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
if (!MyGraphicDriver->IsDeviceLost())
{
return;
}
}
}
void Visual3d_View::RedrawImmediate()

View File

@ -0,0 +1,72 @@
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
}
}
}