OpenGl_Texture::Init2DMultisample() - new method to initialize multisampled texture.
Graphic3d_RenderingParams::NbMsaaSamples - add option defining MSAA samples number.
RayTracing will keep using FBO without MSAA, however it is possible to combine
MSAA for rasterization and FSAA for RayTracing.
OpenGl_FrameBuffer constructor has been changed to do not take arguments.
OpenGl_FrameBuffer::Init() method has been extended with mandatory parameters
defining Color and Depth attachment formats
and optional parameter defining number of MSAA parameters.
Draw Harness, add option -msaa to vrenderparams.
//! Creates default rendering parameters.
Graphic3d_RenderingParams()
: Method (Graphic3d_RM_RASTERIZATION),
+ NbMsaaSamples (0),
+ // ray tracing parameters
IsGlobalIlluminationEnabled (Standard_False),
SamplesPerPixel (THE_DEFAULT_SPP),
RaytracingDepth (THE_DEFAULT_DEPTH),
IsTransparentShadowEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False),
CoherentPathTracingMode (Standard_False),
-
+ // stereoscopic parameters
StereoMode (Graphic3d_StereoMode_QuadBuffer),
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
ToReverseStereo (Standard_False),
public:
Graphic3d_RenderingMode Method; //!< specifies rendering mode, Graphic3d_RM_RASTERIZATION by default
+ Standard_Integer NbMsaaSamples; //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default
Standard_Boolean IsGlobalIlluminationEnabled; //!< enables/disables global illumination effects (path tracing)
Standard_Integer SamplesPerPixel; //!< number of samples per pixel (SPP)
myTexClamp (GL_CLAMP_TO_EDGE),
myMaxTexDim (1024),
myMaxClipPlanes (6),
+ myMaxMsaaSamples(0),
myGlVerMajor (0),
myGlVerMinor (0),
myIsInitialized (Standard_False),
}
}
-// =======================================================================
-// function : MaxDegreeOfAnisotropy
-// purpose :
-// =======================================================================
-Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
-{
- return myAnisoMax;
-}
-
-// =======================================================================
-// function : MaxTextureSize
-// purpose :
-// =======================================================================
-Standard_Integer OpenGl_Context::MaxTextureSize() const
-{
- return myMaxTexDim;
-}
-
-// =======================================================================
-// function : MaxClipPlanes
-// purpose :
-// =======================================================================
-Standard_Integer OpenGl_Context::MaxClipPlanes() const
-{
- return myMaxClipPlanes;
-}
-
#if !defined(GL_ES_VERSION_2_0)
inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
{
// function : ResetErrors
// purpose :
// =======================================================================
-void OpenGl_Context::ResetErrors()
+void OpenGl_Context::ResetErrors (const bool theToPrintErrors)
{
- while (glGetError() != GL_NO_ERROR)
+ int aPrevErr = 0;
+ int anErr = ::glGetError();
+ if (!theToPrintErrors)
{
- //
+ for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
+ {
+ //
+ }
+ return;
+ }
+
+ for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
+ {
+ TCollection_ExtendedString anErrId;
+ switch (anErr)
+ {
+ case GL_INVALID_ENUM: anErrId = "GL_INVALID_ENUM"; break;
+ case GL_INVALID_VALUE: anErrId = "GL_INVALID_VALUE"; break;
+ case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
+ #ifdef GL_STACK_OVERFLOW
+ case GL_STACK_OVERFLOW: anErrId = "GL_STACK_OVERFLOW"; break;
+ case GL_STACK_UNDERFLOW: anErrId = "GL_STACK_UNDERFLOW"; break;
+ #endif
+ case GL_OUT_OF_MEMORY: anErrId = "GL_OUT_OF_MEMORY"; break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
+ break;
+ default:
+ anErrId = TCollection_ExtendedString("#") + anErr;
+ break;
+ }
+
+ const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
+ PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
}
}
// read version
myGlVerMajor = 0;
myGlVerMinor = 0;
+ myMaxMsaaSamples = 0;
ReadGlVersion (myGlVerMajor, myGlVerMinor);
myVendor = (const char* )::glGetString (GL_VENDOR);
{
arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
}
+ if (IsGlGreaterEqual (3, 1)
+ && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
+ {
+ // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
+ // but MSAA Textures - only in OpenGL ES 3.1+
+ ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
+ }
hasUintIndex = IsGlGreaterEqual (3, 0)
|| CheckExtension ("GL_OES_element_index_uint");
return;
}
+ // MSAA RenderBuffers have been defined in OpenGL 3.0,
+ // but MSAA Textures - only in OpenGL 3.2+
+ if (!has32
+ && CheckExtension ("GL_ARB_texture_multisample")
+ && FindProcShort (glTexImage2DMultisample))
+ {
+ GLint aNbColorSamples = 0, aNbDepthSamples = 0;
+ ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
+ ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
+ myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
+ }
+ if (!has43
+ && CheckExtension ("GL_ARB_texture_storage_multisample")
+ && FindProcShort (glTexStorage2DMultisample))
+ {
+ //
+ }
+
if (!has31)
{
checkWrongVersion (3, 1);
{
core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
}
+ ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
if (!has33)
{
const OpenGl_GlFunctions* Functions() const { return myFuncs.operator->(); }
//! Clean up errors stack for this GL context (glGetError() in loop).
- Standard_EXPORT void ResetErrors();
+ Standard_EXPORT void ResetErrors (const bool theToPrintErrors = false);
//! This method uses system-dependent API to retrieve information
//! about GL context bound to the current thread.
Standard_Integer TextureWrapClamp() const { return myTexClamp; }
//! @return maximum degree of anisotropy texture filter
- Standard_EXPORT Standard_Integer MaxDegreeOfAnisotropy() const;
+ Standard_Integer MaxDegreeOfAnisotropy() const { return myAnisoMax; }
//! @return value for GL_MAX_TEXTURE_SIZE
- Standard_EXPORT Standard_Integer MaxTextureSize() const;
+ Standard_Integer MaxTextureSize() const { return myMaxTexDim; }
+
+ //! @return value for GL_MAX_SAMPLES
+ Standard_Integer MaxMsaaSamples() const { return myMaxMsaaSamples; }
//! Get maximum number of clip planes supported by OpenGl.
//! This value is implementation dependent. At least 6
//! planes should be supported by OpenGl (see specs).
//! @return value for GL_MAX_CLIP_PLANES
- Standard_EXPORT Standard_Integer MaxClipPlanes() const;
+ Standard_Integer MaxClipPlanes() const { return myMaxClipPlanes; }
//! Returns true if VBO is supported and permitted.
inline bool ToUseVbo() const
Standard_Integer myTexClamp; //!< either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1)
Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE
Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
+ Standard_Integer myMaxMsaaSamples; //!< value for GL_MAX_SAMPLES
Standard_Integer myGlVerMajor; //!< cached GL version major number
Standard_Integer myGlVerMinor; //!< cached GL version minor number
Standard_Boolean myIsInitialized; //!< flag indicates initialization state
#include <Standard_Assert.hxx>
#include <TCollection_ExtendedString.hxx>
+namespace
+{
+
+ //! Determine data type from texture sized format.
+ static bool getDepthDataFormat (GLint theTextFormat,
+ GLenum& thePixelFormat,
+ GLenum& theDataType)
+ {
+ switch (theTextFormat)
+ {
+ case GL_DEPTH24_STENCIL8:
+ {
+ thePixelFormat = GL_DEPTH_STENCIL;
+ theDataType = GL_UNSIGNED_INT_24_8;
+ return true;
+ }
+ case GL_DEPTH32F_STENCIL8:
+ {
+ thePixelFormat = GL_DEPTH_STENCIL;
+ theDataType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+ return true;
+ }
+ case GL_DEPTH_COMPONENT16:
+ {
+ thePixelFormat = GL_DEPTH;
+ theDataType = GL_UNSIGNED_SHORT;
+ return true;
+ }
+ case GL_DEPTH_COMPONENT24:
+ {
+ thePixelFormat = GL_DEPTH;
+ theDataType = GL_UNSIGNED_INT;
+ return true;
+ }
+ case GL_DEPTH_COMPONENT32F:
+ {
+ thePixelFormat = GL_DEPTH;
+ theDataType = GL_FLOAT;
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
// =======================================================================
// function : OpenGl_FrameBuffer
// purpose :
// =======================================================================
-OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
+OpenGl_FrameBuffer::OpenGl_FrameBuffer()
: myVPSizeX (0),
myVPSizeY (0),
- myTextFormat (theTextureFormat),
+ myNbSamples (0),
+ myColorFormat (GL_RGBA8),
+ myDepthFormat (GL_DEPTH24_STENCIL8),
myGlFBufferId (NO_FRAMEBUFFER),
myGlColorRBufferId (NO_RENDERBUFFER),
myGlDepthRBufferId (NO_RENDERBUFFER),
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
const GLsizei theSizeX,
- const GLsizei theSizeY)
+ const GLsizei theSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
+ const GLsizei theNbSamples)
{
+ myColorFormat = theColorFormat;
+ myDepthFormat = theDepthFormat;
+ myNbSamples = theNbSamples;
if (theGlContext->arbFBO == NULL)
{
return Standard_False;
// clean up previous state
Release (theGlContext.operator->());
+ if (myColorFormat == 0
+ && myDepthFormat == 0)
+ {
+ return Standard_False;
+ }
myIsOwnBuffer = true;
const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2;
// Create the textures (will be used as color buffer and depth-stencil buffer)
- if (!myColorTexture->Init (theGlContext, myTextFormat,
- GL_RGBA, GL_UNSIGNED_BYTE,
- aSizeX, aSizeY, Graphic3d_TOT_2D))
+ if (theNbSamples != 0)
{
- Release (theGlContext.operator->());
- return Standard_False;
+ if (myColorFormat != 0
+ && !myColorTexture ->Init2DMultisample (theGlContext, theNbSamples, myColorFormat, aSizeX, aSizeY))
+ {
+ Release (theGlContext.operator->());
+ return Standard_False;
+ }
+ if (myDepthFormat != 0
+ && !myDepthStencilTexture->Init2DMultisample (theGlContext, theNbSamples, myDepthFormat, aSizeX, aSizeY))
+ {
+ Release (theGlContext.operator->());
+ return Standard_False;
+ }
}
-
- // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
- // instead of just trying to create such texture
- if (!myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
- GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
- aSizeX, aSizeY, Graphic3d_TOT_2D))
+ else
{
- TCollection_ExtendedString aMsg = TCollection_ExtendedString()
- + "Warning! Depth textures are not supported by hardware!";
- theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB,
- 0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
- aMsg);
-
- theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
- theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
- theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, aSizeX, aSizeY);
- theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
+ if (myColorFormat != 0
+ && !myColorTexture->Init (theGlContext, myColorFormat,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ aSizeX, aSizeY, Graphic3d_TOT_2D))
+ {
+ Release (theGlContext.operator->());
+ return Standard_False;
+ }
+
+ // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
+ // instead of just trying to create such texture
+ GLenum aPixelFormat = 0;
+ GLenum aDataType = 0;
+ if (myDepthFormat != 0
+ && getDepthDataFormat (myDepthFormat, aPixelFormat, aDataType)
+ && !myDepthStencilTexture->Init (theGlContext, myDepthFormat,
+ aPixelFormat, aDataType,
+ aSizeX, aSizeY, Graphic3d_TOT_2D))
+ {
+ TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+ + "Warning! Depth textures are not supported by hardware!";
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_PORTABILITY_ARB,
+ 0,
+ GL_DEBUG_SEVERITY_HIGH_ARB,
+ aMsg);
+
+ theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
+ theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
+ theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, aSizeX, aSizeY);
+ theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
+ }
}
// Build FBO and setup it as texture
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
- theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
+ if (myColorTexture->IsValid())
+ {
+ theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ myColorTexture->GetTarget(), myColorTexture->TextureId(), 0);
+ }
if (myDepthStencilTexture->IsValid())
{
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+ myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
#else
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+ myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
+ myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
#endif
}
else if (myGlDepthRBufferId != NO_RENDERBUFFER)
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& theGlContext,
const GLsizei theViewportSizeX,
- const GLsizei theViewportSizeY)
+ const GLsizei theViewportSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
+ const GLsizei theNbSamples)
{
- if (myVPSizeX == theViewportSizeX
- && myVPSizeY == theViewportSizeY)
-
+ if (myVPSizeX == theViewportSizeX
+ && myVPSizeY == theViewportSizeY
+ && myColorFormat == theColorFormat
+ && myDepthFormat == theDepthFormat
+ && myNbSamples == theNbSamples)
{
return IsValid();
}
- return Init (theGlContext, theViewportSizeX, theViewportSizeY);
+ return Init (theGlContext, theViewportSizeX, theViewportSizeY, theColorFormat, theDepthFormat, theNbSamples);
}
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theSizeX,
const GLsizei theSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
const GLuint theColorRBufferFromWindow)
{
+ myColorFormat = theColorFormat;
+ myDepthFormat = theDepthFormat;
+ myNbSamples = 0;
if (theGlCtx->arbFBO == NULL)
{
return Standard_False;
{
myGlColorRBufferId = theColorRBufferFromWindow;
}
- else
+ else if (myColorFormat != 0)
{
theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId);
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId);
- theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, aSizeX, aSizeY);
+ theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, myColorFormat, aSizeX, aSizeY);
}
- theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
- theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
- theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, aSizeX, aSizeY);
-
- theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
+ if (myDepthFormat != 0)
+ {
+ theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
+ theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
+ theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, myDepthFormat, aSizeX, aSizeY);
+ theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
+ }
// create FBO
theGlCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, myGlColorRBufferId);
-#ifdef GL_DEPTH_STENCIL_ATTACHMENT
- theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, myGlDepthRBufferId);
-#else
- theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, myGlDepthRBufferId);
- theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, myGlDepthRBufferId);
-#endif
+ if (myGlDepthRBufferId != NO_RENDERBUFFER)
+ {
+ #ifdef GL_DEPTH_STENCIL_ATTACHMENT
+ theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, myGlDepthRBufferId);
+ #else
+ theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, myGlDepthRBufferId);
+ theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, myGlDepthRBufferId);
+ #endif
+ }
if (theGlCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
UnbindBuffer (theGlCtx);
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlCtx)
{
+ myNbSamples = 0;
if (theGlCtx->arbFBO == NULL)
{
return Standard_False;
public:
//! Empty constructor
- Standard_EXPORT OpenGl_FrameBuffer (GLint theTextureFormat = GL_RGBA8);
+ Standard_EXPORT OpenGl_FrameBuffer();
//! Destructor
Standard_EXPORT virtual ~OpenGl_FrameBuffer();
//! Destroy object - will release GPU memory if any.
Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx);
+ //! Number of multisampling samples.
+ GLsizei NbSamples() const
+ {
+ return myNbSamples;
+ }
+
+ //! Return true if FBO has been created with color attachment.
+ bool HasColor() const
+ {
+ return myColorFormat != 0;
+ }
+
+ //! Return true if FBO has been created with depth attachment.
+ bool HasDepth() const
+ {
+ return myDepthFormat != 0;
+ }
+
//! Textures width.
GLsizei GetSizeX() const
{
return isValidFrameBuffer();
}
- //! Notice! Obsolete hardware (GeForce FX etc)
- //! doesn't support rectangular textures!
- //! There are 3 possible results if you are trying
- //! to create non power-of-two FBO on these cards:
- //! 1) FBO creation will fail,
- //! current implementation will try to generate compatible FBO;
- //! 2) FBO rendering will be done in software mode (ForceWare 'hack');
- //! 3) FBO rendering will be incorrect (some obsolete Catalyst drivers).
+ //! Initialize FBO for rendering into textures.
+ //! @param theGlCtx currently bound OpenGL context
+ //! @param theSizeX texture width
+ //! @param theSizeY texture height
+ //! @param theColorFormat color texture sized format (0 means no color attachment), e.g. GL_RGBA8
+ //! @param theDepthFormat depth-stencil texture sized format (0 means no depth attachment), e.g. GL_DEPTH24_STENCIL8
+ //! @param theNbSamples MSAA number of samples (0 means normal texture)
+ //! @return true on success
Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
- const GLsizei theViewportSizeX,
- const GLsizei theViewportSizeY);
+ const GLsizei theSizeX,
+ const GLsizei theSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
+ const GLsizei theNbSamples = 0);
//! (Re-)initialize FBO with specified dimensions.
Standard_EXPORT Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theViewportSizeX,
- const GLsizei theViewportSizeY);
+ const GLsizei theViewportSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
+ const GLsizei theNbSamples = 0);
+
+ //! (Re-)initialize FBO with properties taken from another FBO.
+ Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx,
+ const OpenGl_FrameBuffer& theFbo)
+ {
+ return InitLazy (theGlCtx, theFbo.myVPSizeX, theFbo.myVPSizeY, theFbo.myColorFormat, theFbo.myDepthFormat, theFbo.myNbSamples);
+ }
//! (Re-)initialize FBO with specified dimensions.
//! The Render Buffer Objects will be used for Color, Depth and Stencil attachments (as opposite to textures).
- //! @param theGlCtx currently bound OpenGL context
- //! @param theViewportSizeX required viewport size, the actual dimensions of FBO might be greater
- //! @param theViewportSizeY required viewport size, the actual dimensions of FBO might be greater
+ //! @param theGlCtx currently bound OpenGL context
+ //! @param theSizeX render buffer width
+ //! @param theSizeY render buffer height
+ //! @param theColorFormat color render buffer sized format, e.g. GL_RGBA8
+ //! @param theDepthFormat depth-stencil render buffer sized format, e.g. GL_DEPTH24_STENCIL8
//! @param theColorRBufferFromWindow when specified - should be ID of already initialized RB object, which will be released within this class
Standard_EXPORT Standard_Boolean InitWithRB (const Handle(OpenGl_Context)& theGlCtx,
- const GLsizei theViewportSizeX,
- const GLsizei theViewportSizeY,
+ const GLsizei theSizeX,
+ const GLsizei theSizeY,
+ const GLint theColorFormat,
+ const GLint theDepthFormat,
const GLuint theColorRBufferFromWindow = 0);
//! Initialize class from currently bound FBO.
GLsizei myVPSizeX; //!< viewport width (should be <= texture width)
GLsizei myVPSizeY; //!< viewport height (should be <= texture height)
- GLint myTextFormat; //!< GL_RGB, GL_RGBA,...
+ GLsizei myNbSamples; //!< number of MSAA samples
+ GLint myColorFormat; //!< sized format for color texture, GL_RGBA8 by default
+ GLint myDepthFormat; //!< sized format for depth-stencil texture, GL_DEPTH24_STENCIL8 by default
GLuint myGlFBufferId; //!< FBO object ID
GLuint myGlColorRBufferId; //!< color Render Buffer object (alternative to myColorTexture)
GLuint myGlDepthRBufferId; //!< depth-stencil Render Buffer object (alternative to myDepthStencilTexture)
// OpenGL ES 3.0+ or GL_OES_element_index_uint extension
#define GL_UNSIGNED_INT 0x1405
+ // OpenGL ES 3.1+
+ #define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+ #define GL_MAX_SAMPLES 0x8D57
+
// in core since OpenGL ES 3.0, extension GL_EXT_texture_rg
#define GL_RED 0x1903
#define GL_R8 0x8229
#define GL_UNSIGNED_INT_24_8 0x84FA
#define GL_DEPTH24_STENCIL8 0x88F0
+ // OpenGL ES 3.0+
+ #define GL_DEPTH_COMPONENT32F 0x8CAC
+ #define GL_DEPTH32F_STENCIL8 0x8CAD
+ #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
typedef void (*glBlitFramebuffer_t)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
glBlitFramebuffer_t glBlitFramebuffer;
+public: //! @name OpenGL ES 3.1
+
+ typedef void (*glTexStorage2DMultisample_t)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+ glTexStorage2DMultisample_t glTexStorage2DMultisample;
+
#else // OpenGL ES vs. desktop
public: //! @name OpenGL 1.2
#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_Context.hxx>
-#include <OpenGl_GlCore15.hxx>
+#include <OpenGl_GlCore32.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Standard_Assert.hxx>
theType, &theImage);
}
+// =======================================================================
+// function : Init2DMultisample
+// purpose :
+// =======================================================================
+bool OpenGl_Texture::Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
+ const GLsizei theNbSamples,
+ const GLint theTextFormat,
+ const GLsizei theSizeX,
+ const GLsizei theSizeY)
+{
+ if (!Create (theCtx)
+ || theNbSamples > theCtx->MaxMsaaSamples()
+ || theNbSamples < 1)
+ {
+ return false;
+ }
+
+ const GLsizei aNbSamples = OpenGl_Context::GetPowerOfTwo (theNbSamples, theCtx->MaxMsaaSamples());
+ myTarget = GL_TEXTURE_2D_MULTISAMPLE;
+ if(theSizeX > theCtx->MaxTextureSize()
+ || theSizeY > theCtx->MaxTextureSize())
+ {
+ return false;
+ }
+
+ Bind (theCtx);
+ //myTextFormat = theTextFormat;
+#if !defined(GL_ES_VERSION_2_0)
+ if (theCtx->Functions()->glTexStorage2DMultisample != NULL)
+ {
+ theCtx->Functions()->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+ }
+ else
+ {
+ theCtx->Functions()->glTexImage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+ }
+#else
+ theCtx->Functions() ->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+#endif
+ if (theCtx->core11fwd->glGetError() != GL_NO_ERROR)
+ {
+ Unbind (theCtx);
+ return false;
+ }
+
+ mySizeX = theSizeX;
+ mySizeY = theSizeY;
+
+ Unbind (theCtx);
+ return true;
+}
+
// =======================================================================
// function : InitRectangle
// purpose :
const Graphic3d_TypeOfTexture theType,
const Image_PixMap* theImage = NULL);
+ //! Initialize the 2D multisampling texture using glTexImage2DMultisample().
+ Standard_EXPORT bool Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
+ const GLsizei theNbSamples,
+ const GLint theTextFormat,
+ const GLsizei theSizeX,
+ const GLsizei theSizeY);
+
//! Allocates texture rectangle with specified format and size.
//! \note Texture data is not initialized (will contain trash).
Standard_EXPORT bool InitRectangle (const Handle(OpenGl_Context)& theCtx,
myToShowGradTrihedron (false),
myStateCounter (theCounter),
myLastLightSourceState (0, 0),
+ myFboColorFormat (GL_RGBA8),
+ myFboDepthFormat (GL_DEPTH24_STENCIL8),
+ myToFlipOutput (Standard_False),
myFrameCounter (0),
myHasFboBlit (Standard_True),
myTransientDrawToFront (Standard_True),
myMainSceneFbos[1] = new OpenGl_FrameBuffer();
myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
+ myOpenGlFBO = new OpenGl_FrameBuffer();
+ myOpenGlFBO2 = new OpenGl_FrameBuffer();
+ myRaytraceFBO1[0] = new OpenGl_FrameBuffer();
+ myRaytraceFBO1[1] = new OpenGl_FrameBuffer();
+ myRaytraceFBO2[0] = new OpenGl_FrameBuffer();
+ myRaytraceFBO2[1] = new OpenGl_FrameBuffer();
}
// =======================================================================
myMainSceneFbos[1] ->Release (theCtx.operator->());
myImmediateSceneFbos[0]->Release (theCtx.operator->());
myImmediateSceneFbos[1]->Release (theCtx.operator->());
+ myOpenGlFBO ->Release (theCtx.operator->());
+ myOpenGlFBO2 ->Release (theCtx.operator->());
myFullScreenQuad .Release (theCtx.operator->());
myFullScreenQuadFlip .Release (theCtx.operator->());
OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip);
//! Blend together views pair into stereo image.
- void drawStereoPair();
+ void drawStereoPair (OpenGl_FrameBuffer* theDrawFbo);
protected:
//! Two framebuffers (left and right views) store cached main presentation
//! of the view (without presentation of immediate layers).
+ GLint myFboColorFormat; //!< sized format for color attachments
+ GLint myFboDepthFormat; //!< sized format for depth-stencil attachments
Handle(OpenGl_FrameBuffer) myMainSceneFbos[2];
Handle(OpenGl_FrameBuffer) myImmediateSceneFbos[2]; //!< Additional buffers for immediate layer in stereo mode.
OpenGl_VertexBuffer myFullScreenQuad; //!< Vertices for full-screen quad rendering.
Handle(OpenGl_FrameBuffer) myRaytraceFBO2[2];
//! Framebuffer (FBO) for preliminary OpenGL output.
Handle(OpenGl_FrameBuffer) myOpenGlFBO;
+ Handle(OpenGl_FrameBuffer) myOpenGlFBO2;
//! Vertex buffer (VBO) for drawing dummy quad.
OpenGl_VertexBuffer myRaytraceScreenQuad;
initBufferTiling (aFrameWidth, aFrameHeight, width, height);
// try to initialize framebuffer
- if (aFrameBuffer->Init (aCtx, aFrameWidth, aFrameHeight))
+ if (aFrameBuffer->Init (aCtx, aFrameWidth, aFrameHeight, GL_RGBA8, GL_DEPTH24_STENCIL8))
{
#ifdef HAVE_FREEIMAGE
// try to allocate fipImage and necessary resources
return myRaytraceInitStatus == OpenGl_RT_INIT;
}
- if (myRaytraceFBO1[0].IsNull())
- {
- myRaytraceFBO1[0] = new OpenGl_FrameBuffer (GL_RGBA32F);
- myRaytraceFBO1[1] = new OpenGl_FrameBuffer (GL_RGBA32F);
- }
-
- if (myRaytraceFBO2[0].IsNull())
- {
- myRaytraceFBO2[0] = new OpenGl_FrameBuffer (GL_RGBA32F);
- myRaytraceFBO2[1] = new OpenGl_FrameBuffer (GL_RGBA32F);
- }
-
const GLfloat aVertices[] = { -1.f, -1.f, 0.f,
-1.f, 1.f, 0.f,
1.f, 1.f, 0.f,
// =======================================================================
void OpenGl_View::releaseRaytraceResources (const Handle(OpenGl_Context)& theGlContext)
{
- nullifyResource (theGlContext, myOpenGlFBO);
- nullifyResource (theGlContext, myRaytraceFBO1[0]);
- nullifyResource (theGlContext, myRaytraceFBO2[0]);
- nullifyResource (theGlContext, myRaytraceFBO1[1]);
- nullifyResource (theGlContext, myRaytraceFBO2[1]);
+ myRaytraceFBO1[0]->Release (theGlContext.operator->());
+ myRaytraceFBO1[1]->Release (theGlContext.operator->());
+ myRaytraceFBO2[0]->Release (theGlContext.operator->());
+ myRaytraceFBO2[1]->Release (theGlContext.operator->());
nullifyResource (theGlContext, myRaytraceShader);
nullifyResource (theGlContext, myPostFSAAShader);
return Standard_True;
}
- if ( myRaytraceFBO1[0]->GetVPSizeX() != theSizeX
- || myRaytraceFBO1[0]->GetVPSizeY() != theSizeY)
- {
- myRaytraceFBO1[0]->Init (theGlContext, theSizeX, theSizeY);
- myRaytraceFBO2[0]->Init (theGlContext, theSizeX, theSizeY);
- }
+ myRaytraceFBO1[0]->InitLazy (theGlContext, theSizeX, theSizeY, GL_RGBA32F, myFboDepthFormat);
+ myRaytraceFBO2[0]->InitLazy (theGlContext, theSizeX, theSizeY, GL_RGBA32F, myFboDepthFormat);
// Init second set of buffers for stereographic rendering.
if (myCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
{
- if (myRaytraceFBO1[1]->GetVPSizeX() != theSizeX
- || myRaytraceFBO1[1]->GetVPSizeY() != theSizeY)
- {
- myRaytraceFBO1[1]->Init (theGlContext, theSizeX, theSizeY);
- myRaytraceFBO2[1]->Init (theGlContext, theSizeX, theSizeY);
- }
+ myRaytraceFBO1[1]->InitLazy (theGlContext, theSizeX, theSizeY, GL_RGBA32F, myFboDepthFormat);
+ myRaytraceFBO2[1]->InitLazy (theGlContext, theSizeX, theSizeY, GL_RGBA32F, myFboDepthFormat);
}
else
{
Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWindow->Width();
Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myWindow->Height();
+ // determine multisampling parameters
+ Standard_Integer aNbSamples = Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0);
+ if (aNbSamples != 0)
+ {
+ aNbSamples = OpenGl_Context::GetPowerOfTwo (aNbSamples, aCtx->MaxMsaaSamples());
+ }
+
if ( aFrameBuffer == NULL
&& !aCtx->DefaultFrameBuffer().IsNull()
&& aCtx->DefaultFrameBuffer()->IsValid())
}
if (myHasFboBlit
- && (myTransientDrawToFront || aProjectType == Graphic3d_Camera::Projection_Stereo))
+ && (myTransientDrawToFront
+ || aProjectType == Graphic3d_Camera::Projection_Stereo
+ || aNbSamples != 0))
{
if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
- || myMainSceneFbos[0]->GetVPSizeY() != aSizeY)
+ || myMainSceneFbos[0]->GetVPSizeY() != aSizeY
+ || myMainSceneFbos[0]->NbSamples() != aNbSamples)
{
// prepare FBOs containing main scene
// for further blitting and rendering immediate presentations on top
if (aCtx->core20fwd != NULL)
{
- myMainSceneFbos[0]->Init (aCtx, aSizeX, aSizeY);
+ myMainSceneFbos[0]->Init (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples);
}
if (!aCtx->caps->useSystemBuffer && myMainSceneFbos[0]->IsValid())
{
- myImmediateSceneFbos[0]->InitLazy (aCtx, aSizeX, aSizeY);
+ myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
}
}
}
if (aProjectType == Graphic3d_Camera::Projection_Stereo
&& myMainSceneFbos[0]->IsValid())
{
- myMainSceneFbos[1]->InitLazy (aCtx, aSizeX, aSizeY);
+ myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
if (!myMainSceneFbos[1]->IsValid())
{
// no enough memory?
}
else if (!aCtx->HasStereoBuffers() || aStereoMode != Graphic3d_StereoMode_QuadBuffer)
{
- myImmediateSceneFbos[0]->InitLazy (aCtx, aSizeX, aSizeY);
- myImmediateSceneFbos[1]->InitLazy (aCtx, aSizeX, aSizeY);
+ myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
+ myImmediateSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
if (!myImmediateSceneFbos[0]->IsValid()
|| !myImmediateSceneFbos[1]->IsValid())
{
if (anImmFbos[0] != NULL)
{
- bindDefaultFbo (aFrameBuffer);
- drawStereoPair();
+ drawStereoPair (aFrameBuffer);
}
}
else
Standard_True) || toSwap;
if (anImmFbos[0] != NULL)
{
- bindDefaultFbo (aFrameBuffer);
- drawStereoPair();
+ drawStereoPair (aFrameBuffer);
}
}
else
{
const Standard_Integer aSizeX = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeX() : myWindow->Width();
const Standard_Integer aSizeY = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeY() : myWindow->Height();
-
- if (myOpenGlFBO.IsNull())
- myOpenGlFBO = new OpenGl_FrameBuffer;
-
- if (myOpenGlFBO->GetVPSizeX() != aSizeX
- || myOpenGlFBO->GetVPSizeY() != aSizeY)
- {
- myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
- }
+ myOpenGlFBO ->InitLazy (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, 0);
if (myRaytraceFilter.IsNull())
myRaytraceFilter = new OpenGl_RaytraceFilter;
#endif
aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-/*#if !defined(GL_ES_VERSION_2_0)
- if (aCtx->arbFBOBlit != NULL)
+#if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->arbFBOBlit != NULL
+ && theReadFbo->NbSamples() != 0)
{
+ GLbitfield aCopyMask = 0;
theReadFbo->BindReadBuffer (aCtx);
if (theDrawFbo != NULL
&& theDrawFbo->IsValid())
{
theDrawFbo->BindDrawBuffer (aCtx);
+ if (theDrawFbo->HasColor()
+ && theReadFbo->HasColor())
+ {
+ aCopyMask |= GL_COLOR_BUFFER_BIT;
+ }
+ if (theDrawFbo->HasDepth()
+ && theReadFbo->HasDepth())
+ {
+ aCopyMask |= GL_DEPTH_BUFFER_BIT;
+ }
}
else
{
+ if (theReadFbo->HasColor())
+ {
+ aCopyMask |= GL_COLOR_BUFFER_BIT;
+ }
+ if (theReadFbo->HasDepth())
+ {
+ aCopyMask |= GL_DEPTH_BUFFER_BIT;
+ }
aCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
}
+
// we don't copy stencil buffer here... does it matter for performance?
aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
- GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
-
+ aCopyMask, GL_NEAREST);
if (theDrawFbo != NULL
- && theDrawFbo->IsValid())
+ && theDrawFbo->IsValid())
{
theDrawFbo->BindBuffer (aCtx);
}
}
}
else
-#endif*/
+#endif
{
aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
aCtx->core20fwd->glDepthMask (GL_TRUE);
// function : drawStereoPair
// purpose :
// =======================================================================
-void OpenGl_View::drawStereoPair()
+void OpenGl_View::drawStereoPair (OpenGl_FrameBuffer* theDrawFbo)
{
+ const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+ bindDefaultFbo (theDrawFbo);
OpenGl_FrameBuffer* aPair[2] =
{
myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
return;
}
+ if (aPair[0]->NbSamples() != 0)
+ {
+ // resolve MSAA buffers before drawing
+ if (!myOpenGlFBO ->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, myFboDepthFormat, 0)
+ || !myOpenGlFBO2->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, 0, 0))
+ {
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+ GL_DEBUG_TYPE_ERROR_ARB,
+ 0,
+ GL_DEBUG_SEVERITY_HIGH_ARB,
+ "Error! Unable to allocate FBO for blitting stereo pair");
+ bindDefaultFbo (theDrawFbo);
+ return;
+ }
+
+ if (!blitBuffers (aPair[0], myOpenGlFBO .operator->(), Standard_False)
+ || !blitBuffers (aPair[1], myOpenGlFBO2.operator->(), Standard_False))
+ {
+ bindDefaultFbo (theDrawFbo);
+ return;
+ }
+
+ aPair[0] = myOpenGlFBO .operator->();
+ aPair[1] = myOpenGlFBO2.operator->();
+ bindDefaultFbo (theDrawFbo);
+ }
+
struct
{
Standard_Integer left;
std::swap (aPair[0], aPair[1]);
}
- Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
aCtx->core20fwd->glDepthMask (GL_TRUE);
aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myHeight);
::glBindRenderbuffer (GL_RENDERBUFFER, 0);
- if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, aWinRBColor))
+ if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, aWinRBColor))
{
TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
// create the FBO
const Handle(OpenGl_Context)& aCtx = GetGlContext();
OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
- if (!aFrameBuffer->Init (aCtx, theWidth, theHeight))
+ if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
{
aFrameBuffer->Release (aCtx.operator->());
delete aFrameBuffer;
case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
}
theDI << "\n";
+ theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
+ theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
- theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
aParams.Method = Graphic3d_RM_RASTERIZATION;
}
+ else if (aFlag == "-msaa")
+ {
+ if (toPrint)
+ {
+ theDI << aParams.NbMsaaSamples << " ";
+ continue;
+ }
+ else if (++anArgIter >= theArgNb)
+ {
+ std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+ return 1;
+ }
+
+ const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
+ if (aNbSamples < 0)
+ {
+ std::cerr << "Error: invalid number of MSAA samples " << aNbSamples << ".\n";
+ return 1;
+ }
+ else
+ {
+ aParams.NbMsaaSamples = aNbSamples;
+ }
+ }
else if (aFlag == "-raydepth"
|| aFlag == "-ray_depth")
{
__FILE__, VRenderParams, group);
theCommands.Add("vrenderparams",
"\n Manages rendering parameters: "
- "\n '-rayTrace' Enables GPU ray-tracing"
"\n '-raster' Disables GPU ray-tracing"
+ "\n '-msaa 0..4' Specifies number of samples for MSAA"
+ "\n '-rayTrace' Enables GPU ray-tracing"
"\n '-rayDepth 0..10' Defines maximum ray-tracing depth"
"\n '-shadows on|off' Enables/disables shadows rendering"
"\n '-reflections on|off' Enables/disables specular reflections"
--- /dev/null
+puts "========"
+puts "Multisampling FBOs"
+puts "========"
+
+pload MODELING VISUALIZATION
+box b 2 3 1
+vclear
+vclose ALL
+vinit View1 w=512 h=512
+vsetgradientbg 180 200 255 180 180 180 2
+vsetdispmode 0
+vdisplay b
+vfit
+vrotate 0.5 0 0
+vzbufftrihedron
+
+vrenderparams -msaa 0
+vdump $::imagedir/${::casename}_0.png
+vrenderparams -msaa 2
+vdump $::imagedir/${::casename}_2.png
+vrenderparams -msaa 4
+vdump $::imagedir/${::casename}_4.png
+vrenderparams -msaa 8
+vdump $::imagedir/${::casename}_8.png