#ifndef __Cocoa_LocalPool_h_
#define __Cocoa_LocalPool_h_
-#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc)
+#if defined(__clang__) && (__clang_major__ >= 4)
+#if __has_feature(objc_arc)
+ #define HAVE_OBJC_ARC
+#endif
+#endif
+
+#ifdef HAVE_OBJC_ARC
// @autoreleasepool should be used within ARC
#import <Cocoa/Cocoa.h>
#endif
-#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc)
- // ARC
-#else
+#ifndef HAVE_OBJC_ARC
// =======================================================================
// function : Cocoa_LocalPool
IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
-#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc)
- #define HAVE_OBJC_ARC
-#endif
-
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
//
#else
Graphic3d_ShaderVariable.hxx
Graphic3d_ShaderVariable.cxx
Graphic3d_ShaderVariable.lxx
+Graphic3d_StereoMode.hxx
Graphic3d_MapOfStructure.hxx
Graphic3d_MapIteratorOfMapOfStructure.hxx
Graphic3d_IndexedMapOfAddress.hxx
#define _Graphic3d_RenderingParams_HeaderFile
#include <Graphic3d_RenderingMode.hxx>
+#include <Graphic3d_StereoMode.hxx>
+#include <Graphic3d_Mat4.hxx>
+#include <Graphic3d_Vec4.hxx>
//! Helper class to store rendering parameters.
class Graphic3d_RenderingParams
//! Default ray-tracing depth.
static const Standard_Integer THE_DEFAULT_DEPTH = 3;
+ //! Anaglyph filter presets.
+ enum Anaglyph
+ {
+ Anaglyph_RedCyan_Simple, //!< simple filter for Red-Cyan glasses (R+GB)
+ Anaglyph_RedCyan_Optimized, //!< optimized filter for Red-Cyan glasses (R+GB)
+ Anaglyph_YellowBlue_Simple, //!< simple filter for Yellow-Blue glasses (RG+B)
+ Anaglyph_YellowBlue_Optimized, //!< optimized filter for Yellow-Blue glasses (RG+B)
+ Anaglyph_GreenMagenta_Simple, //!< simple filter for Green-Magenta glasses (G+RB)
+ Anaglyph_UserDefined //!< use externally specified matrices
+ };
+
public:
//! Creates default rendering parameters.
Graphic3d_RenderingParams()
: Method (Graphic3d_RM_RASTERIZATION),
- RaytracingDepth (THE_DEFAULT_DEPTH),
+ IsGlobalIlluminationEnabled (Standard_False),
SamplesPerPixel (THE_DEFAULT_SPP),
+ RaytracingDepth (THE_DEFAULT_DEPTH),
IsShadowEnabled (Standard_True),
IsReflectionEnabled (Standard_False),
IsAntialiasingEnabled (Standard_False),
IsTransparentShadowEnabled (Standard_False),
- IsGlobalIlluminationEnabled (Standard_False),
- UseEnvironmentMapBackground (Standard_False)
+
+ UseEnvironmentMapBackground (Standard_False),
+ StereoMode (Graphic3d_StereoMode_QuadBuffer),
+ AnaglyphFilter (Anaglyph_RedCyan_Optimized),
+ ToReverseStereo (Standard_False)
{
- //
+ const Graphic3d_Vec4 aZero (0.0f, 0.0f, 0.0f, 0.0f);
+ AnaglyphLeft .SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
+ AnaglyphLeft .SetRow (1, aZero);
+ AnaglyphLeft .SetRow (2, aZero);
+ AnaglyphLeft .SetRow (3, aZero);
+ AnaglyphRight.SetRow (0, aZero);
+ AnaglyphRight.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
+ AnaglyphRight.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
+ AnaglyphRight.SetRow (3, aZero);
}
public:
- //! Specifies rendering mode.
- Graphic3d_RenderingMode Method;
-
- //! Maximum ray-tracing depth.
- Standard_Integer RaytracingDepth;
-
- //! Number of samples per pixel (SPP).
- Standard_Integer SamplesPerPixel;
-
- //! Enables/disables shadows rendering.
- Standard_Boolean IsShadowEnabled;
-
- //! Enables/disables specular reflections.
- Standard_Boolean IsReflectionEnabled;
-
- //! Enables/disables adaptive anti-aliasing.
- Standard_Boolean IsAntialiasingEnabled;
-
- //! Enables/disables light propagation through transparent media.
- Standard_Boolean IsTransparentShadowEnabled;
-
- //! Enables/disables global illumination effects (uses path tracing).
- Standard_Boolean IsGlobalIlluminationEnabled;
-
- //! Enables/disables environment map background (instead of OCCT background).
- Standard_Boolean UseEnvironmentMapBackground;
+ Graphic3d_RenderingMode Method; //!< specifies rendering mode, Graphic3d_RM_RASTERIZATION by default
+
+ Standard_Boolean IsGlobalIlluminationEnabled; //!< enables/disables global illumination effects (path tracing)
+ Standard_Integer SamplesPerPixel; //!< number of samples per pixel (SPP)
+ Standard_Integer RaytracingDepth; //!< maximum ray-tracing depth, 3 by default
+ Standard_Boolean IsShadowEnabled; //!< enables/disables shadows rendering, True by default
+ Standard_Boolean IsReflectionEnabled; //!< enables/disables specular reflections, False by default
+ Standard_Boolean IsAntialiasingEnabled; //!< enables/disables adaptive anti-aliasing, False by default
+ Standard_Boolean IsTransparentShadowEnabled; //!< enables/disables light propagation through transparent media, False by default
+ Standard_Boolean UseEnvironmentMapBackground; //!< enables/disables environment map background
+
+ Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
+ Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
+ 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
};
--- /dev/null
+// Created on: 2015-06-05
+// Created by: Kirill Gavrilov
+// Copyright (c) 2015 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_StereoMode_HeaderFile
+#define _Graphic3d_StereoMode_HeaderFile
+
+//! This enumeration defines the list of stereoscopic output modes.
+enum Graphic3d_StereoMode
+{
+ Graphic3d_StereoMode_QuadBuffer, //!< OpenGL QuadBuffer
+ Graphic3d_StereoMode_Anaglyph, //!< Anaglyph glasses, the type should be specified in addition
+ Graphic3d_StereoMode_RowInterlaced, //!< Row-interlaced stereo
+ Graphic3d_StereoMode_ColumnInterlaced, //!< Column-interlaced stereo
+ Graphic3d_StereoMode_ChessBoard, //!< chess-board stereo for DLP TVs
+ Graphic3d_StereoMode_SideBySide, //!< horizontal pair
+ Graphic3d_StereoMode_OverUnder, //!< vertical pair
+ Graphic3d_StereoMode_SoftPageFlip, //!< software PageFlip for shutter glasses, should NOT be used!
+ Graphic3d_StereoMode_NB //!< the number of modes
+};
+
+#endif // _Graphic3d_StereoMode_HeaderFile
#include <Aspect_Drawable.hxx>
#include <Aspect_RenderingContext.hxx>
-typedef struct {
- int mapped;
-} EXT_WINDOW ;
-
/* WINDOW */
typedef struct {
Aspect_Drawable XWindow;
Aspect_Drawable XParentWindow;
- EXT_WINDOW *ext_data;
-
- struct {
- float xm, ym, xM, yM;
- } Position;
-
int dx, dy;
-
- char *Title;
-
- char *Icon;
+ int left, top;
struct {
float r, g, b;
//const OSD_WhoAmI Iam = OSD_WEnvironmentIterator;
#ifdef __APPLE__
+ #import <TargetConditionals.h>
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ extern char **environ;
+ #else
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
- #else
- extern char **environ;
#endif
#else
extern char **environ;
#else
ffpEnable (Standard_False),
#endif
+ swapInterval (1),
buffersNoSwap (Standard_False),
contextStereo (Standard_False),
#ifdef OCCT_DEBUG
pntSpritesDisable = theCopy.pntSpritesDisable;
keepArrayData = theCopy.keepArrayData;
ffpEnable = theCopy.ffpEnable;
+ swapInterval = theCopy.swapInterval;
buffersNoSwap = theCopy.buffersNoSwap;
contextStereo = theCopy.contextStereo;
contextDebug = theCopy.contextDebug;
Standard_Boolean pntSpritesDisable; //!< flag permits Point Sprites usage, will significantly affect performance (OFF by default)
Standard_Boolean keepArrayData; //!< Disables freeing CPU memory after building VBOs (OFF by default)
Standard_Boolean ffpEnable; //!< Enables FFP (fixed-function pipeline), do not use built-in GLSL programs (ON by default on desktop OpenGL and OFF on OpenGL ES)
+ Standard_Integer swapInterval; //!< controls swap interval - 0 for VSync off and 1 for VSync on, 1 by default
public: //! @name context creation parameters
//
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
#include <dlfcn.h>
+ #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ //
+ #else
+ #include <OpenGL/OpenGL.h>
+ #endif
#else
#include <GL/glx.h> // glXGetProcAddress()
#endif
#endif // __APPLE__
+// =======================================================================
+// function : SetSwapInterval
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
+{
+#if defined(HAVE_EGL)
+ if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
+ {
+ return Standard_True;
+ }
+#elif defined(_WIN32)
+ if (myFuncs->wglSwapIntervalEXT != NULL)
+ {
+ myFuncs->wglSwapIntervalEXT (theInterval);
+ return Standard_True;
+ }
+#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ //
+#elif defined(__APPLE__)
+ if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
+ {
+ return Standard_True;
+ }
+#else
+ if (theInterval == -1
+ && myFuncs->glXSwapIntervalEXT != NULL)
+ {
+ typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
+ glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
+ aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
+ return Standard_True;
+ }
+ else if (myFuncs->glXSwapIntervalSGI != NULL)
+ {
+ myFuncs->glXSwapIntervalSGI (theInterval);
+ return Standard_True;
+ }
+#endif
+ return Standard_False;
+}
+
// =======================================================================
// function : findProc
// purpose :
#define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
// retrieve platform-dependent extensions
-#if defined(_WIN32) && !defined(HAVE_EGL)
+#if defined(HAVE_EGL)
+ //
+#elif defined(_WIN32)
if (FindProcShort (wglGetExtensionsStringARB))
{
const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
FindProcShort (wglDXUnlockObjectsNV);
}
}
+#elif defined(__APPLE__)
+ //
+#else
+ const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
+ if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
+ {
+ FindProcShort (glXSwapIntervalEXT);
+ }
+ if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
+ {
+ FindProcShort (glXSwapIntervalSGI);
+ }
+ //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
#endif
// initialize debug context extension
|| (myGlVerMajor == theVerMajor && myGlVerMinor >= theVerMinor);
}
+ //! Access entire map of loaded OpenGL functions.
+ const OpenGl_GlFunctions* Functions() const { return myFuncs.operator->(); }
+
//! Clean up errors stack for this GL context (glGetError() in loop).
Standard_EXPORT void ResetErrors();
//! Swap front/back buffers for this GL context (should be activated before!).
Standard_EXPORT void SwapBuffers();
+ //! Setup swap interval (VSync).
+ Standard_EXPORT Standard_Boolean SetSwapInterval (const Standard_Integer theInterval);
+
//! Return true if active mode is GL_RENDER (cached state)
Standard_Boolean IsRender() const
{
return (aCView != NULL) && aCView->WS->BufferDump ((OpenGl_FrameBuffer* )theCView.ptrFBO, theImage, theBufferType);
}
+//! Compute aligned number greater or equal to specified one
+inline Standard_Size getAligned (const Standard_Size theNumber,
+ const Standard_Size theAlignment)
+{
+ return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
+}
+
Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
Image_PixMap& theImage,
const Graphic3d_BufferType& theBufferType)
// setup alignment
const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
+ bool isBatchCopy = !theImage.IsTopDown();
+ const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
+ GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
+ Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
+ if (anExtraBytes < anAligment)
+ {
+ aPixelsWidth = 0;
+ }
+ else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
+ {
+ aPixelsWidth = 0;
+ isBatchCopy = false;
+ }
#if !defined(GL_ES_VERSION_2_0)
- const GLint anExtraBytes = (GLint )theImage.RowExtraBytes();
- const GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
- glPixelStorei (GL_PACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
+ glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
+#else
+ if (aPixelsWidth != 0)
+ {
+ isBatchCopy = false;
+ }
#endif
- if (theImage.IsTopDown())
+ if (!isBatchCopy)
{
// copy row by row
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
myMapOfLightPrograms.Clear();
myFontProgram.Nullify();
myBlitProgram.Nullify();
- myAnaglyphProgram.Nullify();
+ for (Standard_Integer aModeIter = 0; aModeIter < Graphic3d_StereoMode_NB; ++aModeIter)
+ {
+ myStereoPrograms[aModeIter].Nullify();
+ }
switchLightPrograms();
}
}
// =======================================================================
-// function : prepareStdProgramAnaglyph
+// function : prepareStdProgramStereo
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_ShaderManager::prepareStdProgramAnaglyph()
+Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
+ const Graphic3d_StereoMode theStereoMode)
{
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
TCollection_AsciiString aSrcVert =
EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
EOL"}";
- TCollection_AsciiString aSrcFrag =
- EOL"uniform sampler2D uLeftSampler;"
- EOL"uniform sampler2D uRightSampler;"
- EOL
- EOL"THE_SHADER_IN vec2 TexCoord;"
- EOL
- EOL"void main()"
- EOL"{"
- EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
- EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
- EOL" aColorL.b = 0.0;"
- EOL" aColorL.g = 0.0;"
- EOL" aColorR.r = 0.0;"
- EOL" occFragColor = aColorL + aColorR;"
- EOL"}";
+ TCollection_AsciiString aSrcFrag;
+ switch (theStereoMode)
+ {
+ case Graphic3d_StereoMode_Anaglyph:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"uniform mat4 uMultL;"
+ EOL"uniform mat4 uMultR;"
+ EOL
+ EOL"vec4 THE_POW_UP = vec4 (2.2, 2.2, 2.2, 1.0);"
+ EOL"vec4 THE_POW_DOWN = 1.0 / THE_POW_UP;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
+ EOL" aColorR = pow (aColorR, THE_POW_UP);"
+ EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
+ EOL" occFragColor = pow (aColor, THE_POW_DOWN);"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_RowInterlaced:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" if (int (mod (gl_FragCoord.y + 1.5, 2.0)) == 1)"
+ EOL" {"
+ EOL" occFragColor = aColorL;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" occFragColor = aColorR;"
+ EOL" }"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_ColumnInterlaced:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" if (int (mod (gl_FragCoord.x + 1.5, 2.0)) != 1)"
+ EOL" {"
+ EOL" occFragColor = aColorL;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" occFragColor = aColorR;"
+ EOL" }"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_ChessBoard:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" bool isEvenX = int(mod(floor(gl_FragCoord.x + 1.5), 2.0)) == 1;"
+ EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y + 1.5), 2.0)) != 1;"
+ EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
+ EOL" {"
+ EOL" occFragColor = aColorL;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" occFragColor = aColorR;"
+ EOL" }"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_SideBySide:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec2 aTexCoord = vec2 (TexCoord.x * 2.0, TexCoord.y);"
+ EOL" if (TexCoord.x > 0.5)"
+ EOL" {"
+ EOL" aTexCoord.x -= 1.0;"
+ EOL" }"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
+ EOL" if (TexCoord.x <= 0.5)"
+ EOL" {"
+ EOL" occFragColor = aColorL;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" occFragColor = aColorR;"
+ EOL" }"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_OverUnder:
+ {
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec2 aTexCoord = vec2 (TexCoord.x, TexCoord.y * 2.0);"
+ EOL" if (TexCoord.y > 0.5)"
+ EOL" {"
+ EOL" aTexCoord.y -= 1.0;"
+ EOL" }"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
+ EOL" if (TexCoord.y <= 0.5)"
+ EOL" {"
+ EOL" occFragColor = aColorL;"
+ EOL" }"
+ EOL" else"
+ EOL" {"
+ EOL" occFragColor = aColorR;"
+ EOL" }"
+ EOL"}";
+ break;
+ }
+ case Graphic3d_StereoMode_QuadBuffer:
+ case Graphic3d_StereoMode_SoftPageFlip:
+ default:
+ {
+ /*const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[Graphic3d_StereoMode_QuadBuffer];
+ if (!aProgram.IsNull())
+ {
+ return aProgram->IsValid();
+ }*/
+ aSrcFrag =
+ EOL"uniform sampler2D uLeftSampler;"
+ EOL"uniform sampler2D uRightSampler;"
+ EOL
+ EOL"THE_SHADER_IN vec2 TexCoord;"
+ EOL
+ EOL"void main()"
+ EOL"{"
+ EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
+ EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
+ EOL" aColorL.b = 0.0;"
+ EOL" aColorL.g = 0.0;"
+ EOL" aColorR.r = 0.0;"
+ EOL" occFragColor = aColorL + aColorR;"
+ EOL"}";
+ break;
+ }
+ }
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core32 != NULL)
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
TCollection_AsciiString aKey;
- if (!Create (aProgramSrc, aKey, myAnaglyphProgram))
+ if (!Create (aProgramSrc, aKey, theProgram))
{
- myAnaglyphProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+ theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
return Standard_False;
}
- myContext->BindProgram (myAnaglyphProgram);
- myAnaglyphProgram->SetSampler (myContext, "uLeftSampler", 0);
- myAnaglyphProgram->SetSampler (myContext, "uRightSampler", 1);
+ myContext->BindProgram (theProgram);
+ theProgram->SetSampler (myContext, "uLeftSampler", 0);
+ theProgram->SetSampler (myContext, "uRightSampler", 1);
myContext->BindProgram (NULL);
return Standard_True;
}
#define _OpenGl_ShaderManager_HeaderFile
#include <Graphic3d_ShaderProgram.hxx>
+#include <Graphic3d_StereoMode.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_Sequence.hxx>
&& myContext->BindProgram (myBlitProgram);
}
- //! Bind program for rendering Anaglyph image.
- Standard_Boolean BindAnaglyphProgram()
+ //! Bind program for rendering stereoscopic image.
+ Standard_Boolean BindStereoProgram (const Graphic3d_StereoMode theStereoMode)
{
- if (myAnaglyphProgram.IsNull())
+ if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB)
{
- prepareStdProgramAnaglyph();
+ return Standard_False;
}
- return !myAnaglyphProgram.IsNull()
- && myContext->BindProgram (myAnaglyphProgram);
+
+ if (myStereoPrograms[theStereoMode].IsNull())
+ {
+ prepareStdProgramStereo (myStereoPrograms[theStereoMode], theStereoMode);
+ }
+ const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[theStereoMode];
+ return !aProgram.IsNull()
+ && myContext->BindProgram (aProgram);
}
public:
//! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms
Standard_EXPORT void switchLightPrograms();
- //! Prepare standard GLSL program for Anaglyph image.
- Standard_EXPORT Standard_Boolean prepareStdProgramAnaglyph();
+ //! Prepare standard GLSL program for stereoscopic image.
+ Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
+ const Graphic3d_StereoMode theStereoMode);
protected:
Handle(OpenGl_ShaderProgram) myBlitProgram; //!< standard program for FBO blit emulation
OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on shading model and lights configuration
- Handle(OpenGl_ShaderProgram) myAnaglyphProgram; //!< standard program for Anaglyph image
+ Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
OpenGl_Context* myContext; //!< OpenGL context
myOwnGContext (theGContext == 0),
myWidth (theCWindow.dx),
myHeight (theCWindow.dy),
- myBgColor (THE_DEFAULT_BG_COLOR)
+ myBgColor (THE_DEFAULT_BG_COLOR),
+ mySwapInterval (theCaps->swapInterval)
{
myBgColor.rgb[0] = theCWindow.Background.r;
myBgColor.rgb[1] = theCWindow.Background.g;
myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )aDisp, (Aspect_RenderingContext )aGContext, isCoreProfile);
#endif
myGlContext->Share (theShareCtx);
-
+ myGlContext->SetSwapInterval (mySwapInterval);
Init();
}
Standard_Integer myHeight; //!< window height in pixels
TEL_COLOUR myBgColor; //!< background color
+ Standard_Integer mySwapInterval;//!< last assigned swap interval (VSync) for this window
+
public:
DEFINE_STANDARD_RTTI(OpenGl_Window) // Type definition
#endif
myWidth (theCWindow.dx),
myHeight (theCWindow.dy),
- myBgColor (THE_DEFAULT_BG_COLOR)
+ myBgColor (THE_DEFAULT_BG_COLOR),
+ mySwapInterval (theCaps->swapInterval)
{
myBgColor.rgb[0] = theCWindow.Background.r;
myBgColor.rgb[1] = theCWindow.Background.g;
#endif
myGlContext->Share (theShareCtx);
+ myGlContext->SetSwapInterval (mySwapInterval);
Init();
}
{
return false;
}
+ else if (theReadFbo == theDrawFbo)
+ {
+ return true;
+ }
// clear destination before blitting
if (theDrawFbo != NULL
// function : drawStereoPair
// purpose :
// =======================================================================
-void OpenGl_Workspace::drawStereoPair()
+void OpenGl_Workspace::drawStereoPair (const Graphic3d_CView& theCView)
{
OpenGl_FrameBuffer* aPair[2] =
{
myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
};
if (aPair[0] == NULL
- || aPair[1] == NULL)
+ || aPair[1] == NULL
+ || !myTransientDrawToFront)
{
aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL;
return;
}
+ Standard_Boolean toReverse = theCView.RenderParams.ToReverseStereo;
+ const Standard_Boolean isOddY = (theCView.DefWindow.top + theCView.DefWindow.dy) % 2 == 1;
+ const Standard_Boolean isOddX = theCView.DefWindow.left % 2 == 1;
+ if (isOddY
+ && (theCView.RenderParams.StereoMode == Graphic3d_StereoMode_RowInterlaced
+ || theCView.RenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard))
+ {
+ toReverse = !toReverse;
+ }
+ if (isOddX
+ && (theCView.RenderParams.StereoMode == Graphic3d_StereoMode_ColumnInterlaced
+ || theCView.RenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard))
+ {
+ toReverse = !toReverse;
+ }
+
+ if (toReverse)
+ {
+ std::swap (aPair[0], aPair[1]);
+ }
+
myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
myGlContext->core20fwd->glDepthMask (GL_TRUE);
myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
if (myFullScreenQuad.IsValid()
- && aManager->BindAnaglyphProgram())
+ && aManager->BindStereoProgram (theCView.RenderParams.StereoMode))
{
+ if (theCView.RenderParams.StereoMode == Graphic3d_StereoMode_Anaglyph)
+ {
+ OpenGl_Mat4 aFilterL, aFilterR;
+ aFilterL.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+ aFilterR.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+ switch (theCView.RenderParams.AnaglyphFilter)
+ {
+ case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple:
+ {
+ aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
+ break;
+ }
+ case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized:
+ {
+ aFilterL.SetRow (0, Graphic3d_Vec4 ( 0.4154f, 0.4710f, 0.16666667f, 0.0f));
+ aFilterL.SetRow (1, Graphic3d_Vec4 (-0.0458f, -0.0484f, -0.0257f, 0.0f));
+ aFilterL.SetRow (2, Graphic3d_Vec4 (-0.0547f, -0.0615f, 0.0128f, 0.0f));
+ aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (0, Graphic3d_Vec4 (-0.01090909f, -0.03636364f, -0.00606061f, 0.0f));
+ aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.37560000f, 0.73333333f, 0.01111111f, 0.0f));
+ aFilterR.SetRow (2, Graphic3d_Vec4 (-0.06510000f, -0.12870000f, 1.29710000f, 0.0f));
+ aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
+ break;
+ }
+ case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple:
+ {
+ aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
+ aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
+ break;
+ }
+ case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized:
+ {
+ aFilterL.SetRow (0, Graphic3d_Vec4 ( 1.062f, -0.205f, 0.299f, 0.0f));
+ aFilterL.SetRow (1, Graphic3d_Vec4 (-0.026f, 0.908f, 0.068f, 0.0f));
+ aFilterL.SetRow (2, Graphic3d_Vec4 (-0.038f, -0.173f, 0.022f, 0.0f));
+ aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (0, Graphic3d_Vec4 (-0.016f, -0.123f, -0.017f, 0.0f));
+ aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.006f, 0.062f, -0.017f, 0.0f));
+ aFilterR.SetRow (2, Graphic3d_Vec4 ( 0.094f, 0.185f, 0.911f, 0.0f));
+ aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f));
+ break;
+ }
+ case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple:
+ {
+ aFilterR.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f));
+ aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
+ aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
+ break;
+ }
+ case Graphic3d_RenderingParams::Anaglyph_UserDefined:
+ {
+ aFilterL = theCView.RenderParams.AnaglyphLeft;
+ aFilterR = theCView.RenderParams.AnaglyphRight;
+ break;
+ }
+ }
+ myGlContext->ActiveProgram()->SetUniform (myGlContext, "uMultL", aFilterL);
+ myGlContext->ActiveProgram()->SetUniform (myGlContext, "uMultR", aFilterR);
+ }
+
aPair[0]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 0);
aPair[1]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
return;
}
+ if (mySwapInterval != myGlContext->caps->swapInterval)
+ {
+ mySwapInterval = myGlContext->caps->swapInterval;
+ myGlContext->SetSwapInterval (mySwapInterval);
+ }
+
++myFrameCounter;
myIsCullingEnabled = theCView.IsCullingEnabled;
+ const Graphic3d_StereoMode aStereoMode = theCView.RenderParams.StereoMode;
+ const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
+ Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
// release pending GL resources
myGlContext->ReleaseDelayed();
}
if (myHasFboBlit
- && myTransientDrawToFront)
+ && (myTransientDrawToFront || aProjectType == Graphic3d_Camera::Projection_Stereo))
{
if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
|| myMainSceneFbos[0]->GetVPSizeY() != aSizeY)
myImmediateSceneFbos[1]->ChangeViewport (0, 0);
}
- // draw entire frame using normal OpenGL pipeline
- const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
- Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
- if (aProjectType == Graphic3d_Camera::Projection_Stereo)
+ if (aProjectType == Graphic3d_Camera::Projection_Stereo
+ && myMainSceneFbos[0]->IsValid())
{
- if (aFrameBuffer != NULL
- || !myGlContext->IsRender())
+ myMainSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
+ if (!myMainSceneFbos[1]->IsValid())
{
- // implicitly switch to mono camera for image dump
+ // no enough memory?
aProjectType = Graphic3d_Camera::Projection_Perspective;
}
- else if (myMainSceneFbos[0]->IsValid())
+ else if (!myTransientDrawToFront)
{
- myMainSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
- if (!myMainSceneFbos[1]->IsValid())
+ //
+ }
+ else if (!myGlContext->HasStereoBuffers()
+ || aStereoMode != Graphic3d_StereoMode_QuadBuffer)
+ {
+ myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY);
+ myImmediateSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
+ if (!myImmediateSceneFbos[0]->IsValid()
+ || !myImmediateSceneFbos[1]->IsValid())
{
- // no enough memory?
aProjectType = Graphic3d_Camera::Projection_Perspective;
}
- else if (!myGlContext->HasStereoBuffers())
- {
- myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY);
- myImmediateSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
- if (!myImmediateSceneFbos[0]->IsValid()
- || !myImmediateSceneFbos[1]->IsValid())
- {
- aProjectType = Graphic3d_Camera::Projection_Perspective;
- }
- }
}
}
myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
};
+ if (!myTransientDrawToFront)
+ {
+ anImmFbos[0] = aMainFbos[0];
+ anImmFbos[1] = aMainFbos[1];
+ }
+ else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
+ || aStereoMode == Graphic3d_StereoMode_QuadBuffer)
+ {
+ anImmFbos[0] = NULL;
+ anImmFbos[1] = NULL;
+ }
+
#if !defined(GL_ES_VERSION_2_0)
- myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
+ myGlContext->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
#endif
redraw1 (theCView, theCUnderLayer, theCOverLayer,
aMainFbos[0], Graphic3d_Camera::Projection_MonoLeftEye);
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
#if !defined(GL_ES_VERSION_2_0)
- myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
+ myGlContext->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
#endif
if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[0], aProjectType, anImmFbos[0]))
{
toSwap = false;
}
+ else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
+ && toSwap)
+ {
+ myGlContext->SwapBuffers();
+ }
#if !defined(GL_ES_VERSION_2_0)
- myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
+ myGlContext->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
#endif
redraw1 (theCView, theCUnderLayer, theCOverLayer,
aMainFbos[1], Graphic3d_Camera::Projection_MonoRightEye);
if (anImmFbos[0] != NULL)
{
bindDefaultFbo (aFrameBuffer);
- drawStereoPair();
+ drawStereoPair (theCView);
}
}
else
aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
}
+ const Graphic3d_StereoMode aStereoMode = theCView.RenderParams.StereoMode;
if (aProjectType == Graphic3d_Camera::Projection_Stereo)
{
if (aFrameBuffer != NULL)
myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
};
+ if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
+ || aStereoMode == Graphic3d_StereoMode_QuadBuffer)
+ {
+ anImmFbos[0] = NULL;
+ anImmFbos[1] = NULL;
+ }
if (myGlContext->arbFBO != NULL)
{
#if !defined(GL_ES_VERSION_2_0)
if (anImmFbos[0] == NULL)
{
- myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
+ myGlContext->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
}
#endif
toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
Graphic3d_Camera::Projection_MonoLeftEye,
anImmFbos[0],
Standard_True) || toSwap;
+ if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
+ && toSwap
+ && !myGlContext->caps->buffersNoSwap)
+ {
+ myGlContext->SwapBuffers();
+ }
if (myGlContext->arbFBO != NULL)
{
#if !defined(GL_ES_VERSION_2_0)
if (anImmFbos[1] == NULL)
{
- myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
+ myGlContext->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
}
#endif
toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
if (anImmFbos[0] != NULL)
{
bindDefaultFbo (aFrameBuffer);
- drawStereoPair();
+ drawStereoPair (theCView);
}
}
else
void bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo = NULL);
//! Blend together views pair into stereo image.
- void drawStereoPair();
+ void drawStereoPair (const Graphic3d_CView& theCView);
//! Blit snapshot containing main scene (myMainSceneFbos or BackBuffer)
//! into presentation buffer (myMainSceneFbos -> offscreen FBO or myMainSceneFbos -> BackBuffer or BackBuffer -> FrontBuffer),
V3d_Plane.hxx
V3d_Plane.cxx
V3d_ListOfTransient.hxx
+V3d_StereoDumpOptions.hxx
-- TOBM_ALWAYS_DISPLAYED force display of back faces
-- TOBM_NEVER_DISPLAYED disable display of back faces
- enumeration StereoDumpOptions is
- SDO_MONO,
- SDO_LEFT_EYE,
- SDO_RIGHT_EYE
- end StereoDumpOptions;
- ---Purpose : Options to be used with image dumping.
- --
- -- SDO_MONO dump monographic projection for stereo camera
- -- SDO_LEFT_EYE dump left eye projection for stereo camera
- -- SDO_RIGHT_EYE dump right eye projection for stereo camera
+ primitive StereoDumpOptions;
------------------------
---Category: The classes
--- /dev/null
+// Created on: 2015-06-05
+// Created by: Kirill Gavrilov
+// Copyright (c) 2015 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_StereoDumpOptions_HeaderFile
+#define _V3d_StereoDumpOptions_HeaderFile
+
+//! Options to be used with image dumping.
+//! Notice that the value will have no effect with disabled stereo output.
+enum V3d_StereoDumpOptions
+{
+ V3d_SDO_MONO, //!< ignore stereo mode and dump monographic projection for stereo camera
+ V3d_SDO_LEFT_EYE, //!< dump only left eye projection for stereo camera
+ V3d_SDO_RIGHT_EYE, //!< dump only right eye projection for stereo camera
+ V3d_SDO_BLENDED //!< dump blended pair specific to the active device output Graphic3d_StereoMode (result will be undefined for modes like Graphic3d_StereoMode_QuadBuffer)
+};
+
+#endif // _V3d_StereoDumpOptions_HeaderFile
{
switch (theStereoOptions)
{
- case V3d_SDO_MONO :
+ case V3d_SDO_MONO:
+ {
myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
break;
-
- case V3d_SDO_LEFT_EYE :
+ }
+ case V3d_SDO_LEFT_EYE:
+ {
myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
break;
-
- case V3d_SDO_RIGHT_EYE :
+ }
+ case V3d_SDO_RIGHT_EYE:
+ {
myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
break;
+ }
+ case V3d_SDO_BLENDED:
+ {
+ break; // dump as is
+ }
}
}
return 0;
}
+//! Auxiliary enumeration
+enum ViewerTest_StereoPair
+{
+ ViewerTest_SP_Single,
+ ViewerTest_SP_SideBySide,
+ ViewerTest_SP_OverUnder
+};
+
//==============================================================================
//function : VDump
//purpose : To dump the active view snapshot to image file
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;
for (; anArgIter < theArgNb; ++anArgIter)
{
TCollection_AsciiString anArg (theArgVec[anArgIter]);
anArg.LowerCase();
- if (anArg == "rgba")
+ if (anArg == "-buffer")
{
- aBufferType = Graphic3d_BT_RGBA;
- }
- else if (anArg == "rgb")
- {
- aBufferType = Graphic3d_BT_RGB;
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
+ aBufArg.LowerCase();
+ if (aBufArg == "rgba")
+ {
+ aBufferType = Graphic3d_BT_RGBA;
+ }
+ else if (aBufArg == "rgb")
+ {
+ aBufferType = Graphic3d_BT_RGB;
+ }
+ else if (aBufArg == "depth")
+ {
+ aBufferType = Graphic3d_BT_Depth;
+ }
+ else
+ {
+ std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
+ return 1;
+ }
}
- else if (anArg == "depth")
+ else if (anArg == "-stereo")
{
- aBufferType = Graphic3d_BT_Depth;
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
+ aStereoArg.LowerCase();
+ if (aStereoArg == "l"
+ || aStereoArg == "left")
+ {
+ aStereoOpts = V3d_SDO_LEFT_EYE;
+ }
+ else if (aStereoArg == "r"
+ || aStereoArg == "right")
+ {
+ aStereoOpts = V3d_SDO_RIGHT_EYE;
+ }
+ else if (aStereoArg == "mono")
+ {
+ aStereoOpts = V3d_SDO_MONO;
+ }
+ else if (aStereoArg == "blended"
+ || aStereoArg == "blend"
+ || aStereoArg == "stereo")
+ {
+ aStereoOpts = V3d_SDO_BLENDED;
+ }
+ else if (aStereoArg == "sbs"
+ || aStereoArg == "sidebyside")
+ {
+ aStereoPair = ViewerTest_SP_SideBySide;
+ }
+ else if (aStereoArg == "ou"
+ || aStereoArg == "overunder")
+ {
+ aStereoPair = ViewerTest_SP_OverUnder;
+ }
+ else
+ {
+ std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
+ return 1;
+ }
}
- else if (anArg == "l"
- || anArg == "left")
+ else if (anArg == "-rgba"
+ || anArg == "rgba")
{
- aStereoOpts = V3d_SDO_LEFT_EYE;
+ aBufferType = Graphic3d_BT_RGBA;
}
- else if (anArg == "r"
- || anArg == "right")
+ else if (anArg == "-rgb"
+ || anArg == "rgb")
{
- aStereoOpts = V3d_SDO_RIGHT_EYE;
+ aBufferType = Graphic3d_BT_RGB;
}
- else if (anArg == "mono")
+ else if (anArg == "-depth"
+ || anArg == "depth")
{
- aStereoOpts = V3d_SDO_MONO;
+ aBufferType = Graphic3d_BT_Depth;
}
- else if (anArg == "w"
- || anArg == "width")
+
+ else if (anArg == "-width"
+ || anArg == "width"
+ || anArg == "sizex")
{
- if (aWidth != 0)
+ if (aWidth != 0)
{
std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
return 1;
}
aWidth = Draw::Atoi (theArgVec[anArgIter]);
}
- else if (anArg == "h"
- || anArg == "height")
+ else if (anArg == "-height"
+ || anArg == "height"
+ || anArg == "-sizey")
{
if (aHeight != 0)
{
std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
return 1;
}
- if (++anArgIter >= theArgNb)
- {
- std::cout << "Error: integer value is expected right after 'height'\n";
- return 1;
- }
- aHeight = Draw::Atoi (theArgVec[anArgIter]);
- }
- else if (anArg.IsIntegerValue())
- {
- // compatibility with old syntax
- if (aWidth != 0
- || aHeight != 0)
- {
- std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
- return 1;
- }
else if (++anArgIter >= theArgNb)
{
- std::cout << "Error: height value is expected right after width\n";
+ std::cout << "Error: integer value is expected right after 'height'\n";
return 1;
}
- aWidth = Draw::Atoi (theArgVec[anArgIter - 1]);
aHeight = Draw::Atoi (theArgVec[anArgIter]);
}
else
if (aWidth <= 0 || aHeight <= 0)
{
- if (aStereoOpts != V3d_SDO_MONO)
+ aView->Window()->Size (aWidth, aHeight);
+ }
+
+ Image_AlienPixMap aPixMap;
+
+ bool isBigEndian = Image_PixMap::IsBigEndianHost();
+ Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
+ switch (aBufferType)
+ {
+ 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;
+ }
+
+ switch (aStereoPair)
+ {
+ case ViewerTest_SP_Single:
{
- aView->Window()->Size (aWidth, aHeight);
+ if (!aView->ToPixMap (aPixMap, aWidth, aHeight, aBufferType, Standard_True, aStereoOpts))
+ {
+ theDI << "Fail: view dump failed!\n";
+ return 0;
+ }
+ else if (aPixMap.SizeX() != Standard_Size(aWidth)
+ || aPixMap.SizeY() != Standard_Size(aHeight))
+ {
+ theDI << "Fail: dumped dimensions " << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
+ << " are lesser than requested " << aWidth << "x" << aHeight << "\n";
+ }
+ break;
}
- else
+ case ViewerTest_SP_SideBySide:
{
- if (!aView->Dump (aFilePath, aBufferType))
+ if (!aPixMap.InitZero (aFormat, aWidth * 2, aHeight))
+ {
+ 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)
+ )
{
theDI << "Fail: view dump failed!\n";
+ return 0;
}
- return 0;
+ break;
}
- }
+ case ViewerTest_SP_OverUnder:
+ {
+ if (!aPixMap.InitZero (aFormat, aWidth, aHeight * 2))
+ {
+ theDI << "Fail: not enough memory for image allocation!\n";
+ return 0;
+ }
- Image_AlienPixMap aPixMap;
- if (!aView->ToPixMap (aPixMap, aWidth, aHeight, aBufferType, Standard_True, aStereoOpts))
- {
- theDI << "Fail: view dump failed!\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))
+ {
+ theDI << "Fail: view dump failed!\n";
+ return 0;
+ }
+ break;
+ }
}
- if (aPixMap.SizeX() != Standard_Size(aWidth)
- || aPixMap.SizeY() != Standard_Size(aHeight))
- {
- theDI << "Fail: dumped dimensions " << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
- << " are lesser than requested " << aWidth << "x" << aHeight << "\n";
- }
if (!aPixMap.Save (aFilePath))
{
theDI << "Fail: image can not be saved!\n";
return 0;
}
-
//==============================================================================
//function : Displays,Erase...
//purpose :
"Lists all objects displayed in 3D viewer",
__FILE__,VDir,group);
+#ifdef HAVE_FREEIMAGE
+ #define DUMP_FORMATS "{png|bmp|jpg|gif}"
+#else
+ #define DUMP_FORMATS "{ppm}"
+#endif
theCommands.Add("vdump",
- #ifdef HAVE_FREEIMAGE
- "vdump <filename>.{png|bmp|jpg|gif} [rgb|rgba|depth=rgb] [mono|left|right=mono]"
- "\n\t\t: [width Width=0 height Height=0]"
- "\n\t\t: Dumps content of the active view into PNG, BMP, JPEG or GIF file",
- #else
- "vdump <filename>.{ppm} [rgb|rgba|depth=rgb] [mono|left|right=mono]"
- "\n\t\t: [width Width=0 height Height=0]"
- "\n\t\t: Dumps content of the active view into PPM image file",
- #endif
+ "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: Dumps content of the active view into image file",
__FILE__,VDump,group);
theCommands.Add("vsub", "vsub 0/1 (off/on) [obj] : Subintensity(on/off) of selected objects",
{
ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
}
+ else if (!strcasecmp (buf_ret, "/"))
+ {
+ Handle(Graphic3d_Camera) aCamera = aView->Camera();
+ if (aCamera->IsStereo())
+ {
+ aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
+ aView->Redraw();
+ }
+ }
+ else if (!strcasecmp (buf_ret, "*"))
+ {
+ Handle(Graphic3d_Camera) aCamera = aView->Camera();
+ if (aCamera->IsStereo())
+ {
+ aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
+ aView->Redraw();
+ }
+ }
else if (*buf_ret == THE_KEY_DELETE)
{
Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
LPARAM lParam )
{
static int Up = 1;
+ const Handle(V3d_View)& aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
+ {
+ return DefWindowProc( hwnd, Msg, wParam, lParam );
+ }
- if ( !ViewerTest::CurrentView().IsNull() ) {
PAINTSTRUCT ps;
switch( Msg ) {
case WM_SIZE:
VT_ProcessConfigure();
break;
+ case WM_MOVE:
+ case WM_MOVING:
+ case WM_SIZING:
+ switch (aView->RenderingParams().StereoMode)
+ {
+ case Graphic3d_StereoMode_RowInterlaced:
+ case Graphic3d_StereoMode_ColumnInterlaced:
+ case Graphic3d_StereoMode_ChessBoard:
+ VT_ProcessConfigure(); // track window moves to reverse stereo pair
+ break;
+ default:
+ break;
+ }
+ break;
case WM_KEYDOWN:
if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
{
c[0] = '.';
}
+ else if (wParam == VK_DIVIDE)
+ {
+ c[0] = '/';
+ }
+ // dot
+ else if (wParam == VK_MULTIPLY)
+ {
+ c[0] = '*';
+ }
VT_ProcessKeyPress (c);
}
break;
}
break;
+ case WM_MOUSEWHEEL:
+ {
+ int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
+ if (wParam & MK_CONTROL)
+ {
+ if (aView->Camera()->IsStereo())
+ {
+ Standard_Real aFocus = aView->Camera()->ZFocus() + (aDelta > 0 ? 0.05 : -0.05);
+ if (aFocus > 0.2
+ && aFocus < 2.0)
+ {
+ aView->Camera()->SetZFocus (aView->Camera()->ZFocusType(), aFocus);
+ aView->Redraw();
+ }
+ }
+ }
+ else
+ {
+ aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
+ }
+ break;
+ }
+
case WM_MOUSEMOVE:
{
//cout << "\t WM_MOUSEMOVE" << endl;
return( DefWindowProc( hwnd, Msg, wParam, lParam ));
}
return 0L;
- }
-
- return DefWindowProc( hwnd, Msg, wParam, lParam );
}
theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
+ theDI << "VSync: " << aCaps->swapInterval << "\n";
theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
+ theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
return 0;
}
{
continue;
}
+ else if (anArgCase == "-vsync"
+ || anArgCase == "-swapinterval")
+ {
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aCaps->swapInterval = toEnable;
+ }
else if (anArgCase == "-ffp")
{
Standard_Boolean toEnable = Standard_True;
aCaps->ffpEnable = Standard_False;
}
}
+ else if (anArgCase == "-stereo"
+ || anArgCase == "-quadbuffer")
+ {
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aCaps->contextStereo = toEnable;
+ }
else
{
std::cout << "Error: unknown argument '" << anArg << "'\n";
return 0;
}
+//! Parse stereo output mode
+inline Standard_Boolean parseStereoMode (Standard_CString theArg,
+ Graphic3d_StereoMode& theMode)
+{
+ TCollection_AsciiString aFlag (theArg);
+ aFlag.LowerCase();
+ if (aFlag == "quadbuffer")
+ {
+ theMode = Graphic3d_StereoMode_QuadBuffer;
+ }
+ else if (aFlag == "anaglyph")
+ {
+ theMode = Graphic3d_StereoMode_Anaglyph;
+ }
+ else if (aFlag == "row"
+ || aFlag == "rowinterlaced")
+ {
+ theMode = Graphic3d_StereoMode_RowInterlaced;
+ }
+ else if (aFlag == "col"
+ || aFlag == "colinterlaced"
+ || aFlag == "columninterlaced")
+ {
+ theMode = Graphic3d_StereoMode_ColumnInterlaced;
+ }
+ else if (aFlag == "chess"
+ || aFlag == "chessboard")
+ {
+ theMode = Graphic3d_StereoMode_ChessBoard;
+ }
+ else if (aFlag == "sbs"
+ || aFlag == "sidebyside")
+ {
+ theMode = Graphic3d_StereoMode_SideBySide;
+ }
+ else if (aFlag == "ou"
+ || aFlag == "overunder")
+ {
+ theMode = Graphic3d_StereoMode_OverUnder;
+ }
+ else if (aFlag == "pageflip"
+ || aFlag == "softpageflip")
+ {
+ theMode = Graphic3d_StereoMode_SoftPageFlip;
+ }
+ else
+ {
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
+//! Parse anaglyph filter
+inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
+ Graphic3d_RenderingParams::Anaglyph& theFilter)
+{
+ TCollection_AsciiString aFlag (theArg);
+ aFlag.LowerCase();
+ if (aFlag == "redcyansimple")
+ {
+ theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
+ }
+ else if (aFlag == "redcyan"
+ || aFlag == "redcyanoptimized")
+ {
+ theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
+ }
+ else if (aFlag == "yellowbluesimple")
+ {
+ theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
+ }
+ else if (aFlag == "yellowblue"
+ || aFlag == "yellowblueoptimized")
+ {
+ theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
+ }
+ else if (aFlag == "greenmagenta"
+ || aFlag == "greenmagentasimple")
+ {
+ theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
+ }
+ else
+ {
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
//==============================================================================
//function : VStereo
//purpose :
Standard_Integer theArgNb,
const char** theArgVec)
{
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
if (theArgNb < 2)
{
- Handle(V3d_View) aView = ViewerTest::CurrentView();
if (aView.IsNull())
{
- std::cerr << "No active view. Please call vinit.\n";
+ std::cout << "Error: no active viewer!\n";
return 0;
}
return 0;
}
- ViewerTest_myDefaultCaps.contextStereo = Draw::Atoi (theArgVec[1]) != 0;
+ Handle(Graphic3d_Camera) aCamera;
+ Graphic3d_RenderingParams* aParams = NULL;
+ Graphic3d_StereoMode aMode = Graphic3d_StereoMode_QuadBuffer;
+ if (!aView.IsNull())
+ {
+ aParams = &aView->ChangeRenderingParams();
+ aMode = aParams->StereoMode;
+ aCamera = aView->Camera();
+ }
+
+ ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+ {
+ Standard_CString anArg = theArgVec[anArgIter];
+ TCollection_AsciiString aFlag (anArg);
+ aFlag.LowerCase();
+ if (anUpdateTool.parseRedrawMode (aFlag))
+ {
+ continue;
+ }
+ else if (aFlag == "0"
+ || aFlag == "off")
+ {
+ if (++anArgIter < theArgNb)
+ {
+ std::cout << "Error: wrong number of arguments!\n";
+ return 1;
+ }
+
+ if (!aCamera.IsNull()
+ && aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
+ {
+ aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
+ }
+ ViewerTest_myDefaultCaps.contextStereo = Standard_False;
+ return 0;
+ }
+ else if (aFlag == "1"
+ || aFlag == "on")
+ {
+ if (++anArgIter < theArgNb)
+ {
+ std::cout << "Error: wrong number of arguments!\n";
+ return 1;
+ }
+
+ if (!aCamera.IsNull())
+ {
+ aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
+ }
+ ViewerTest_myDefaultCaps.contextStereo = Standard_True;
+ return 0;
+ }
+ else if (aFlag == "-reverse"
+ || aFlag == "-reversed"
+ || aFlag == "-swap")
+ {
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aParams->ToReverseStereo = toEnable;
+ }
+ else if (aFlag == "-noreverse"
+ || aFlag == "-noswap")
+ {
+ Standard_Boolean toDisable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toDisable))
+ {
+ --anArgIter;
+ }
+ aParams->ToReverseStereo = !toDisable;
+ }
+ else if (aFlag == "-mode"
+ || aFlag == "-stereomode")
+ {
+ if (++anArgIter >= theArgNb
+ || !parseStereoMode (theArgVec[anArgIter], aMode))
+ {
+ std::cout << "Error: syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+
+ if (aMode == Graphic3d_StereoMode_QuadBuffer)
+ {
+ ViewerTest_myDefaultCaps.contextStereo = Standard_True;
+ }
+ }
+ else if (aFlag == "-anaglyph"
+ || aFlag == "-anaglyphfilter")
+ {
+ Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
+ if (++anArgIter >= theArgNb
+ || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
+ {
+ std::cout << "Error: syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+
+ aMode = Graphic3d_StereoMode_Anaglyph;
+ aParams->AnaglyphFilter = aFilter;
+ }
+ else if (parseStereoMode (anArg, aMode)) // short syntax
+ {
+ if (aMode == Graphic3d_StereoMode_QuadBuffer)
+ {
+ ViewerTest_myDefaultCaps.contextStereo = Standard_True;
+ }
+ }
+ else
+ {
+ std::cout << "Error: syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+ }
+
+ if (!aView.IsNull())
+ {
+ aParams->StereoMode = aMode;
+ aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
+ }
return 0;
}
"vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
__FILE__, VVbo, group);
theCommands.Add ("vstereo",
- "\nvstereo [{0|1}] : turn stereo usage On/Off; affects only newly displayed objects",
+ "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
+ "\n\t\t: [-anaglyph Filter]"
+ "\n\t\t: Control stereo output mode. Available modes for -mode:"
+ "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
+ "\n\t\t: requires driver support."
+ "\n\t\t: Should be called BEFORE vinit!"
+ "\n\t\t: anaglyph - Anaglyph glasses"
+ "\n\t\t: rowInterlaced - row-interlaced display"
+ "\n\t\t: columnInterlaced - column-interlaced display"
+ "\n\t\t: chessBoard - chess-board output"
+ "\n\t\t: sideBySide - horizontal pair"
+ "\n\t\t: overUnder - vertical pair"
+ "\n\t\t: Available Anaglyph filters for -anaglyph:"
+ "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
+ "\n\t\t: greenMagentaSimple",
__FILE__, VStereo, group);
theCommands.Add ("vcaps",
"vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
"\n\t\t: [-compatibleContext {0|1}]"
+ "\n\t\t: [-vsync {0|1}]"
+ "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
"\n\t\t: [-softMode {0|1}] [-noupdate|-update]"
"\n\t\t: Modify particular graphic driver options:"
"\n\t\t: FFP - use fixed-function pipeline instead of"
"\n\t\t: VBO - use Vertex Buffer Object (copy vertex"
"\n\t\t: arrays to GPU memory)"
"\n\t\t: sprite - use textured sprites instead of bitmaps"
+ "\n\t\t: vsync - switch VSync on or off"
"\n\t\t: Context creation options:"
"\n\t\t: softMode - software OpenGL implementation"
"\n\t\t: compatibleProfile - backward-compatible profile"
+ "\n\t\t: quadbuffer - QuadBuffer"
"\n\t\t: Unlike vrenderparams, these parameters control alternative"
"\n\t\t: rendering paths producing the same visual result when"
"\n\t\t: possible."
MyCView.DefWindow.XWindow = theWindow->NativeHandle();
MyCView.DefWindow.XParentWindow = theWindow->NativeParentHandle();
- Standard_Integer Width, Height;
- theWindow->Size (Width, Height);
- MyCView.DefWindow.dx = Width;
- MyCView.DefWindow.dy = Height;
+ Standard_Integer aWidth = 0, aHeight = 0, aLeft = 0, aTop = 0;
+ theWindow->Position (aLeft, aTop, aWidth, aHeight);
+ theWindow->Size (aWidth, aHeight);
+ MyCView.DefWindow.left = aLeft;
+ MyCView.DefWindow.top = aTop;
+ MyCView.DefWindow.dx = aWidth;
+ MyCView.DefWindow.dy = aHeight;
Standard_Real R, G, B;
MyBackground = MyWindow->Background ();
const Aspect_TypeOfUpdate anUpdateMode = myViewManager->UpdateMode();
myViewManager->SetUpdateMode (Aspect_TOU_WAIT);
- Standard_Integer aWidth, aHeight;
+ Standard_Integer aWidth = 0, aHeight = 0, aLeft = 0, aTop = 0;
+ MyWindow->Position (aLeft, aTop, aWidth, aHeight);
+ MyCView.DefWindow.left = aLeft;
+ MyCView.DefWindow.top = aTop;
+
MyWindow->Size (aWidth, aHeight);
if (aWidth > 0 && aHeight > 0)
{
vsetdispmode 1
vdisplay b
vfit
-vdump ${imagedir}/texture_409.png rgb 409 409
-vdump ${imagedir}/texture_412.png rgb 412 412
+vdump ${imagedir}/texture_409.png -buffer rgb -width 409 -height 409
+vdump ${imagedir}/texture_412.png -buffer rgb -width 412 -height 412
# texture loaded correctly
vtexture b ${imagedir}/texture_412.png
vcamera -ortho
vfit
set aTitle "ortho"
-vdump $imagedir/${casename}_${aTitle}.png rgb 512 512
+vdump $imagedir/${casename}_${aTitle}.png -buffer rgb -width 512 -height 512
vcamera -persp
vfit
set aTitle "persp"
-vdump $imagedir/${casename}_${aTitle}.png rgb 512 512
+vdump $imagedir/${casename}_${aTitle}.png -buffer rgb -width 512 -height 512
vcamera -stereo
set aTitle "stereoR"
-vdump $imagedir/${casename}_${aTitle}.png rgb 512 512 R
+vdump $imagedir/${casename}_${aTitle}.png -buffer rgb -width 512 -height 512 -stereo R
set aTitle "stereoL"
-vdump $imagedir/${casename}_${aTitle}.png rgb 512 512 L
+vdump $imagedir/${casename}_${aTitle}.png -buffer rgb -width 512 -height 512 -stereo L
# test context stereo mode swicthing
# if not supported by hardware it must not crash
vcamera -stereo
vfit
set aTitle "afterSwitch"
-vdump $imagedir/${casename}_${aTitle}.png rgb 512 512 R
+vdump $imagedir/${casename}_${aTitle}.png -buffer rgb -width 512 -height 512 -stereo R
--- /dev/null
+puts "========"
+puts "Stereo output modes"
+puts "========"
+
+restore [locate_data_file occ/fuse.brep] f
+vinit View1
+vclear
+vsetdispmode 1
+vaxo
+vdisplay f
+vfit
+vrotate -0.5 0.0 0.0
+
+vstereo -mode anaglyph
+vfit
+vdump $::imagedir/${::casename}_anaglyph.png -stereo blend
+
+vstereo -mode columnInterlaced
+vdump $::imagedir/${::casename}_col.png -stereo blend
+
+vstereo -mode chessBoard
+vdump $::imagedir/${::casename}_chess.png -stereo blend
+
+vstereo -mode rowInterlaced
+vdump $::imagedir/${::casename}_row.png -stereo blend
+
+vstereo -mode sideBySide
+vdump $::imagedir/${::casename}_sbs_anamorph.png -stereo blend
+
+vstereo -mode overUnder
+vdump $::imagedir/${::casename}_overunder_anamorph.png -stereo blend
+
+vdump $::imagedir/${::casename}_sbs.png -stereo sbs