From 4c8faa5e2dd0d3e4bd7039c908016d8204889c09 Mon Sep 17 00:00:00 2001 From: drochalo Date: Fri, 3 Nov 2023 10:48:11 +0000 Subject: [PATCH] 0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer Added option to dump only a selection of zlayer's content. Changed zlayers redraw and render method for selection of layers to render. Added filters for layer parsing. Modified vdump command. Added test with multiple dumps for comparison. Added option to dump shadow maps. --- src/Graphic3d/Graphic3d_BufferType.hxx | 9 +-- src/Graphic3d/Graphic3d_CView.cxx | 3 + src/Graphic3d/Graphic3d_CView.hxx | 38 ++++++++--- src/OpenGl/OpenGl_FrameBuffer.cxx | 8 +-- src/OpenGl/OpenGl_LayerFilter.hxx | 1 + src/OpenGl/OpenGl_LayerList.cxx | 32 +++++++--- src/OpenGl/OpenGl_LayerList.hxx | 3 +- src/OpenGl/OpenGl_View.cxx | 79 +++++++++++++++++++++-- src/OpenGl/OpenGl_View.hxx | 6 ++ src/V3d/V3d_ImageDumpOptions.hxx | 33 ++++++---- src/V3d/V3d_View.cxx | 22 ++++++- src/V3d/V3d_View.hxx | 20 ++++-- src/ViewerTest/ViewerTest.cxx | 81 ++++++++++++++++++++++-- tests/v3d/bugs/bug32752 | 88 ++++++++++++++++++++++++++ 14 files changed, 365 insertions(+), 58 deletions(-) create mode 100644 tests/v3d/bugs/bug32752 diff --git a/src/Graphic3d/Graphic3d_BufferType.hxx b/src/Graphic3d/Graphic3d_BufferType.hxx index 99e449bca2..3e7e9f2a36 100644 --- a/src/Graphic3d/Graphic3d_BufferType.hxx +++ b/src/Graphic3d/Graphic3d_BufferType.hxx @@ -17,11 +17,12 @@ //! Define buffers available for dump enum Graphic3d_BufferType { - Graphic3d_BT_RGB, //!< color buffer without alpha component - Graphic3d_BT_RGBA, //!< color buffer - Graphic3d_BT_Depth, //!< depth buffer + Graphic3d_BT_RGB, //!< color buffer without alpha component + Graphic3d_BT_RGBA, //!< color buffer + Graphic3d_BT_Depth, //!< depth buffer Graphic3d_BT_RGB_RayTraceHdrLeft, //!< left view HDR color buffer for Ray-Tracing - Graphic3d_BT_Red, //!< color buffer, red channel + Graphic3d_BT_Red, //!< color buffer, red channel + Graphic3d_BT_ShadowMap, //!< buffer with shadow map }; #endif // _Graphic3d_BufferType_H__ diff --git a/src/Graphic3d/Graphic3d_CView.cxx b/src/Graphic3d/Graphic3d_CView.cxx index 59e0ee75a9..2a0be6b193 100644 --- a/src/Graphic3d/Graphic3d_CView.cxx +++ b/src/Graphic3d/Graphic3d_CView.cxx @@ -42,6 +42,9 @@ Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theM myBackfacing (Graphic3d_TypeOfBackfacingModel_Auto), myVisualization (Graphic3d_TOV_WIREFRAME), // + myZLayerTarget (Graphic3d_ZLayerId_BotOSD), + myZLayerRedrawMode (Standard_False), + // myBgColor (Quantity_NOC_BLACK), myBackgroundType (Graphic3d_TOB_NONE), myToUpdateSkydome (Standard_False), diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 5fe56d4467..abebcebc61 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -112,6 +112,18 @@ public: //! Sets visualization type of the view. void SetVisualizationType (const Graphic3d_TypeOfVisualization theType) { myVisualization = theType; } + //! Returns ZLayerId target + Graphic3d_ZLayerId ZLayerTarget() const { return myZLayerTarget; } + + //! Sets ZLayerId target. + void SetZLayerTarget (const Graphic3d_ZLayerId theTarget) { myZLayerTarget = theTarget; } + + //! Returns ZLayerId redraw mode + Standard_Boolean ZLayerRedrawMode() const { return myZLayerRedrawMode; } + + //! Sets ZLayerId redraw mode. + void SetZLayerRedrawMode (const Standard_Boolean theMode) { myZLayerRedrawMode = theMode; } + //! Switches computed HLR mode in the view Standard_EXPORT void SetComputedMode (const Standard_Boolean theMode); @@ -258,6 +270,11 @@ public: //! Dump active rendering buffer into specified memory buffer. virtual Standard_Boolean BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) = 0; + //! Dumps the graphical contents of a shadowmap framebuffer into an image. + //! @param theImage the image to store the shadow map. + //! @param theLightName [in] name of the light used to generate the shadow map. + virtual Standard_Boolean ShadowMapDump (Image_PixMap& theImage, const TCollection_AsciiString& theLightName) = 0; + //! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated. virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) = 0; @@ -638,15 +655,18 @@ protected: Graphic3d_Vec2d mySubviewOffset; //!< subview corner offset within parent view Handle(Graphic3d_StructureManager) myStructureManager; - Handle(Graphic3d_Camera) myCamera; - Graphic3d_SequenceOfStructure myStructsToCompute; - Graphic3d_SequenceOfStructure myStructsComputed; - Graphic3d_MapOfStructure myStructsDisplayed; - Standard_Boolean myIsInComputedMode; - Standard_Boolean myIsActive; - Standard_Boolean myIsRemoved; - Graphic3d_TypeOfBackfacingModel myBackfacing; - Graphic3d_TypeOfVisualization myVisualization; + Handle(Graphic3d_Camera) myCamera; + Graphic3d_SequenceOfStructure myStructsToCompute; + Graphic3d_SequenceOfStructure myStructsComputed; + Graphic3d_MapOfStructure myStructsDisplayed; + Standard_Boolean myIsInComputedMode; + Standard_Boolean myIsActive; + Standard_Boolean myIsRemoved; + Graphic3d_TypeOfBackfacingModel myBackfacing; + Graphic3d_TypeOfVisualization myVisualization; + + Graphic3d_ZLayerId myZLayerTarget; //!< ZLayerId for redrawing the content of specific zlayers. + Standard_Boolean myZLayerRedrawMode; //!< If true redraws single layer, otherwise redraws group of layers. Quantity_ColorRGBA myBgColor; Handle(Graphic3d_TextureMap) myBackgroundImage; diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index ca4ac757e2..0fdbe4ce81 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -978,7 +978,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t return false; } - aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED; + aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED; aType = GL_UNSIGNED_BYTE; break; } @@ -989,7 +989,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t return false; } - aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED; + aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED; aType = GL_UNSIGNED_SHORT; break; } @@ -1000,7 +1000,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t return false; } - aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED; + aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED; aType = GL_FLOAT; break; } @@ -1113,7 +1113,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t GLint aReadBufferPrev = GL_BACK; if (theGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES - && theBufferType == Graphic3d_BT_Depth + && (theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap) && aFormat != GL_DEPTH_COMPONENT) { return Standard_False; diff --git a/src/OpenGl/OpenGl_LayerFilter.hxx b/src/OpenGl/OpenGl_LayerFilter.hxx index 0531bf1b56..5483f0f3d2 100644 --- a/src/OpenGl/OpenGl_LayerFilter.hxx +++ b/src/OpenGl/OpenGl_LayerFilter.hxx @@ -23,6 +23,7 @@ enum OpenGl_LayerFilter OpenGl_LF_All, //!< process all layers OpenGl_LF_Upper, //!< process only top non-raytracable layers OpenGl_LF_Bottom, //!< process only Graphic3d_ZLayerId_BotOSD + OpenGl_LF_Single, //!< process single layer OpenGl_LF_RayTracable //!< process only normal raytracable layers (save the bottom layer) }; diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index 52a494d0e2..4cceccfdb5 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -58,10 +58,12 @@ namespace //! Main constructor. OpenGl_FilteredIndexedLayerIterator (const NCollection_List& theSeq, Standard_Boolean theToDrawImmediate, - OpenGl_LayerFilter theLayersToProcess) + OpenGl_LayerFilter theFilterMode, + Graphic3d_ZLayerId theLayersToProcess) : myIter (theSeq), - myLayersToProcess (theLayersToProcess), - myToDrawImmediate (theToDrawImmediate) + myFilterMode (theFilterMode), + myToDrawImmediate (theToDrawImmediate), + myLayersToProcess (theLayersToProcess) { next(); } @@ -94,11 +96,15 @@ namespace continue; } - switch (myLayersToProcess) + switch (myFilterMode) { case OpenGl_LF_All: { - return; + if (aLayer->LayerId() >= myLayersToProcess) + { + return; + } + break; } case OpenGl_LF_Upper: { @@ -119,6 +125,14 @@ namespace } break; } + case OpenGl_LF_Single: + { + if (aLayer->LayerId() == myLayersToProcess) + { + return; + } + break; + } case OpenGl_LF_RayTracable: { if (aLayer->LayerSettings().IsRaytracable() @@ -133,8 +147,9 @@ namespace } private: OpenGl_IndexedLayerIterator myIter; - OpenGl_LayerFilter myLayersToProcess; + OpenGl_LayerFilter myFilterMode; Standard_Boolean myToDrawImmediate; + Graphic3d_ZLayerId myLayersToProcess; }; static const Standard_Integer THE_DRAW_BUFFERS0[] = { GL_COLOR_ATTACHMENT0 }; @@ -714,7 +729,8 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace //======================================================================= void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, const Standard_Boolean theToDrawImmediate, - const OpenGl_LayerFilter theLayersToProcess, + const OpenGl_LayerFilter theFilterMode, + const Graphic3d_ZLayerId theLayersToProcess, OpenGl_FrameBuffer* theReadDrawFbo, OpenGl_FrameBuffer* theOitAccumFbo) const { @@ -750,7 +766,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, && !isShadowMapPass; const Handle(Graphic3d_LightSet) aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources(); const Handle(OpenGl_ShadowMapArray) aShadowMaps = aCtx->ShaderManager()->LightSourceState().ShadowMaps(); - for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();) + for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theFilterMode, theLayersToProcess); aLayerIterStart.More();) { bool hasSkippedDepthLayers = false; for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter) diff --git a/src/OpenGl/OpenGl_LayerList.hxx b/src/OpenGl/OpenGl_LayerList.hxx index 442364334d..eb614f55af 100644 --- a/src/OpenGl/OpenGl_LayerList.hxx +++ b/src/OpenGl/OpenGl_LayerList.hxx @@ -102,7 +102,8 @@ public: //! Render this element Standard_EXPORT void Render (const Handle(OpenGl_Workspace)& theWorkspace, const Standard_Boolean theToDrawImmediate, - const OpenGl_LayerFilter theLayersToProcess, + const OpenGl_LayerFilter theFilterMode, + const Graphic3d_ZLayerId theLayersToProcess, OpenGl_FrameBuffer* theReadDrawFbo, OpenGl_FrameBuffer* theOitAccumFbo) const; diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 7907795567..e1010f47df 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -520,12 +520,12 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3 const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft) { - return myWorkspace->BufferDump(myFBO, theImage, theBufferType); + return myWorkspace->BufferDump (myFBO, theImage, theBufferType); } if (!myRaytraceParameters.AdaptiveScreenSampling) { - return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType); + return myWorkspace->BufferDump (myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType); } if (aCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) @@ -572,6 +572,71 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3 return true; } +//======================================================================= +//function : ShadowMapDump +//purpose : +//======================================================================= +Standard_Boolean OpenGl_View::ShadowMapDump (Image_PixMap& theImage, const TCollection_AsciiString& theLightName) +{ + if (!myShadowMaps->IsValid()) + { + return Standard_False; + } + + const Handle(OpenGl_Context)& aGlCtx = myWorkspace->GetGlContext(); + for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter) + { + Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue(aShadowIter); + if (!aShadow.IsNull() && aShadow->LightSource()->Name() == theLightName) + { + const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer(); + if (aShadowFbo->GetVPSizeX() == myRenderParams.ShadowMapResolution) + { + if ((Standard_Integer)theImage.Width() != aShadowFbo->GetVPSizeX() || (Standard_Integer)theImage.Height() != aShadowFbo->GetVPSizeY()) + { + theImage.InitZero(Image_Format_GrayF, aShadowFbo->GetVPSizeX(), aShadowFbo->GetVPSizeY()); + } + GLint aReadBufferPrev = GL_BACK; + // Bind FBO if used. + if (!aShadowFbo.IsNull() && aShadowFbo->IsValid()) + { + aShadowFbo->BindBuffer (aGlCtx); + } + else if (aGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES) + { + aGlCtx->core11fwd->glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev); + GLint aDrawBufferPrev = GL_BACK; + aGlCtx->core11fwd->glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev); + aGlCtx->core11fwd->glReadBuffer (aDrawBufferPrev); + } + // Setup alignment. + const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL. + aGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment); + // Read data. + aGlCtx->core11fwd->glReadPixels (0, 0, GLsizei(theImage.SizeX()), GLsizei(theImage.SizeY()), GL_DEPTH_COMPONENT, GL_FLOAT, theImage.ChangeData()); + aGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1); + if (aGlCtx->hasPackRowLength) + { + aGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0); + } + // Unbind FBO. + if (!aShadowFbo.IsNull() && aShadowFbo->IsValid()) + { + aShadowFbo->UnbindBuffer (aGlCtx); + } + else if (aGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES) + { + aGlCtx->core11fwd->glReadBuffer (aReadBufferPrev); + } + // Check for errors. + const bool hasErrors = aGlCtx->ResetErrors (true); + return !hasErrors; + } + } + } + return Standard_False; +} + // ======================================================================= // function : GradientBackground // purpose : @@ -2583,7 +2648,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, if (aCtx->arbFBOBlit != NULL) { // Render bottom OSD layer - myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo); + myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, myZLayerTarget, theReadDrawFbo, theOitAccumFbo); const Standard_Integer aPrevFilter = myWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_NonRaytraceableOnly); myWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_NonRaytraceableOnly); @@ -2599,7 +2664,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, } // Render non-polygonal elements in default layer - myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_RayTracable, theReadDrawFbo, theOitAccumFbo); + myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_RayTracable, myZLayerTarget, theReadDrawFbo, theOitAccumFbo); } myWorkspace->SetRenderFilter (aPrevFilter); } @@ -2622,7 +2687,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, raytrace (aSizeXY.x(), aSizeXY.y(), theProjection, theReadDrawFbo, aCtx); // Render upper (top and topmost) OpenGL layers - myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, theReadDrawFbo, theOitAccumFbo); + myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, myZLayerTarget, theReadDrawFbo, theOitAccumFbo); } } @@ -2630,7 +2695,9 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, // mode or in case of ray-tracing failure if (toRenderGL) { - myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All, theReadDrawFbo, theOitAccumFbo); + // check if only a single layer is to be dumped + OpenGl_LayerFilter aFilter = myZLayerRedrawMode ? OpenGl_LF_Single : OpenGl_LF_All; + myZLayers.Render (myWorkspace, theToDrawImmediate, aFilter, myZLayerTarget, theReadDrawFbo, theOitAccumFbo); // Set flag that scene was redrawn by standard pipeline myWasRedrawnGL = Standard_True; diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 17768a06d1..5d4cca1029 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -111,6 +111,12 @@ public: Standard_EXPORT virtual Standard_Boolean BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) Standard_OVERRIDE; + //! Dumps the graphical contents of a shadowmap framebuffer into an image. + //! @param theImage the image to store the shadow map. + //! @param theLightName [in] name of the light used to generate the shadow map. + Standard_EXPORT virtual Standard_Boolean ShadowMapDump (Image_PixMap& theImage, + const TCollection_AsciiString& theLightName) Standard_OVERRIDE; + //! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated. Standard_EXPORT virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE; diff --git a/src/V3d/V3d_ImageDumpOptions.hxx b/src/V3d/V3d_ImageDumpOptions.hxx index 368f7c881d..a15f57b83a 100644 --- a/src/V3d/V3d_ImageDumpOptions.hxx +++ b/src/V3d/V3d_ImageDumpOptions.hxx @@ -16,29 +16,36 @@ #include #include +#include //! The structure defines options for image dump functionality. struct V3d_ImageDumpOptions { - Standard_Integer Width; //!< width of image dump to allocate an image, 0 by default (meaning that image should be already allocated) - Standard_Integer Height; //!< height of image dump to allocate an image, 0 by default (meaning that image should be already allocated) - Graphic3d_BufferType BufferType; //!< which buffer to dump (color / depth), Graphic3d_BT_RGB by default - V3d_StereoDumpOptions StereoOptions; //!< dumping stereoscopic camera, V3d_SDO_MONO by default (middle-point monographic projection) - Standard_Integer TileSize; //!< the view dimension limited for tiled dump, 0 by default (automatic tiling depending on hardware capabilities) - Standard_Boolean ToAdjustAspect; //!< flag to override active view aspect ratio by (Width / Height) defined for image dump (TRUE by default) + Standard_Integer Width; //!< Width of image dump to allocate an image, 0 by default (meaning that image should be already allocated). + Standard_Integer Height; //!< Height of image dump to allocate an image, 0 by default (meaning that image should be already allocated). + Graphic3d_BufferType BufferType; //!< Which buffer to dump (color / depth), Graphic3d_BT_RGB by default. + V3d_StereoDumpOptions StereoOptions; //!< Dumping stereoscopic camera, V3d_SDO_MONO by default (middle-point monographic projection). + Standard_Integer TileSize; //!< The view dimension limited for tiled dump, 0 by default (automatic tiling depending on hardware capabilities). + Standard_Boolean ToAdjustAspect; //!< Flag to override active view aspect ratio by (Width / Height) defined for image dump (TRUE by default). + Graphic3d_ZLayerId TargetZLayerId; //!< Target z layer id which defines the last layer to be drawn before image dump. + Standard_Boolean IsSingleLayer; //SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y())); } - + //apply zlayer rendering parameters to view + myView->SetZLayerTarget (theParams.TargetZLayerId); + myView->SetZLayerRedrawMode (theParams.IsSingleLayer); // render immediate structures into back buffer rather than front const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False); @@ -2952,7 +2955,19 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage, myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y()); } Redraw(); - isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType); + if (theParams.BufferType == Graphic3d_BT_ShadowMap) + { + // draw shadow maps + if (!myView->ShadowMapDump (theImage, theParams.LightName)) + { + Message::SendFail ("OpenGl_View::BufferDump() failed to dump shadowmap"); + isSuccess = Standard_False; + } + } + else + { + isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType); + } } else { @@ -3024,6 +3039,9 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage, myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y()); } myView->SetFBO (aPrevFBOPtr); + //apply default zlayer rendering parameters to view + myView->SetZLayerTarget (Graphic3d_ZLayerId_BotOSD); + myView->SetZLayerRedrawMode (Standard_False); return isSuccess; } diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index 22847902e9..93804995a4 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -851,19 +851,25 @@ public: //! @param theBufferType type of the view buffer to dump (color / depth) //! @param theToAdjustAspect when true, active view aspect ratio will be overridden by (theWidth / theHeight) //! @param theStereoOptions how to dump stereographic camera - Standard_Boolean ToPixMap (Image_PixMap& theImage, - const Standard_Integer theWidth, - const Standard_Integer theHeight, + Standard_Boolean ToPixMap (Image_PixMap& theImage, + const Standard_Integer theWidth, + const Standard_Integer theHeight, const Graphic3d_BufferType& theBufferType = Graphic3d_BT_RGB, const Standard_Boolean theToAdjustAspect = Standard_True, - const V3d_StereoDumpOptions theStereoOptions = V3d_SDO_MONO) + const Graphic3d_ZLayerId theTargetZLayerId = Graphic3d_ZLayerId_BotOSD, + const Standard_Integer theIsSingleLayer = Standard_False, + const V3d_StereoDumpOptions theStereoOptions = V3d_SDO_MONO, + const Standard_CString theLightName = "") { V3d_ImageDumpOptions aParams; - aParams.Width = theWidth; - aParams.Height = theHeight; - aParams.BufferType = theBufferType; + aParams.Width = theWidth; + aParams.Height = theHeight; + aParams.BufferType = theBufferType; aParams.StereoOptions = theStereoOptions; aParams.ToAdjustAspect = theToAdjustAspect; + aParams.TargetZLayerId = theTargetZLayerId; + aParams.IsSingleLayer = theIsSingleLayer; + aParams.LightName = theLightName; return ToPixMap (theImage, aParams); } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index dced0cf3f9..380f5ac67b 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -966,8 +966,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single; V3d_ImageDumpOptions aParams; Handle(Graphic3d_Camera) aCustomCam; - aParams.BufferType = Graphic3d_BT_RGB; - aParams.StereoOptions = V3d_SDO_MONO; + aParams.BufferType = Graphic3d_BT_RGB; + aParams.StereoOptions = V3d_SDO_MONO; + aParams.TargetZLayerId = Graphic3d_ZLayerId_BotOSD; + aParams.IsSingleLayer = Standard_False; + aParams.LightName = ""; for (; anArgIter < theArgNb; ++anArgIter) { TCollection_AsciiString anArg (theArgVec[anArgIter]); @@ -998,6 +1001,31 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, { aParams.BufferType = Graphic3d_BT_Depth; } + else if (aBufArg == "shadowmap") + { + if (++anArgIter >= theArgNb) + { + Message::SendFail() << "Error: missing light name for shadowmap dump"; + return 1; + } + aParams.BufferType = Graphic3d_BT_ShadowMap; + aParams.LightName = theArgVec[anArgIter]; + Standard_Boolean isLightFound = Standard_False; + for (V3d_ListOfLightIterator aLightIter(aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next()) + { + Handle(V3d_Light) aLight = aLightIter.Value(); + if (aLight->Name() == aParams.LightName) + { + isLightFound = Standard_True; + break; + } + } + if (!isLightFound) + { + Message::SendFail() << "Error: couldn't find light '" << aParams.LightName << "'"; + return 1; + } + } else { Message::SendFail() << "Error: unknown buffer '" << aBufArg << "'"; @@ -1105,6 +1133,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, { aParams.BufferType = Graphic3d_BT_Depth; } + else if (anArg == "-shadowmap" + || anArg == "shadowmap") + { + aParams.BufferType = Graphic3d_BT_ShadowMap; + } else if (anArg == "-width" || anArg == "width" || anArg == "sizex") @@ -1147,6 +1180,39 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, } aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]); } + else if (anArg == "-grouplayer") + { + if (++anArgIter >= theArgNb) + { + Message::SendFail() << "Error: integer value is expected right after 'grouplayer'"; + return 1; + } + Graphic3d_ZLayerId aZLayer = (Graphic3d_ZLayerId)Draw::Atoi (theArgVec[anArgIter]); + if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer) || + aZLayer == Graphic3d_ZLayerId_UNKNOWN) + { + Message::SendFail() << "Error: invalid layer " << aZLayer << "."; + return 1; + } + aParams.TargetZLayerId = aZLayer; + } + else if (anArg == "-singlelayer") + { + if (++anArgIter >= theArgNb) + { + Message::SendFail() << "Error: integer value is expected right after 'singlelayer'"; + return 1; + } + Graphic3d_ZLayerId aZLayer = (Graphic3d_ZLayerId)Draw::Atoi (theArgVec[anArgIter]); + if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer) || + aZLayer == Graphic3d_ZLayerId_UNKNOWN) + { + Message::SendFail() << "Error: invalid layer " << aZLayer << "."; + return 1; + } + aParams.TargetZLayerId = aZLayer; + aParams.IsSingleLayer = Standard_True; + } else { Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'"; @@ -1174,6 +1240,7 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break; case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break; case Graphic3d_BT_Red: aFormat = Image_Format_Gray; break; + case Graphic3d_BT_ShadowMap: aFormat = Image_Format_GrayF; break; } const bool wasImmUpdate = aView->SetImmediateUpdate (false); @@ -1194,8 +1261,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI, else if (aPixMap.SizeX() != Standard_Size(aParams.Width) || aPixMap.SizeY() != Standard_Size(aParams.Height)) { - theDI << "Fail: dumped dimensions " << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY() - << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n"; + if (aParams.BufferType != Graphic3d_BT_ShadowMap) + { + theDI << "Fail: dumped dimensions " << (Standard_Integer)aPixMap.SizeX() << "x" << (Standard_Integer)aPixMap.SizeY() + << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n"; + } } break; } @@ -6784,6 +6854,9 @@ vdump .png [-width Width -height Height] [-stereo mono|left|right|blend|sideBySide|overUnder=mono] [-xrPose base|head|handLeft|handRight=base] [-tileSize Size=0] + [-grouplayer zlayerId] + [-singlelayer zlayerId] + [-buffer shadowmap lightname] Dumps content of the active view into image file. )" /* [vdump] */); diff --git a/tests/v3d/bugs/bug32752 b/tests/v3d/bugs/bug32752 new file mode 100644 index 0000000000..90b630e7a3 --- /dev/null +++ b/tests/v3d/bugs/bug32752 @@ -0,0 +1,88 @@ +puts "========" +puts "0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer" +puts "========" +puts "" + +pload MODELING VISUALIZATION +vclear +vinit +box b1 20 0 0 10 10 10 +box b2 -20 0 0 10 10 10 +box b3 0 -10 0 5 5 5 +box b4 0 5 0 5 5 5 +box b5 0 0 5 3 3 3 +box b6 0 0 -5 7 7 7 +box b7 0 -5 -10 3 3 3 + +set aLayerId1 [vzlayer -add -enable depthTest -enable depthWrite -disable depthClear] +set aLayerId2 [vzlayer -add -enable depthTest -enable depthWrite -disable depthClear] + +vdisplay -dispmode 1 -layer ${aLayerId1} b1 +vdisplay -dispmode 1 -layer ${aLayerId2} b2 +vdisplay -dispmode 1 -layer 0 b3 +vdisplay -dispmode 1 -layer -2 b4 +vdisplay -dispmode 1 -layer -3 b5 +vdisplay -dispmode 1 -layer -4 b6 +vdisplay -dispmode 1 -layer -5 b7 +vfit +vviewparams -scale 15.0 -proj 0.57735 -0.57735 0.57735 -up -0.1 0.1 0.1 -at 0.0 0.0 0.0 + +vsetcolor b1 RED3 +vsetcolor b2 GREEN3 +vsetcolor b3 BLUE3 +vsetcolor b4 ORANGE3 +vsetcolor b5 YELLOW3 +vsetcolor b6 SALMON3 +vsetcolor b7 PURPLE3 + +#dump entire scene +#color +vdump $imagedir/${casename}_all.png +#depth +vdump $imagedir/${casename}_depth.png -buffer depth + +#dump single layer +vdump $imagedir/${casename}_only_b1.png -singlelayer ${aLayerId1} +vdump $imagedir/${casename}_only_b2.png -singlelayer ${aLayerId2} +vdump $imagedir/${casename}_only_b3.png -singlelayer 0 +vdump $imagedir/${casename}_only_b4.png -singlelayer -2 +vdump $imagedir/${casename}_only_b5.png -singlelayer -3 +vdump $imagedir/${casename}_only_b6.png -singlelayer -4 +vdump $imagedir/${casename}_only_b7.png -singlelayer -5 + +#dump a group of layers +vdump $imagedir/${casename}_upto_b1.png -grouplayer ${aLayerId1} +vdump $imagedir/${casename}_upto_b2.png -grouplayer ${aLayerId2} +vdump $imagedir/${casename}_upto_b3.png -grouplayer 0 +vdump $imagedir/${casename}_upto_b4.png -grouplayer -2 +vdump $imagedir/${casename}_upto_b5.png -grouplayer -3 +vdump $imagedir/${casename}_upto_b6.png -grouplayer -4 +vdump $imagedir/${casename}_upto_b7.png -grouplayer -5 + +#dump single layer depth values +vdump $imagedir/${casename}_only_b1_depth.png -buffer depth -singlelayer ${aLayerId1} +vdump $imagedir/${casename}_only_b2_depth.png -buffer depth -singlelayer ${aLayerId2} +vdump $imagedir/${casename}_only_b3_depth.png -buffer depth -singlelayer 0 +vdump $imagedir/${casename}_only_b4_depth.png -buffer depth -singlelayer -2 +vdump $imagedir/${casename}_only_b5_depth.png -buffer depth -singlelayer -3 +vdump $imagedir/${casename}_only_b6_depth.png -buffer depth -singlelayer -4 +vdump $imagedir/${casename}_only_b7_depth.png -buffer depth -singlelayer -5 + +#dump a group of layers depth values +vdump $imagedir/${casename}_upto_b1_depth.png -buffer depth -grouplayer ${aLayerId1} +vdump $imagedir/${casename}_upto_b2_depth.png -buffer depth -grouplayer ${aLayerId2} +vdump $imagedir/${casename}_upto_b3_depth.png -buffer depth -grouplayer 0 +vdump $imagedir/${casename}_upto_b4_depth.png -buffer depth -grouplayer -2 +vdump $imagedir/${casename}_upto_b5_depth.png -buffer depth -grouplayer -3 +vdump $imagedir/${casename}_upto_b6_depth.png -buffer depth -grouplayer -4 +vdump $imagedir/${casename}_upto_b7_depth.png -buffer depth -grouplayer -5 + +#dump shadow maps +vlight -clear +vlight v1 -type directional -intensity 1 -dir -1 0 -0.5 -castShadows 1 +vlight v2 -type directional -intensity 1 -dir -1 0.1 0 -castShadows 1 +#dump scene +vdump $imagedir/${casename}_newlights.png +#dump shadowmaps +vdump $imagedir/${casename}_shadowmap_v1.png -buffer shadowmap v1 +vdump $imagedir/${casename}_shadowmap_v2.png -buffer shadowmap v2