Graphic3d_Camera definition has been exended by optional Tile property (Graphic3d_CameraTile structure).
V3d_View::ToPixMap() now performs tiled dump when image size exceeds hardware limits.
OpenGl_View::Redraw() - fixed dump of immediate Z layers in no stereo and no MSAA case.
OpenGl_Context now tracks viewport values.
Draw Harness command vdump has been extended with new argument -tileSize.
Graphic3d_BufferType.hxx
Graphic3d_Camera.cxx
Graphic3d_Camera.hxx
+Graphic3d_CameraTile.hxx
Graphic3d_CappingFlags.hxx
Graphic3d_CLight.hxx
Graphic3d_ClipPlane.cxx
Graphic3d_TypeOfComposition.hxx
Graphic3d_TypeOfConnection.hxx
Graphic3d_TypeOfLightSource.hxx
+Graphic3d_TypeOfLimit.hxx
Graphic3d_TypeOfMaterial.hxx
Graphic3d_TypeOfPrimitiveArray.hxx
Graphic3d_TypeOfReflection.hxx
SetZFocus (theOtherCamera->ZFocusType(), theOtherCamera->ZFocus());
SetIOD (theOtherCamera->GetIODType(), theOtherCamera->IOD());
SetProjectionType (theOtherCamera->ProjectionType());
+ SetTile (theOtherCamera->myTile);
}
// =======================================================================
InvalidateProjection();
}
+// =======================================================================
+// function : SetTile
+// purpose :
+// =======================================================================
+void Graphic3d_Camera::SetTile (const Graphic3d_CameraTile& theTile)
+{
+ if (myTile == theTile)
+ {
+ return;
+ }
+
+ myTile = theTile;
+ InvalidateProjection();
+}
+
// =======================================================================
// function : OrthogonalizeUp
// purpose :
? static_cast<Elem_t> (myZFocus * Distance())
: static_cast<Elem_t> (myZFocus);
+ if (myTile.IsValid())
+ {
+ const Elem_t aDXFull = Elem_t(2) * aDXHalf;
+ const Elem_t aDYFull = Elem_t(2) * aDYHalf;
+ const Graphic3d_Vec2i anOffset = myTile.OffsetLowerLeft();
+ aLeft = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
+ aRight = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x() + myTile.TileSize.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
+ aBot = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
+ aTop = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y() + myTile.TileSize.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
+ }
+
switch (myProjType)
{
case Projection_Orthographic :
#ifndef _Graphic3d_Camera_HeaderFile
#define _Graphic3d_Camera_HeaderFile
+#include <Graphic3d_CameraTile.hxx>
#include <Graphic3d_Mat4d.hxx>
#include <Graphic3d_Mat4.hxx>
#include <Graphic3d_Vec3.hxx>
return myIODType;
}
+ //! Get current tile.
+ const Graphic3d_CameraTile& Tile() const { return myTile; }
+
+ //! Sets the Tile defining the drawing sub-area within View.
+ //! Note that tile defining a region outside the view boundaries is also valid - use method Graphic3d_CameraTile::Cropped() to assign a cropped copy.
+ //! @param theTile tile definition
+ Standard_EXPORT void SetTile (const Graphic3d_CameraTile& theTile);
+
//! @name Basic camera operations
public:
Standard_Real myIOD; //!< Intraocular distance value.
IODType myIODType; //!< Intraocular distance definition type.
+ Graphic3d_CameraTile myTile;//!< Tile defining sub-area for drawing
+
mutable TransformMatrices<Standard_Real> myMatricesD;
mutable TransformMatrices<Standard_ShortReal> myMatricesF;
--- /dev/null
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_CameraTile_HeaderFile
+#define _Graphic3d_CameraTile_HeaderFile
+
+#include <Graphic3d_Vec2.hxx>
+#include <Standard_Integer.hxx>
+#include <Standard_TypeDef.hxx>
+
+//! Class defines the area (Tile) inside a view.
+class Graphic3d_CameraTile
+{
+public:
+
+ Graphic3d_Vec2i TotalSize; //!< total size of the View area, in pixels
+ Graphic3d_Vec2i TileSize; //!< size of the Tile, in pixels
+ Graphic3d_Vec2i Offset; //!< the lower-left corner of the Tile relative to the View area (or upper-left if IsTopDown is true), in pixels
+ bool IsTopDown; //!< indicate the offset coordinate system - lower-left (default) or top-down
+
+public:
+
+ //! Default constructor.
+ //! Initializes the empty Tile of zero size and lower-left offset orientation.
+ //! Such Tile is considered uninitialized (invalid).
+ Graphic3d_CameraTile() : IsTopDown (false) {}
+
+ //! Return true if Tile has been defined.
+ bool IsValid() const
+ {
+ return TotalSize.x() > 0 && TotalSize.y() > 0
+ && TileSize.x() > 0 && TileSize.y() > 0;
+ }
+
+ //! Return offset position from lower-left corner.
+ Graphic3d_Vec2i OffsetLowerLeft() const
+ {
+ return Graphic3d_Vec2i (Offset.x(),
+ !IsTopDown
+ ? Offset.y()
+ : TotalSize.y() - Offset.y() - 1);
+ }
+
+ //! Return the copy cropped by total size
+ Graphic3d_CameraTile Cropped() const
+ {
+ Graphic3d_CameraTile aTile = *this;
+ if (!IsValid())
+ {
+ return aTile;
+ }
+
+ aTile.Offset.x() = Max (Offset.x(), 0);
+ aTile.Offset.y() = Max (Offset.y(), 0);
+
+ const Standard_Integer anX = Min (Offset.x() + TileSize.x(), TotalSize.x());
+ const Standard_Integer anY = Min (Offset.y() + TileSize.y(), TotalSize.y());
+ aTile.TileSize.x() = anX - Offset.x();
+ aTile.TileSize.y() = anY - Offset.y();
+ return aTile;
+ }
+
+ //! Equality check.
+ bool operator== (const Graphic3d_CameraTile& theOther) const
+ {
+ const Graphic3d_Vec2i anOffset1 = OffsetLowerLeft();
+ const Graphic3d_Vec2i anOffset2 = theOther.OffsetLowerLeft();
+ return TotalSize.x() == theOther.TotalSize.x()
+ && TotalSize.y() == theOther.TotalSize.y()
+ && TileSize.x() == theOther.TileSize.x()
+ && TileSize.y() == theOther.TileSize.y()
+ && anOffset1.x() == anOffset2.x()
+ && anOffset1.y() == anOffset2.y();
+ }
+
+};
+
+#endif // _Graphic3d_CameraTile_HeaderFile
#include <Graphic3d_ZLayerId.hxx>
#include <Graphic3d_ZLayerSettings.hxx>
#include <Graphic3d_CLight.hxx>
+#include <Graphic3d_TypeOfLimit.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColStd_SequenceOfInteger.hxx>
public:
-
- //! call_togl_inquirelight
- virtual Standard_Integer InquireLightLimit() = 0;
-
- //! call_togl_inquireplane
- virtual Standard_Integer InquirePlaneLimit() = 0;
-
- //! call_togl_inquireview
- virtual Standard_Integer InquireViewLimit() = 0;
-
+ //! Request limit of graphic resource of specific type.
+ virtual Standard_Integer InquireLimit (const Graphic3d_TypeOfLimit theType) const = 0;
+
+ //! Request maximum number of active light sources supported by driver and hardware.
+ Standard_Integer InquireLightLimit() const { return InquireLimit (Graphic3d_TypeOfLimit_MaxNbLights); }
+
+ //! Request maximum number of active clipping planes supported by driver and hardware.
+ Standard_Integer InquirePlaneLimit() const { return InquireLimit (Graphic3d_TypeOfLimit_MaxNbClipPlanes); }
+
+ //! Request maximum number of views supported by driver.
+ Standard_Integer InquireViewLimit() const { return InquireLimit (Graphic3d_TypeOfLimit_MaxNbViews); }
+
+public:
+
//! Creates new empty graphic structure
virtual Handle(Graphic3d_CStructure) CreateStructure (const Handle(Graphic3d_StructureManager)& theManager) = 0;
return;
}
+ const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
if (Flags == Graphic3d_TMF_TriedronPers)
{
// reset Z focus for trihedron persistence
// scale factor to pixels
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
- const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(theViewportHeight);
+ const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
// offset from the corner
const Standard_Real anOffset = Point.z() * aScale;
// scale factor to pixels
const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
- const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(theViewportHeight);
+ const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
gp_XYZ aCenter (0.0, 0.0, -aFocus);
if (Point.x() != 0.0)
{
#ifndef _Graphic3d_TransformUtils_HeaderFile
#define _Graphic3d_TransformUtils_HeaderFile
+#include <gp_Trsf.hxx>
#include <Graphic3d_Vec.hxx>
#include <Standard_math.hxx> // M_PI
--- /dev/null
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_TypeOfLimit_HeaderFile
+#define _Graphic3d_TypeOfLimit_HeaderFile
+
+//! Type of graphic resource limit.
+enum Graphic3d_TypeOfLimit
+{
+ Graphic3d_TypeOfLimit_MaxNbLights, //!< maximum number of active light sources
+ Graphic3d_TypeOfLimit_MaxNbClipPlanes, //!< maximum number of active clipping planes
+ Graphic3d_TypeOfLimit_MaxNbViews, //!< maximum number of views
+ Graphic3d_TypeOfLimit_MaxTextureSize, //!< maximum size of texture
+ Graphic3d_TypeOfLimit_MaxMsaa, //!< maximum number of MSAA samples
+ Graphic3d_TypeOfLimit_NB //!< number of elements in this enumeration
+};
+
+#endif // _Graphic3d_TypeOfLimit_HeaderFile
#include <Aspect_FillMethod.hxx>
#include <NCollection_AlignedAllocator.hxx>
#include <OpenGl_Texture.hxx>
+#include <OpenGl_View.hxx>
#include <Graphic3d_TextureParams.hxx>
// =======================================================================
// =======================================================================
OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
: OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
- myToUpdate (Standard_False),
myType (theType),
+ myFillMethod (Aspect_FM_NONE),
myViewWidth (0),
myViewHeight (0),
- myFillMethod (Aspect_FM_NONE)
+ myToUpdate (Standard_False)
{
Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
myAttribs = new Graphic3d_Buffer (anAlloc);
myGradientParams.color1 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
myGradientParams.color2 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
myGradientParams.type = Aspect_GFM_NONE;
+
+ myTrsfPers.Flags = Graphic3d_TMF_2d;
+ if (myType == Graphic3d_TOB_TEXTURE)
+ {
+ myTrsfPers.Point.x() = 0.0;
+ myTrsfPers.Point.y() = 0.0;
+ }
+ else
+ {
+ myTrsfPers.Point.x() = -1.0;
+ myTrsfPers.Point.y() = -1.0;
+ }
}
// =======================================================================
}
// =======================================================================
-// method : Init
+// method : init
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& theWorkspace)
+Standard_Boolean OpenGl_BackgroundArray::init (const Handle(OpenGl_Workspace)& theWorkspace) const
{
switch (myType)
{
}
case Graphic3d_TOB_TEXTURE:
{
- myViewWidth = theWorkspace->Width();
- myViewHeight = theWorkspace->Height();
if (!createTextureArray (theWorkspace))
{
return Standard_False;
// method : createGradientArray
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
+Standard_Boolean OpenGl_BackgroundArray::createGradientArray() const
{
// Initialize data for primitive array
Graphic3d_Attribute aGragientAttribInfo[] =
OpenGl_Vec2 aVertices[4] =
{
- OpenGl_Vec2( 1.0f, -1.0f),
- OpenGl_Vec2( 1.0f, 1.0f),
- OpenGl_Vec2(-1.0f, -1.0f),
- OpenGl_Vec2(-1.0f, 1.0f)
+ OpenGl_Vec2(float(myViewWidth), 0.0f),
+ OpenGl_Vec2(float(myViewWidth), float(myViewHeight)),
+ OpenGl_Vec2(0.0f, 0.0f),
+ OpenGl_Vec2(0.0f, float(myViewHeight))
};
float* aCorners[4] = {};
}
case Aspect_GFM_CORNER1:
{
- aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
- aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
- aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
- aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
+ aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
+ aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight));
+ aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
+ aVertices[3] = OpenGl_Vec2(0.0f, 0.0f);
aCorners[0] = myGradientParams.color2.xyz().ChangeData();
aCorners[1] = myGradientParams.color1.xyz().ChangeData();
}
case Aspect_GFM_CORNER3:
{
- aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
- aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
- aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
- aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
+ aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
+ aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight));
+ aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
+ aVertices[3] = OpenGl_Vec2(0.0f, 0.0f);
aCorners[0] = myGradientParams.color2.xyz().ChangeData();
aCorners[1] = myGradientParams.color2.xyz().ChangeData();
// method : createTextureArray
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace)
+Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const
{
Graphic3d_Attribute aTextureAttribInfo[] =
{
GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
// Set up for stretching or tiling
- GLfloat anOffsetX = 1.0f;
- GLfloat anOffsetY = 1.0f;
+ GLfloat anOffsetX = 0.5f * (float )myViewWidth;
+ GLfloat anOffsetY = 0.5f * (float )myViewHeight;
// Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
// (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
if (myFillMethod == Aspect_FM_CENTERED)
{
- anOffsetX = aTextureWidth / (GLfloat )myViewWidth;
- anOffsetY = aTextureHeight / (GLfloat )myViewHeight;
+ anOffsetX = 0.5f * aTextureWidth;
+ anOffsetY = 0.5f * aTextureHeight;
}
else if (myFillMethod == Aspect_FM_TILED)
{
return Standard_True;
}
+
+// =======================================================================
+// method : createTextureArray
+// purpose :
+// =======================================================================
+void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ Standard_Integer aViewSizeX = aCtx->Viewport()[2];
+ Standard_Integer aViewSizeY = aCtx->Viewport()[3];
+ if (theWorkspace->View()->Camera()->Tile().IsValid())
+ {
+ aViewSizeX = theWorkspace->View()->Camera()->Tile().TotalSize.x();
+ aViewSizeY = theWorkspace->View()->Camera()->Tile().TotalSize.y();
+ }
+ if (myToUpdate
+ || myViewWidth != aViewSizeX
+ || myViewHeight != aViewSizeY)
+ {
+ myViewWidth = aViewSizeX;
+ myViewHeight = aViewSizeY;
+ init (theWorkspace);
+ }
+
+ OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
+ OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
+ myTrsfPers.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
+ aCtx->Viewport()[2], aCtx->Viewport()[3]);
+
+ aCtx->ProjectionState.Push();
+ aCtx->WorldViewState.Push();
+ aCtx->ProjectionState.SetCurrent (aProjection);
+ aCtx->WorldViewState.SetCurrent (aWorldView);
+ aCtx->ApplyProjectionMatrix();
+ aCtx->ApplyModelViewMatrix();
+
+ OpenGl_PrimitiveArray::Render (theWorkspace);
+
+ aCtx->ProjectionState.Pop();
+ aCtx->WorldViewState.Pop();
+ aCtx->ApplyProjectionMatrix();
+}
//! Main constructor.
Standard_EXPORT OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType);
+ //! Render primitives to the window
+ Standard_EXPORT virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const Standard_OVERRIDE;
+
//! Check if background parameters are set properly
Standard_EXPORT bool IsDefined() const;
- //! Fill attributes arrays for background array according to its type:
- //! - for gradient background its attributes consist of colors and gradient coordinates
- //! - for texture one its attributes consist of position and texure coordinates.
- Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Workspace)& theWorkspace);
-
//! Sets background texture parameters
Standard_EXPORT void SetTextureParameters (const Aspect_FillMethod theFillMethod);
const Quantity_Color& theColor2,
const Aspect_GradientFillMethod theType);
- //! Shows if array parameters were changed
- Standard_Boolean IsDataChanged() const { return myToUpdate; }
-
- //! Shows if view sizes were changed
- //! (texture coordinates is no be changed)
- Standard_Boolean IsViewSizeChanged (const Handle(OpenGl_Workspace)& theWorkspace) const
- {
- return myType == Graphic3d_TOB_TEXTURE
- && (myViewWidth != theWorkspace->Width()
- || myViewHeight != theWorkspace->Height());
- }
-
protected: //! @name Internal structure for storing gradient parameters
struct OpenGl_GradientParameters
protected:
+ //! Fill attributes arrays for background array according to its type:
+ //! - for gradient background its attributes consist of colors and gradient coordinates
+ //! - for texture one its attributes consist of position and texture coordinates.
+ Standard_EXPORT Standard_Boolean init (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
//! Initializes gradient arrays.
- Standard_EXPORT Standard_Boolean createGradientArray();
+ Standard_EXPORT Standard_Boolean createGradientArray() const;
//! Initializes texture arrays.
//! @param theWorkspace OpenGl workspace that stores texture in the current enabled face aspect.
- Standard_EXPORT Standard_Boolean createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace);
+ Standard_EXPORT Standard_Boolean createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const;
//! Marks array parameters as changed,
//! on next rendering stage array data is to be updated.
protected:
- Standard_Boolean myToUpdate; //!< Shows if array parameters were changed and data (myAttribs storage) is to be updated
- Graphic3d_TypeOfBackground myType; //!< Type of background: texture or gradient.
- Standard_Integer myViewWidth; //!< view width used for array initialization
- Standard_Integer myViewHeight; //!< view height used for array initialization
- Aspect_FillMethod myFillMethod; //!< Texture parameters
- OpenGl_GradientParameters myGradientParams; //!< Gradient parameters
+ Graphic3d_TransformPers myTrsfPers; //!< transformation persistence
+ Graphic3d_TypeOfBackground myType; //!< Type of background: texture or gradient.
+ Aspect_FillMethod myFillMethod; //!< Texture parameters
+ mutable OpenGl_GradientParameters myGradientParams; //!< Gradient parameters
+ mutable Standard_Integer myViewWidth; //!< view width used for array initialization
+ mutable Standard_Integer myViewHeight; //!< view height used for array initialization
+ mutable Standard_Boolean myToUpdate; //!< Shows if array parameters were changed and data (myAttribs storage) is to be updated
};
myIsGlDebugCtx (Standard_False),
myResolutionRatio (1.0f)
{
+ myViewport[0] = 0;
+ myViewport[1] = 0;
+ myViewport[2] = 0;
+ myViewport[3] = 0;
+
// system-dependent fields
#if defined(HAVE_EGL)
myDisplay = (Aspect_Display )EGL_NO_DISPLAY;
}
}
+// =======================================================================
+// function : ResizeViewport
+// purpose :
+// =======================================================================
+void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
+{
+ core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
+ myViewport[0] = theRect[0];
+ myViewport[1] = theRect[1];
+ myViewport[2] = theRect[2];
+ myViewport[3] = theRect[3];
+}
+
#if !defined(GL_ES_VERSION_2_0)
inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
{
public: //! @name methods to alter or retrieve current state
+ //! Return cached viewport definition (x, y, width, height).
+ const Standard_Integer* Viewport() const { return myViewport; }
+
+ //! Resize the viewport (alias for glViewport).
+ //! @param theRect viewport definition (x, y, width, height)
+ Standard_EXPORT void ResizeViewport (const Standard_Integer theRect[4]);
+
//! Return active read buffer.
Standard_Integer ReadBuffer() { return myReadBuffer; }
Handle(OpenGl_Sampler) myTexSampler; //!< currently active sampler object
Handle(OpenGl_FrameBuffer) myDefaultFbo; //!< default Frame Buffer Object
Handle(OpenGl_LineAttributes) myHatchStyles; //!< resource holding predefined hatch styles patterns
+ Standard_Integer myViewport[4]; //!< current viewport
Standard_Integer myPointSpriteOrig; //!< GL_POINT_SPRITE_COORD_ORIGIN state (GL_UPPER_LEFT by default)
Standard_Integer myRenderMode; //!< value for active rendering mode
Standard_Integer myPolygonMode; //!< currently used polygon rasterization mode (glPolygonMode)
// function : SetupViewport
// purpose :
// =======================================================================
-void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& /*theGlCtx*/)
+void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& theGlCtx)
{
- glViewport (0, 0, myVPSizeX, myVPSizeY);
+ const Standard_Integer aViewport[4] = { 0, 0, myVPSizeX, myVPSizeY };
+ theGlCtx->ResizeViewport (aViewport);
}
// =======================================================================
Standard_ShortReal OpenGl_GraduatedTrihedron::getNormal (const Handle(OpenGl_Context)& theContext,
OpenGl_Vec3& theNormal) const
{
- GLint aViewport[4] = {};
- glGetIntegerv(GL_VIEWPORT, aViewport);
+ const Standard_Integer* aViewport = theContext->Viewport();
OpenGl_Mat4 aModelMatrix;
OpenGl_Mat4 aProjMatrix;
// Get current Model-View and Projection states
OpenGl_Mat4 aModelMat;
OpenGl_Mat4 aProjMat;
- GLint aViewport[4];
- aContext->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
aModelMat.Convert (aContext->WorldViewState.Current() * aContext->ModelWorldState.Current());
aProjMat .Convert (aContext->ProjectionState.Current());
OpenGl_Vec3 aEndPoint = -anAxis.Direction * myData.ArrowsLength();
OpenGl_Vec3 aWinPoint;
Graphic3d_TransformUtils::Project<Standard_ShortReal> (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(),
- aModelMat, aProjMat, aViewport,
+ aModelMat, aProjMat, aContext->Viewport(),
aWinPoint.x(), aWinPoint.y(), aWinPoint.z());
aContext->ModelWorldState.SetIdentity();
// Get start point of zoom persistent arrow
OpenGl_Vec3 anArrowStart;
Graphic3d_TransformUtils::UnProject<Standard_ShortReal> (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(),
- aModelMat, aProjMat, aViewport,
+ aModelMat, aProjMat, aContext->Viewport(),
anArrowStart.x(), anArrowStart.y(), anArrowStart.z());
// Render axis line
aModelMat = theMat;
#endif
// =======================================================================
-// function : InquireLightLimit
+// function : InquireLimit
// purpose :
// =======================================================================
-Standard_Integer OpenGl_GraphicDriver::InquireLightLimit()
-{
- return OpenGLMaxLights;
-}
-
-// =======================================================================
-// function : InquireViewLimit
-// purpose :
-// =======================================================================
-Standard_Integer OpenGl_GraphicDriver::InquireViewLimit()
-{
- return 10000;
-}
-
-// =======================================================================
-// function : InquirePlaneLimit
-// purpose :
-// =======================================================================
-Standard_Integer OpenGl_GraphicDriver::InquirePlaneLimit()
+Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit theType) const
{
const Handle(OpenGl_Context)& aCtx = GetSharedContext();
- return aCtx.IsNull() ? aCtx->MaxClipPlanes() : 0;
+ switch (theType)
+ {
+ case Graphic3d_TypeOfLimit_MaxNbLights:
+ return OpenGLMaxLights;
+ case Graphic3d_TypeOfLimit_MaxNbClipPlanes:
+ return !aCtx.IsNull() ? aCtx->MaxClipPlanes() : 0;
+ case Graphic3d_TypeOfLimit_MaxNbViews:
+ return 10000;
+ case Graphic3d_TypeOfLimit_MaxTextureSize:
+ return !aCtx.IsNull() ? aCtx->MaxTextureSize() : 1024;
+ case Graphic3d_TypeOfLimit_MaxMsaa:
+ return !aCtx.IsNull() ? aCtx->MaxMsaaSamples() : 0;
+ case Graphic3d_TypeOfLimit_NB:
+ return 0;
+ }
+ return 0;
}
// =======================================================================
void* theEglConfig);
#endif
- Standard_EXPORT Standard_Integer InquireLightLimit () Standard_OVERRIDE;
- Standard_EXPORT Standard_Integer InquireViewLimit () Standard_OVERRIDE;
+ //! Request limit of graphic resource of specific type.
+ Standard_EXPORT virtual Standard_Integer InquireLimit (const Graphic3d_TypeOfLimit theType) const Standard_OVERRIDE;
public:
Standard_ShortReal& theAscent,
Standard_ShortReal& theDescent) const Standard_OVERRIDE;
- Standard_EXPORT Standard_Integer InquirePlaneLimit() Standard_OVERRIDE;
-
Standard_EXPORT Standard_ShortReal DefaultTextHeight() const Standard_OVERRIDE;
Standard_EXPORT Standard_Boolean ViewExists (const Handle(Aspect_Window)& theWindow, Handle(Graphic3d_CView)& theView) Standard_OVERRIDE;
{
OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
- TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
+ TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
+ aCtx->Viewport()[2], aCtx->Viewport()[3]);
aCtx->ProjectionState.Push();
aCtx->WorldViewState.Push();
myWinZ + theDVec.z(),
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
OpenGl_Mat4d::Map (aProjectMat),
- myViewport,
+ theCtx->Viewport(),
anObjX,
anObjY,
anObjZ);
if (!myIs2d)
{
- glGetIntegerv (GL_VIEWPORT, myViewport);
-
Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(),
myPoint.y(),
myPoint.z(),
myModelMatrix,
myProjMatrix,
- myViewport,
+ theCtx->Viewport(),
myWinX,
myWinY,
myWinZ);
myWinZ,
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
myProjMatrix,
- myViewport,
+ theCtx->Viewport(),
x1,
y1,
z1);
myWinZ,
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
myProjMatrix,
- myViewport,
+ theCtx->Viewport(),
x2,
y2,
z2);
mutable OpenGl_Mat4d myProjMatrix;
mutable OpenGl_Mat4d myModelMatrix;
mutable OpenGl_Mat4d myOrientationMatrix;
- mutable GLint myViewport[4];
mutable GLdouble myWinX;
mutable GLdouble myWinY;
mutable GLdouble myWinZ;
aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
}
- aCtx->ProjectionState.Push();
- aCtx->WorldViewState.Push();
- aCtx->ModelWorldState.Push();
- aCtx->ProjectionState.SetIdentity();
- aCtx->WorldViewState.SetIdentity();
- aCtx->ModelWorldState.SetIdentity();
- aCtx->ApplyProjectionMatrix();
- aCtx->ApplyModelViewMatrix();
-
// Drawing background gradient if:
// - gradient fill type is not Aspect_GFM_NONE and
// - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
}
#endif
- if (myBgGradientArray->IsDataChanged())
- {
- myBgGradientArray->Init (theWorkspace);
- }
-
myBgGradientArray->Render (theWorkspace);
#if !defined(GL_ES_VERSION_2_0)
aCtx->core11fwd->glDisable (GL_BLEND);
const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
-
- if (myBgTextureArray->IsDataChanged()
- || myBgTextureArray->IsViewSizeChanged (theWorkspace))
- {
- myBgTextureArray->Init (theWorkspace);
- }
-
myBgTextureArray->Render (theWorkspace);
-
- // restore aspects
theWorkspace->SetAspectFace (anOldAspectFace);
}
- aCtx->ModelWorldState.Pop();
- aCtx->WorldViewState.Pop();
- aCtx->ProjectionState.Pop();
- aCtx->ApplyProjectionMatrix();
- aCtx->ApplyModelViewMatrix();
-
if (wasUsedZBuffer)
{
theWorkspace->SetUseZBuffer (Standard_True);
}
else
{
- OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
+ OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : aFrameBuffer;
OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
if (!aCtx->caps->useSystemBuffer && myImmediateSceneFbos[0]->IsValid())
{
}
#if !defined(GL_ES_VERSION_2_0)
- if (aMainFbo == NULL
- && aFrameBuffer == NULL)
+ if (aMainFbo == NULL)
{
aCtx->SetReadDrawBuffer (GL_BACK);
}
#endif
- redraw (aProjectType, aMainFbo != NULL ? aMainFbo : aFrameBuffer);
+ redraw (aProjectType, aMainFbo);
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
if (!redrawImmediate (aProjectType, aMainFbo, anImmFbo))
}
else
{
- aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
+ const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() };
+ aCtx->ResizeViewport (aViewport);
}
// request reset of material
aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
}
#endif
- aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
+ const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() };
+ aCtx->ResizeViewport (aViewport);
}
}
glDisable (GL_DITHER);
glDisable (GL_SCISSOR_TEST);
- glViewport (0, 0, myWidth, myHeight);
+ const Standard_Integer aViewport[4] = { 0, 0, myWidth, myHeight };
+ myGlContext->ResizeViewport (aViewport);
#if !defined(GL_ES_VERSION_2_0)
- glDrawBuffer (GL_BACK);
+ myGlContext->SetDrawBuffer (GL_BACK);
if (myGlContext->core11 != NULL)
{
glMatrixMode (GL_MODELVIEW);
V3d_Coordinate.hxx
V3d_DirectionalLight.cxx
V3d_DirectionalLight.hxx
+V3d_ImageDumpOptions.hxx
V3d_Light.cxx
V3d_Light.hxx
V3d_ListOfTransient.hxx
--- /dev/null
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _V3d_ImageDumpOptions_HeaderFile
+#define _V3d_ImageDumpOptions_HeaderFile
+
+#include <Graphic3d_BufferType.hxx>
+#include <V3d_StereoDumpOptions.hxx>
+
+//! 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)
+
+public:
+
+ //! Default constructor.
+ V3d_ImageDumpOptions()
+ : Width (0),
+ Height (0),
+ BufferType (Graphic3d_BT_RGB),
+ StereoOptions (V3d_SDO_MONO),
+ TileSize (0),
+ ToAdjustAspect(Standard_True) {}
+
+};
+
+#endif // _V3d_ImageDumpOptions_HeaderFile
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-/***********************************************************************
-FONCTION :
-----------
-Classe V3d_View :
-HISTORIQUE DES MODIFICATIONS :
---------------------------------
-00-09-92 : GG ; Creation.
-02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
-05-06-97 : FMN ; Correction FitAll()
-30-06-97 : GG ; Correction + Optimisation de Panning(...)
-On fait la translation + le zoom en une seule
-operation au lieu de 2 precedemment qui etait buggee.
-09-07-97 : FMN ; Correction FitAll() sur le Ratio
-16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
-22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
-15-12-97 : FMN ; Ajout texture mapping
-17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
-18-12-97 : FMN ; Ajout mode Ajout
-24-12-97 : FMN ; Remplacement de math par MathGra
-24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
-31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
-07-01-98 : CAL ; Ajout de la methode DoMapping.
-07-01-98 : CAL ; Retrait de tous les "this->" inutiles
-21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
-27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
-12-02-98 : GG ; Reactivation du Redraw dans MustBeResized()
-23-02-98 : FMN ; Remplacement PI par Standard_PI
-25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
-11-03-98 : STT ; S3558
-19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
-ne marche pas.
-08-04-98 : STT ; suppr. S3558
-10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
-13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
-ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
-16-08-98 : CAL ; S3892. Ajout grilles 3d.
-09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
-06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
-16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
-06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
-29-OCT-98 : DCB : Adding ScreenCopy () method.
-REMARQUES :
------------
-About FitAll() multiple. This probleme is caused by missing
-precision of transformation matrices. If it is supposed that
-projection is made in the plane (U,V), there is a difference
-after several Zoom - compared to the exact value (cf ZoomX).
-Don't forget that the matrices work in float and not in double.
-To solve the problem (for lack of a better solution) I make 2 passes.
-************************************************************************/
-/*----------------------------------------------------------------------*/
-/*
-* Includes
-*/
+#include <V3d_View.hxx>
#include <Aspect_GradientBackground.hxx>
#include <Aspect_Grid.hxx>
#include <Graphic3d_TextureEnv.hxx>
#include <Graphic3d_Vector.hxx>
#include <Image_AlienPixMap.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
#include <NCollection_Array1.hxx>
#include <Precision.hxx>
#include <Quantity_Color.hxx>
#include <V3d_Light.hxx>
#include <V3d_StereoDumpOptions.hxx>
#include <V3d_UnMapped.hxx>
-#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
IMPLEMENT_STANDARD_RTTIEXT(V3d_View,MMgt_TShared)
-#define V3d_FLAG_COMPUTATION 0x00000004
-
-// Perspective
-#include <OSD_Environment.hxx>
-
-/*----------------------------------------------------------------------*/
-/*
-* Constant
-*/
-
#define DEUXPI (2. * M_PI)
namespace
//purpose :
//=============================================================================
Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
- const Standard_Integer theWidth,
- const Standard_Integer theHeight,
- const Graphic3d_BufferType& theBufferType,
- const Standard_Boolean theToKeepAspect,
- const V3d_StereoDumpOptions theStereoOptions)
+ const V3d_ImageDumpOptions& theParams)
{
- // always prefer hardware accelerated offscreen buffer
+ Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
+ if (aTargetSize.x() != 0
+ && aTargetSize.y() != 0)
+ {
+ // allocate image buffer for dumping
+ if (theImage.IsEmpty()
+ || theImage.SizeX() != Standard_Size(aTargetSize.x())
+ || theImage.SizeY() != Standard_Size(aTargetSize.y()))
+ {
+ const bool isBigEndian = Image_PixMap::IsBigEndianHost();
+ Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
+ switch (theParams.BufferType)
+ {
+ case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
+ case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
+ case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
+ }
+
+ if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
+ {
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
+ + " for view dump", Message_Fail);
+ return Standard_False;
+ }
+ }
+ }
+ if (theImage.IsEmpty())
+ {
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
+ return Standard_False;
+ }
+ aTargetSize.x() = (Standard_Integer )theImage.SizeX();
+ aTargetSize.y() = (Standard_Integer )theImage.SizeY();
+
Handle(Standard_Transient) aFBOPtr;
Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
- Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
- Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
+ Graphic3d_Vec2i aFBOVPSize = aTargetSize;
+
+ bool isTiling = false;
+ if (theParams.TileSize > 0)
+ {
+ if (aFBOVPSize.x() > theParams.TileSize
+ || aFBOVPSize.y() > theParams.TileSize)
+ {
+ aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
+ aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
+ isTiling = true;
+ }
+ }
+
+ Graphic3d_Vec2i aPrevFBOVPSize;
if (!aPrevFBOPtr.IsNull())
{
+ Graphic3d_Vec2i aPrevFBOSizeMax;
myView->FBOGetDimensions (aPrevFBOPtr,
- aPrevFBOVPSizeX, aPrevFBOVPSizeY,
- aPrevFBOSizeXMax, aPrevFBOSizeYMax);
- if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
+ aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
+ aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
+ if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
+ && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
{
- myView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
aFBOPtr = aPrevFBOPtr;
}
}
if (aFBOPtr.IsNull())
{
- // Try to create hardware accelerated buffer
- aFBOPtr = myView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
- if (!aFBOPtr.IsNull())
+ Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize);
+ if (theParams.TileSize > aMaxTexSize)
{
- myView->FBOGetDimensions (aFBOPtr,
- aFBOVPSizeX, aFBOVPSizeY,
- aFBOSizeXMax, aFBOSizeYMax);
- // reduce viewport in case of hardware limits
- if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
- if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
- myView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
+ + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail);
+ return Standard_False;
}
+
+ if (aFBOVPSize.x() > aMaxTexSize
+ || aFBOVPSize.y() > aMaxTexSize)
+ {
+ aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize);
+ aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize);
+ isTiling = true;
+ }
+
+ // Try to create hardware accelerated buffer
+ aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
}
myView->SetFBO (aFBOPtr);
- // If hardware accelerated buffer - try to use onscreen buffer
- // Results may be bad!
if (aFBOPtr.IsNull())
{
- // retrieve window sizes
- Standard_Integer aWinWidth, aWinHeight;
- MyWindow->Size (aWinWidth, aWinHeight);
-
- // technically we can reduce existing viewport...
- // but currently allow only dumping the window itself
- if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
+ // try to use on-screen buffer
+ Graphic3d_Vec2i aWinSize;
+ MyWindow->Size (aWinSize.x(), aWinSize.y());
+ if (aFBOVPSize.x() != aWinSize.x()
+ || aFBOVPSize.y() != aWinSize.y())
{
- return Standard_False;
+ isTiling = true;
}
+ aFBOVPSize = aWinSize;
+
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
}
+ // backup camera parameters
Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
-
Handle(Graphic3d_Camera) aCamera = Camera();
-
aStoreMapping->Copy (aCamera);
-
if (aCamera->IsStereo())
{
- switch (theStereoOptions)
+ switch (theParams.StereoOptions)
{
case V3d_SDO_MONO:
{
}
}
}
-
- // render immediate structures into back buffer rather than front
- const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
-
- const Standard_Boolean toAutoUpdate = myImmediateUpdate;
- myImmediateUpdate = Standard_False;
- AutoZFit();
- myImmediateUpdate = toAutoUpdate;
-
- if (theToKeepAspect)
+ if (theParams.ToAdjustAspect)
{
- aCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
+ aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
}
+ AutoZFit();
- Redraw();
-
- myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
-
- aCamera->Copy (aStoreMapping);
+ // render immediate structures into back buffer rather than front
+ const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
Standard_Boolean isSuccess = Standard_True;
-
- // allocate image buffer for dumping
- if (theImage.IsEmpty()
- || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
- || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
+ if (!isTiling)
{
- bool isBigEndian = Image_PixMap::IsBigEndianHost();
- Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
- switch (theBufferType)
+ if (!aFBOPtr.IsNull())
{
- case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
- case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
- case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
+ myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
}
+ Redraw();
+ isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
+ }
+ else
+ {
+ Image_PixMap aTilePixMap;
+ aTilePixMap.SetTopDown (theImage.IsTopDown());
- isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
+ Graphic3d_Vec2i anOffset (0, 0);
+ for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
+ {
+ anOffset.x() = 0;
+ for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
+ {
+ Graphic3d_CameraTile aTile;
+ aTile.Offset = anOffset;
+ aTile.TotalSize = aTargetSize;
+ aTile.TileSize = aFBOVPSize;
+ if (!aFBOPtr.IsNull())
+ {
+ // crop corners in case of FBO
+ // (no API to resize viewport of on-screen buffer - keep uncropped in this case)
+ aTile = aTile.Cropped();
+ }
+ if (aTile.TileSize.x() < 1
+ || aTile.TileSize.y() < 1)
+ {
+ continue;
+ }
+
+ const Standard_Integer aLeft = aTile.Offset.x();
+ Standard_Integer aBottom = aTile.Offset.y();
+ if (theImage.IsTopDown())
+ {
+ const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
+ aBottom = aTargetSize.y() - aTop;
+ }
+ aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
+ + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
+ aTile.TileSize.x(), aTile.TileSize.y(),
+ theImage.SizeRowBytes());
+
+ aCamera->SetTile (aTile);
+ if (!aFBOPtr.IsNull())
+ {
+ myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
+ }
+ Redraw();
+ isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
+ if (!isSuccess)
+ {
+ break;
+ }
+ }
+ if (!isSuccess)
+ {
+ break;
+ }
+ }
}
- isSuccess = isSuccess && myView->BufferDump (theImage, theBufferType);
- // FBO now useless, free resources
+ // restore state
+ myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
+ aCamera->Copy (aStoreMapping);
if (aFBOPtr != aPrevFBOPtr)
{
myView->FBORelease (aFBOPtr);
}
else if (!aPrevFBOPtr.IsNull())
{
- myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
+ myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
}
myView->SetFBO (aPrevFBOPtr);
-
return isSuccess;
}
#include <V3d_Coordinate.hxx>
#include <V3d_ListOfTransient.hxx>
-#include <V3d_StereoDumpOptions.hxx>
+#include <V3d_ImageDumpOptions.hxx>
#include <V3d_TypeOfAxe.hxx>
#include <V3d_TypeOfBackfacingModel.hxx>
const Graphic3d_ExportFormat theFormat,
const Graphic3d_SortType theSortType = Graphic3d_ST_BSP_Tree);
- //! Dumps the full contents of the view
- //! to a pixmap of pixel size <theWidth> * <theHeight> and
- //! buffer type <theBufferType>. If <theToKeepAspect> is true
- //! the aspect ratio of view will be kept if <theWidth> and <theHeight>
- //! define another ratio.
- //! Pixmap will be automatically (re)allocated when needed.
- //! When dumping stereographic camera - the corresponding
- //! middle-point monographic projection will be used for dumping by default.
- //! <theStereoOptions> flags are to be used for dumping then left or
- //! right eye projections.
- Standard_EXPORT Standard_Boolean ToPixMap (Image_PixMap& theImage, const Standard_Integer theWidth, const Standard_Integer theHeight, const Graphic3d_BufferType& theBufferType = Graphic3d_BT_RGB, const Standard_Boolean theToKeepAspect = Standard_True, const V3d_StereoDumpOptions theStereoOptions = V3d_SDO_MONO);
+ //! Dumps the full contents of the view to a pixmap with specified parameters.
+ Standard_EXPORT Standard_Boolean ToPixMap (Image_PixMap& theImage,
+ const V3d_ImageDumpOptions& theParams);
+
+ //! Dumps the full contents of the view to a pixmap.
+ //! @param theImage target image, will be re-allocated to match theWidth x theHeight
+ //! @param theWidth target image width
+ //! @param theHeight target image height
+ //! @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,
+ const Graphic3d_BufferType& theBufferType = Graphic3d_BT_RGB,
+ const Standard_Boolean theToAdjustAspect = Standard_True,
+ const V3d_StereoDumpOptions theStereoOptions = V3d_SDO_MONO)
+ {
+ V3d_ImageDumpOptions aParams;
+ aParams.Width = theWidth;
+ aParams.Height = theHeight;
+ aParams.BufferType = theBufferType;
+ aParams.StereoOptions = theStereoOptions;
+ aParams.ToAdjustAspect = theToAdjustAspect;
+ return ToPixMap (theImage, aParams);
+ }
//! Manages display of the back faces
//! When <aModel> is TOBM_AUTOMATIC the object backfaces
Standard_Integer anArgIter = 1;
Standard_CString aFilePath = theArgVec[anArgIter++];
- Graphic3d_BufferType aBufferType = Graphic3d_BT_RGB;
- V3d_StereoDumpOptions aStereoOpts = V3d_SDO_MONO;
ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
- Standard_Integer aWidth = 0;
- Standard_Integer aHeight = 0;
+ V3d_ImageDumpOptions aParams;
+ aParams.BufferType = Graphic3d_BT_RGB;
+ aParams.StereoOptions = V3d_SDO_MONO;
for (; anArgIter < theArgNb; ++anArgIter)
{
TCollection_AsciiString anArg (theArgVec[anArgIter]);
aBufArg.LowerCase();
if (aBufArg == "rgba")
{
- aBufferType = Graphic3d_BT_RGBA;
+ aParams.BufferType = Graphic3d_BT_RGBA;
}
else if (aBufArg == "rgb")
{
- aBufferType = Graphic3d_BT_RGB;
+ aParams.BufferType = Graphic3d_BT_RGB;
}
else if (aBufArg == "depth")
{
- aBufferType = Graphic3d_BT_Depth;
+ aParams.BufferType = Graphic3d_BT_Depth;
}
else
{
if (aStereoArg == "l"
|| aStereoArg == "left")
{
- aStereoOpts = V3d_SDO_LEFT_EYE;
+ aParams.StereoOptions = V3d_SDO_LEFT_EYE;
}
else if (aStereoArg == "r"
|| aStereoArg == "right")
{
- aStereoOpts = V3d_SDO_RIGHT_EYE;
+ aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
}
else if (aStereoArg == "mono")
{
- aStereoOpts = V3d_SDO_MONO;
+ aParams.StereoOptions = V3d_SDO_MONO;
}
else if (aStereoArg == "blended"
|| aStereoArg == "blend"
|| aStereoArg == "stereo")
{
- aStereoOpts = V3d_SDO_BLENDED;
+ aParams.StereoOptions = V3d_SDO_BLENDED;
}
else if (aStereoArg == "sbs"
|| aStereoArg == "sidebyside")
else if (anArg == "-rgba"
|| anArg == "rgba")
{
- aBufferType = Graphic3d_BT_RGBA;
+ aParams.BufferType = Graphic3d_BT_RGBA;
}
else if (anArg == "-rgb"
|| anArg == "rgb")
{
- aBufferType = Graphic3d_BT_RGB;
+ aParams.BufferType = Graphic3d_BT_RGB;
}
else if (anArg == "-depth"
|| anArg == "depth")
{
- aBufferType = Graphic3d_BT_Depth;
+ aParams.BufferType = Graphic3d_BT_Depth;
}
-
else if (anArg == "-width"
|| anArg == "width"
|| anArg == "sizex")
{
- if (aWidth != 0)
+ if (aParams.Width != 0)
{
std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
return 1;
std::cout << "Error: integer value is expected right after 'width'\n";
return 1;
}
- aWidth = Draw::Atoi (theArgVec[anArgIter]);
+ aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
}
else if (anArg == "-height"
|| anArg == "height"
|| anArg == "-sizey")
{
- if (aHeight != 0)
+ if (aParams.Height != 0)
{
std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
return 1;
std::cout << "Error: integer value is expected right after 'height'\n";
return 1;
}
- aHeight = Draw::Atoi (theArgVec[anArgIter]);
+ aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
+ }
+ else if (anArg == "-tile"
+ || anArg == "-tilesize")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Error: integer value is expected right after 'tileSize'\n";
+ return 1;
+ }
+ aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
}
else
{
return 1;
}
}
- if ((aWidth <= 0 && aHeight > 0)
- || (aWidth > 0 && aHeight <= 0))
+ if ((aParams.Width <= 0 && aParams.Height > 0)
+ || (aParams.Width > 0 && aParams.Height <= 0))
{
- std::cout << "Error: dimensions " << aWidth << "x" << aHeight << " are incorrect\n";
+ std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
return 1;
}
return 1;
}
- if (aWidth <= 0 || aHeight <= 0)
+ if (aParams.Width <= 0 || aParams.Height <= 0)
{
- aView->Window()->Size (aWidth, aHeight);
+ aView->Window()->Size (aParams.Width, aParams.Height);
}
Image_AlienPixMap aPixMap;
bool isBigEndian = Image_PixMap::IsBigEndianHost();
Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
- switch (aBufferType)
+ switch (aParams.BufferType)
{
case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
{
case ViewerTest_SP_Single:
{
- if (!aView->ToPixMap (aPixMap, aWidth, aHeight, aBufferType, Standard_True, aStereoOpts))
+ if (!aView->ToPixMap (aPixMap, aParams))
{
theDI << "Fail: view dump failed!\n";
return 0;
}
- else if (aPixMap.SizeX() != Standard_Size(aWidth)
- || aPixMap.SizeY() != Standard_Size(aHeight))
+ 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 " << aWidth << "x" << aHeight << "\n";
+ << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
}
break;
}
case ViewerTest_SP_SideBySide:
{
- if (!aPixMap.InitZero (aFormat, aWidth * 2, aHeight))
+ if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
{
theDI << "Fail: not enough memory for image allocation!\n";
return 0;
Image_PixMap aPixMapL, aPixMapR;
aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
- aWidth, aHeight, aPixMap.SizeRowBytes());
- aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aWidth,
- aWidth, aHeight, aPixMap.SizeRowBytes());
- if (!aView->ToPixMap (aPixMapL, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_LEFT_EYE)
- || !aView->ToPixMap (aPixMapR, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_RIGHT_EYE)
- )
+ aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
+ aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
+ aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
+
+ aParams.StereoOptions = V3d_SDO_LEFT_EYE;
+ Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
+ aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
+ isOk = isOk && aView->ToPixMap (aPixMapR, aParams);
+ if (!isOk)
{
theDI << "Fail: view dump failed!\n";
return 0;
}
case ViewerTest_SP_OverUnder:
{
- if (!aPixMap.InitZero (aFormat, aWidth, aHeight * 2))
+ if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
{
theDI << "Fail: not enough memory for image allocation!\n";
return 0;
Image_PixMap aPixMapL, aPixMapR;
aPixMapL.InitWrapper (aFormat, aPixMap.ChangeData(),
- aWidth, aHeight, aPixMap.SizeRowBytes());
- aPixMapR.InitWrapper (aFormat, aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aHeight,
- aWidth, aHeight, aPixMap.SizeRowBytes());
- if (!aView->ToPixMap (aPixMapL, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_LEFT_EYE)
- || !aView->ToPixMap (aPixMapR, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_RIGHT_EYE))
+ aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
+ aPixMapR.InitWrapper (aFormat, aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
+ aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
+
+ aParams.StereoOptions = V3d_SDO_LEFT_EYE;
+ Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
+ aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
+ isOk = isOk && aView->ToPixMap (aPixMapR, aParams);
+ if (!isOk)
{
theDI << "Fail: view dump failed!\n";
return 0;
"vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
"\n\t\t: [-buffer rgb|rgba|depth=rgb]"
"\n\t\t: [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
+ "\n\t\t: [-tileSize Size=0]"
"\n\t\t: Dumps content of the active view into image file",
__FILE__,VDump,group);
return 0;
}
+//==============================================================================
+//function : VTile
+//purpose :
+//==============================================================================
+static int VTile (Draw_Interpretor& theDI,
+ Standard_Integer theArgNb,
+ const char** theArgVec)
+{
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
+ {
+ std::cerr << "Error: no active viewer.\n";
+ return 1;
+ }
+
+ Graphic3d_CameraTile aTile = aView->Camera()->Tile();
+ if (theArgNb < 2)
+ {
+ theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
+ << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
+ << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
+ return 0;
+ }
+
+ aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+ {
+ TCollection_AsciiString anArg (theArgVec[anArgIter]);
+ anArg.LowerCase();
+ if (anArg == "-lowerleft"
+ || anArg == "-upperleft")
+ {
+ if (anArgIter + 3 < theArgNb)
+ {
+ std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+ return 1;
+ }
+ aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
+ aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
+ aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
+ }
+ else if (anArg == "-total"
+ || anArg == "-totalsize"
+ || anArg == "-viewsize")
+ {
+ if (anArgIter + 3 < theArgNb)
+ {
+ std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+ return 1;
+ }
+ aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
+ aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
+ if (aTile.TotalSize.x() < 1
+ || aTile.TotalSize.y() < 1)
+ {
+ std::cerr << "Error: total size is incorrect.\n";
+ return 1;
+ }
+ }
+ else if (anArg == "-tilesize")
+ {
+ if (anArgIter + 3 < theArgNb)
+ {
+ std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+ return 1;
+ }
+
+ aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
+ aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
+ if (aTile.TileSize.x() < 1
+ || aTile.TileSize.y() < 1)
+ {
+ std::cerr << "Error: tile size is incorrect.\n";
+ return 1;
+ }
+ }
+ else if (anArg == "-unset")
+ {
+ aView->Camera()->SetTile (Graphic3d_CameraTile());
+ aView->Redraw();
+ return 0;
+ }
+ }
+
+ if (aTile.TileSize.x() < 1
+ || aTile.TileSize.y() < 1)
+ {
+ std::cerr << "Error: tile size is undefined.\n";
+ return 1;
+ }
+ else if (aTile.TotalSize.x() < 1
+ || aTile.TotalSize.y() < 1)
+ {
+ std::cerr << "Error: total size is undefined.\n";
+ return 1;
+ }
+
+ aView->Camera()->SetTile (aTile);
+ aView->Redraw();
+ return 0;
+}
+
//==============================================================================
//function : VZLayer
//purpose : Test z layer operations for v3d viewer
" - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
" - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
__FILE__,VGraduatedTrihedron,group);
+ theCommands.Add("vtile" ,
+ "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
+ "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
+ "\n\t\t: -totalSize the size of virtual bigger viewport"
+ "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
+ "\n\t\t: -lowerLeft tile offset as lower left corner"
+ "\n\t\t: -upperLeft tile offset as upper left corner",
+ __FILE__, VTile, group);
theCommands.Add("vzlayer",
"vzlayer add/del/get/settings/enable/disable [id]\n"
" add - add new z layer to viewer and print its id\n"
--- /dev/null
+puts "========"
+puts "Tiled image dump"
+puts "========"
+
+set aFontFile ""
+catch { set aFontFile [locate_data_file DejaVuSans.ttf] }
+
+pload MODELING VISUALIZATION
+box b 2 3 1
+box b2 50 20 30
+
+set aLabelFont "Arial"
+if { "$aFontFile" != "" } {
+ vfont add "$aFontFile" SansFont
+ set aLabelFont "SansFont"
+}
+
+vclear
+vinit View1
+vraytrace 0
+vsetgradientbg 180 200 255 180 180 180 2
+vsetdispmode 0
+vdisplay -dispMode 1 b
+vfit
+vrotate 0.5 0 0
+vzbufftrihedron
+
+catch { vzlayer del 1 }
+vzlayer add 1
+vzlayer enable 1 depthclear
+
+vtrihedron trh
+vdisplay -noupdate trh -layer 1 -trsfPers trihedron -trsfPersPos 1 1 100
+
+text2brep tcc "Center" -font $aLabelFont -height 30 -pos -40 0 0
+vdisplay -noupdate tcc -2d -layer 1 -dispMode 1
+polyline lcc -50 -50 0 -50 50 0 50 50 0 50 0 0 0 -50 0 -50 -50 0
+vdisplay -noupdate lcc -2d -layer 1
+vsetwidth -noupdate lcc 2
+
+text2brep tbl "Bottom-Left" -font $aLabelFont -height 30 -pos 0 3 5
+vdisplay -noupdate tbl -2d -layer 1 -trsfPersPos -1 -1 -dispMode 1
+polyline lbl 0 0 0 0 100 0 100 100 0 100 50 0 50 0 0 0 0 0
+vdisplay -noupdate lbl -2d -layer 1 -trsfPersPos -1 -1
+vsetwidth -noupdate lbl 2
+
+text2brep ttl "Top-Left" -font $aLabelFont -height 30 -pos 0 -30 0
+vdisplay -noupdate ttl -2d -layer 1 -trsfPersPos -1 1 -dispMode 1
+polyline ltl 0 -100 0 0 0 0 100 0 0 100 -50 0 50 -100 0 0 -100 0
+vdisplay -noupdate ltl -2d -layer 1 -trsfPersPos -1 1
+vsetwidth -noupdate ltl 2
+
+text2brep ttr "Top-Right" -font $aLabelFont -height 30 -pos -130 -30 0
+vdisplay -noupdate ttr -2d -layer 1 -trsfPersPos 1 1 -dispMode 1
+polyline ltr -100 -100 0 -100 0 0 0 0 0 0 -50 0 -50 -100 0 -100 -100 0
+vdisplay -noupdate ltr -2d -layer 1 -trsfPersPos 1 1
+vsetwidth -noupdate ltr 2
+
+text2brep tbr "Bottom-Right" -font $aLabelFont -height 30 -pos -180 3 0
+vdisplay -noupdate tbr -2d -layer 1 -trsfPersPos 1 -1 -dispMode 1
+polyline lbr -100 0 0 -100 100 0 0 100 0 0 50 0 -50 0 0 -100 0 0
+vdisplay -noupdate lbr -2d -layer 1 -trsfPersPos 1 -1
+vsetwidth -noupdate lbr 2
+
+vdrawtext t2 "Label" -pos 1 0 1 -font $aLabelFont
+vdisplay b2 -trsfPers zoom -trsfPersPos 1 0 1
+
+vdump $::imagedir/${::casename}_409x409@tile0.png
+vdump $::imagedir/${::casename}_409x409@tile128.png -tileSize 128
+vdump $::imagedir/${::casename}_409x409@tile1024.png -tileSize 1024
+vdump $::imagedir/${::casename}_1920x1080@tile0.png -width 1920 -height 1920
+vdump $::imagedir/${::casename}_1920x1080@tile128.png -width 1920 -height 1920 -tileSize 128
+vdump $::imagedir/${::casename}_1920x1080@tile1024.png -width 1920 -height 1920 -tileSize 1024
+diffimage $::imagedir/${::casename}_409x409@tile0.png $::imagedir/${::casename}_409x409@tile128.png 0 0 0 $::imagedir/${::casename}_409x409@tile128diff.png
+
+# check dump with stereo
+vstereo anaglyph
+vdump $::imagedir/${::casename}_409x409@stereotile0.png -stereo blend
+vdump $::imagedir/${::casename}_409x409@stereotile128.png -stereo blend -tileSize 128
+vdump $::imagedir/${::casename}_409x409@stereotile1024.png -stereo blend -tileSize 1024
+vdump $::imagedir/${::casename}_1920x1080@stereotile0.png -width 1920 -height 1920 -stereo blend
+vdump $::imagedir/${::casename}_1920x1080@stereotile128.png -width 1920 -height 1920 -stereo blend -tileSize 128
+vdump $::imagedir/${::casename}_1920x1080@stereotile1024.png -width 1920 -height 1920 -stereo blend -tileSize 1024
+diffimage $::imagedir/${::casename}_409x409@stereotile0.png $::imagedir/${::casename}_409x409@stereotile128.png 0 0 0 $::imagedir/${::casename}_409x409@stereotile128diff.png
+
+# check dump with Ray Tracing
+vraytrace 1
+vdump $::imagedir/${::casename}_409x409@rttile0.png -stereo blend
+vdump $::imagedir/${::casename}_409x409@rttile128.png -stereo blend -tileSize 128
+vdump $::imagedir/${::casename}_409x409@rttile1024.png -stereo blend -tileSize 1024
+vdump $::imagedir/${::casename}_1920x1080@rttile0.png -width 1920 -height 1920 -stereo blend
+vdump $::imagedir/${::casename}_1920x1080@rttile128.png -width 1920 -height 1920 -stereo blend -tileSize 128
+vdump $::imagedir/${::casename}_1920x1080@rttile1024.png -width 1920 -height 1920 -stereo blend -tileSize 1024
+vraytrace 0