Added new option Graphic3d_RenderingParams::ToSmoothInterlacing enabled by default.
Added -smooth option to vstereo command.
Added -dpiAware option to vinit command (Windows).
HmdFov2d (30.0f),
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
ToReverseStereo (Standard_False),
+ ToSmoothInterlacing (Standard_True),
ToMirrorComposer (Standard_True),
//
StatsPosition (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i (20, 20))),
Graphic3d_Mat4 AnaglyphLeft; //!< left anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
Graphic3d_Mat4 AnaglyphRight; //!< right anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
Standard_Boolean ToReverseStereo; //!< flag to reverse stereo pair, FALSE by default
+ Standard_Boolean ToSmoothInterlacing; //!< flag to smooth output on interlaced displays (improves text readability / reduces line aliasing), TRUE by default
Standard_Boolean ToMirrorComposer; //!< if output device is an external composer - mirror rendering results in window in addition to sending frame to composer, TRUE by default
public: //! @name on-screen display parameters
case Graphic3d_StereoMode_RowInterlaced:
{
aName = "row-interlaced";
+ aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 uTexOffset", Graphic3d_TOS_FRAGMENT));
aSrcFrag =
EOL"void main()"
EOL"{"
- EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
- EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" vec2 aTexCoordL = TexCoord - uTexOffset;"
+ EOL" vec2 aTexCoordR = TexCoord + uTexOffset;"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoordL);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoordR);"
EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
EOL" {"
EOL" occSetFragColor (aColorL);"
case Graphic3d_StereoMode_ColumnInterlaced:
{
aName = "column-interlaced";
+ aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 uTexOffset", Graphic3d_TOS_FRAGMENT));
aSrcFrag =
EOL"void main()"
EOL"{"
- EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
- EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" vec2 aTexCoordL = TexCoord - uTexOffset;"
+ EOL" vec2 aTexCoordR = TexCoord + uTexOffset;"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoordL);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoordR);"
EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
EOL" {"
EOL" occSetFragColor (aColorL);"
case Graphic3d_StereoMode_ChessBoard:
{
aName = "chessboard";
+ aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 uTexOffset", Graphic3d_TOS_FRAGMENT));
aSrcFrag =
EOL"void main()"
EOL"{"
- EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
- EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" vec2 aTexCoordL = TexCoord - uTexOffset;"
+ EOL" vec2 aTexCoordR = TexCoord + uTexOffset;"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoordL);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoordR);"
EOL" bool isEvenX = int(mod(floor(gl_FragCoord.x - 1023.5), 2.0)) != 1;"
EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
Graphic3d_StereoMode_OverUnder, //!< vertical pair
Graphic3d_StereoMode_SoftPageFlip, //!< software PageFlip for shutter glasses, should NOT be used!
Graphic3d_StereoMode_OpenVR, //!< OpenVR (HMD)
- Graphic3d_StereoMode_NB //!< the number of modes
};
+enum { Graphic3d_StereoMode_NB = Graphic3d_StereoMode_OpenVR + 1 };
#endif // _Graphic3d_StereoMode_HeaderFile
// =======================================================================
Standard_Boolean OpenGl_ShaderManager::BindStereoProgram (Graphic3d_StereoMode theStereoMode)
{
- if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB)
+ if (theStereoMode < 0 || (int )theStereoMode >= Graphic3d_StereoMode_NB)
{
return false;
}
myContext->BindProgram (aProgram);
aProgram->SetSampler (myContext, "uLeftSampler", Graphic3d_TextureUnit_0);
aProgram->SetSampler (myContext, "uRightSampler", Graphic3d_TextureUnit_1);
+ aProgram->SetUniform (myContext, "uTexOffset", Graphic3d_Vec2(0.0f));
return true;
}
myRaytraceFBO2[1] = new OpenGl_FrameBuffer ("fbo1_raytrace2");
myDepthPeelingFbos = new OpenGl_DepthPeeling();
myShadowMaps = new OpenGl_ShadowMapArray();
+
+ myXrSceneFbo->ColorTexture()->Sampler()->Parameters()->SetFilter (Graphic3d_TOTF_BILINEAR);
}
// =======================================================================
if (!myOpenGlFBO ->InitLazy (aCtx, aPair[0]->GetVPSize(), myFboColorFormat, myFboDepthFormat, 0)
|| !myOpenGlFBO2->InitLazy (aCtx, aPair[0]->GetVPSize(), myFboColorFormat, 0, 0))
{
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
- GL_DEBUG_TYPE_ERROR,
- 0,
- GL_DEBUG_SEVERITY_HIGH,
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
"Error! Unable to allocate FBO for blitting stereo pair");
bindDefaultFbo (theDrawFbo);
return;
OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput);
const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
- if (aVerts->IsValid()
- && aManager->BindStereoProgram (myRenderParams.StereoMode))
+ if (!aVerts->IsValid()
+ || !aManager->BindStereoProgram (myRenderParams.StereoMode))
{
- if (myRenderParams.StereoMode == Graphic3d_StereoMode_Anaglyph)
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Error! Anaglyph has failed");
+ return;
+ }
+
+ switch (myRenderParams.StereoMode)
+ {
+ case Graphic3d_StereoMode_Anaglyph:
{
OpenGl_Mat4 aFilterL, aFilterR;
aFilterL.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
}
aCtx->ActiveProgram()->SetUniform (aCtx, "uMultL", aFilterL);
aCtx->ActiveProgram()->SetUniform (aCtx, "uMultR", aFilterR);
+ break;
}
-
- aPair[0]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_0);
- aPair[1]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_1);
- aVerts->BindVertexAttrib (aCtx, 0);
-
- aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
-
- aVerts->UnbindVertexAttrib (aCtx, 0);
- aPair[1]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1);
- aPair[0]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_0);
+ case Graphic3d_StereoMode_RowInterlaced:
+ {
+ Graphic3d_Vec2 aTexOffset = myRenderParams.ToSmoothInterlacing
+ ? Graphic3d_Vec2 (0.0f, -0.5f / float(aPair[0]->GetSizeY()))
+ : Graphic3d_Vec2();
+ aCtx->ActiveProgram()->SetUniform (aCtx, "uTexOffset", aTexOffset);
+ break;
+ }
+ case Graphic3d_StereoMode_ColumnInterlaced:
+ {
+ Graphic3d_Vec2 aTexOffset = myRenderParams.ToSmoothInterlacing
+ ? Graphic3d_Vec2 (0.5f / float(aPair[0]->GetSizeX()), 0.0f)
+ : Graphic3d_Vec2();
+ aCtx->ActiveProgram()->SetUniform (aCtx, "uTexOffset", aTexOffset);
+ break;
+ }
+ case Graphic3d_StereoMode_ChessBoard:
+ {
+ Graphic3d_Vec2 aTexOffset = myRenderParams.ToSmoothInterlacing
+ ? Graphic3d_Vec2 (0.5f / float(aPair[0]->GetSizeX()),
+ -0.5f / float(aPair[0]->GetSizeY()))
+ : Graphic3d_Vec2();
+ aCtx->ActiveProgram()->SetUniform (aCtx, "uTexOffset", aTexOffset);
+ break;
+ }
+ default: break;
}
- else
+
+ for (int anEyeIter = 0; anEyeIter < 2; ++anEyeIter)
{
- TCollection_ExtendedString aMsg = TCollection_ExtendedString()
- + "Error! Anaglyph has failed";
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
- GL_DEBUG_TYPE_ERROR,
- 0,
- GL_DEBUG_SEVERITY_HIGH,
- aMsg);
+ OpenGl_FrameBuffer* anEyeFbo = aPair[anEyeIter];
+ anEyeFbo->ColorTexture()->Bind (aCtx, (Graphic3d_TextureUnit )(Graphic3d_TextureUnit_0 + anEyeIter));
+ if (anEyeFbo->ColorTexture()->Sampler()->Parameters()->Filter() != Graphic3d_TOTF_BILINEAR)
+ {
+ // force filtering
+ anEyeFbo->ColorTexture()->Sampler()->Parameters()->SetFilter (Graphic3d_TOTF_BILINEAR);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
}
+ aVerts->BindVertexAttrib (aCtx, 0);
+
+ aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
+
+ aVerts->UnbindVertexAttrib (aCtx, 0);
+ aPair[1]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1);
+ aPair[0]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_0);
}
// =======================================================================
Standard_Boolean isVirtual = false;
Handle(V3d_View) aCopyFrom;
TCollection_AsciiString aName, aValue;
- int is2dMode = -1;
+ int is2dMode = -1, aDpiAware = -1;
for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
{
const TCollection_AsciiString anArg = theArgVec[anArgIt];
{
aDisplayName = theArgVec[++anArgIt];
}
+ else if (anArgCase == "-dpiaware")
+ {
+ aDpiAware = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt) ? 1 : 0;
+ }
else if (!ViewerTest::CurrentView().IsNull()
&& aCopyFrom.IsNull()
&& (anArgCase == "-copy"
}
}
+#if defined(_WIN32)
+ if (aDpiAware != -1)
+ {
+ typedef void* (WINAPI *SetThreadDpiAwarenessContext_t)(void*);
+ if (HMODULE aUser32Module = GetModuleHandleW (L"User32"))
+ {
+ SetThreadDpiAwarenessContext_t aSetDpiAware = (SetThreadDpiAwarenessContext_t )GetProcAddress (aUser32Module, "SetThreadDpiAwarenessContext");
+ if (aDpiAware == 1)
+ {
+ // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
+ if (aSetDpiAware ((void* )-4) == NULL)
+ {
+ // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE for older systems
+ if (aSetDpiAware ((void* )-3) == NULL)
+ {
+ Message::SendFail() << "Error: unable to enable DPI awareness";
+ }
+ }
+ }
+ else
+ {
+ // DPI_AWARENESS_CONTEXT_UNAWARE
+ if (aSetDpiAware ((void* )-1) == NULL)
+ {
+ Message::SendFail() << "Error: unable to disable DPI awareness";
+ }
+ }
+ }
+ }
+#else
+ (void )aDpiAware;
#if !defined(HAVE_XLIB)
if (!aDisplayName.IsEmpty())
{
aDisplayName.Clear();
Message::SendWarning() << "Warning: display parameter will be ignored.\n";
}
+#endif
#endif
ViewerTest_Names aViewNames (aViewName);
TCollection_AsciiString aMode;
switch (aView->RenderingParams().StereoMode)
{
- case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
- case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
- case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
- case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
- case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
- case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
- case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
- case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
- case Graphic3d_StereoMode_Anaglyph :
+ case Graphic3d_StereoMode_QuadBuffer:
+ {
+ aMode = "quadBuffer";
+ break;
+ }
+ case Graphic3d_StereoMode_RowInterlaced:
+ {
+ aMode = "rowInterlaced";
+ if (aView->RenderingParams().ToSmoothInterlacing)
+ {
+ aMode.AssignCat (" (smoothed)");
+ }
+ break;
+ }
+ case Graphic3d_StereoMode_ColumnInterlaced:
+ {
+ aMode = "columnInterlaced";
+ if (aView->RenderingParams().ToSmoothInterlacing)
+ {
+ aMode.AssignCat (" (smoothed)");
+ }
+ break;
+ }
+ case Graphic3d_StereoMode_ChessBoard:
+ {
+ aMode = "chessBoard";
+ if (aView->RenderingParams().ToSmoothInterlacing)
+ {
+ aMode.AssignCat (" (smoothed)");
+ }
+ break;
+ }
+ case Graphic3d_StereoMode_SideBySide:
+ {
+ aMode = "sideBySide";
+ break;
+ }
+ case Graphic3d_StereoMode_OverUnder:
+ {
+ aMode = "overUnder";
+ break;
+ }
+ case Graphic3d_StereoMode_SoftPageFlip:
+ {
+ aMode = "softPageFlip";
+ break;
+ }
+ case Graphic3d_StereoMode_OpenVR:
+ {
+ aMode = "openVR";
+ break;
+ }
+ case Graphic3d_StereoMode_Anaglyph:
+ {
aMode = "anaglyph";
switch (aView->RenderingParams().AnaglyphFilter)
{
case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
- default: break;
+ case Graphic3d_RenderingParams::Anaglyph_UserDefined : aMode.AssignCat (" (userDefined)"); break;
}
- default: break;
+ }
}
theDI << "Mode " << aMode << "\n";
}
}
}
else if (aFlag == "-reverse"
+ || aFlag == "-noreverse"
|| aFlag == "-reversed"
- || aFlag == "-swap")
- {
- Standard_Boolean toEnable = Standard_True;
- if (++anArgIter < theArgNb
- && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
- {
- --anArgIter;
- }
- aParams->ToReverseStereo = toEnable;
- }
- else if (aFlag == "-noreverse"
+ || aFlag == "-swap"
|| aFlag == "-noswap")
{
- Standard_Boolean toDisable = Standard_True;
- if (++anArgIter < theArgNb
- && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
- {
- --anArgIter;
- }
- aParams->ToReverseStereo = !toDisable;
+ aParams->ToReverseStereo = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
}
else if (aFlag == "-mode"
|| aFlag == "-stereomode")
else if (aFlag == "-mirror"
|| aFlag == "-mirrorcomposer")
{
- Standard_Boolean toEnable = Standard_True;
- if (++anArgIter < theArgNb
- && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
- {
- --anArgIter;
- }
- aParams->ToMirrorComposer = toEnable;
+ aParams->ToMirrorComposer = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);;
+ }
+ else if (aFlag == "-smooth"
+ || aFlag == "-nosmooth"
+ || aFlag == "-smoothinterlacing"
+ || aFlag == "-nosmoothinterlacing")
+ {
+ aParams->ToSmoothInterlacing = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
}
else if (anArgIter + 1 < theArgNb
&& (aFlag == "-unitfactor"
addCmd ("vinit", VInit, /* [vinit] */ R"(
vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]
[-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]
- [-display displayName]
+ [-display displayName] [-dpiAware {on|off}]
Creates new View window with specified name viewName.
By default the new view is created in the viewer and in graphic driver shared with active view.
-name {driverName/viewerName/viewName | viewerName/viewName | viewName}
-closeOnEscape when specified, view will be closed on pressing Escape.
-virtual create an offscreen window within interactive session
-2d_mode when on, view will not react on rotate scene events
+ -dpiAware override dpi aware hint (Windows platform)
Additional commands for operations with views: vclose, vactivate, vviewlist.
)" /* [vinit] */);
addCmd ("vstereo", VStereo, /* [vstereo] */ R"(
vstereo [0|1] [-mode Mode] [-reverse {0|1}]
[-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]
- [-anaglyph Filter]
+ [-anaglyph Filter] [-smoothInterlacing]
Control stereo output mode. Available modes for -mode:
quadBuffer OpenGL QuadBuffer stereo;
requires driver support;
anaglyph Anaglyph glasses, filters for -anaglyph:
redCyan, redCyanSimple, yellowBlue, yellowBlueSimple, greenMagentaSimple.
rowInterlaced row-interlaced display
+ smooth smooth interlaced output for better text readability
columnInterlaced column-interlaced display
chessBoard chess-board output
sideBySide horizontal pair
vfit
vdump $::imagedir/${::casename}_anaglyph.png -stereo blend
-vstereo -mode columnInterlaced
+vstereo -mode columnInterlaced -smooth 0
vdump $::imagedir/${::casename}_col.png -stereo blend
-vstereo -mode chessBoard
+vstereo -mode columnInterlaced -smooth 1
+vdump $::imagedir/${::casename}_col_smooth.png -stereo blend
+
+vstereo -mode chessBoard -smooth 0
vdump $::imagedir/${::casename}_chess.png -stereo blend
-vstereo -mode rowInterlaced
+vstereo -mode chessBoard -smooth 1
+vdump $::imagedir/${::casename}_chess_smooth.png -stereo blend
+
+vstereo -mode rowInterlaced -smooth 0
vdump $::imagedir/${::casename}_row.png -stereo blend
+vstereo -mode rowInterlaced -smooth 1
+vdump $::imagedir/${::casename}_row_smooth.png -stereo blend
+
vstereo -mode sideBySide
vdump $::imagedir/${::casename}_sbs_anamorph.png -stereo blend