diff --git a/src/OpenGl/OpenGl_Caps.cxx b/src/OpenGl/OpenGl_Caps.cxx index cc72994b89..140a767d00 100755 --- a/src/OpenGl/OpenGl_Caps.cxx +++ b/src/OpenGl/OpenGl_Caps.cxx @@ -34,6 +34,7 @@ OpenGl_Caps::OpenGl_Caps() useZeroToOneDepth (Standard_False), buffersNoSwap (Standard_False), buffersOpaqueAlpha(Standard_True), + buffersDeepColor (Standard_False), contextStereo (Standard_False), contextDebug (Standard_False), contextSyncDebug (Standard_False), @@ -73,6 +74,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy) useZeroToOneDepth = theCopy.useZeroToOneDepth; buffersNoSwap = theCopy.buffersNoSwap; buffersOpaqueAlpha= theCopy.buffersOpaqueAlpha; + buffersDeepColor = theCopy.buffersDeepColor; contextStereo = theCopy.contextStereo; contextDebug = theCopy.contextDebug; contextSyncDebug = theCopy.contextSyncDebug; diff --git a/src/OpenGl/OpenGl_Caps.hxx b/src/OpenGl/OpenGl_Caps.hxx index 67d0eba38f..5281e046da 100755 --- a/src/OpenGl/OpenGl_Caps.hxx +++ b/src/OpenGl/OpenGl_Caps.hxx @@ -60,6 +60,25 @@ public: //! @name context creation parameters */ Standard_Boolean buffersOpaqueAlpha; + /** + * Specify whether deep color format (10-bit per component / 30-bit RGB) should be used + * instead of standard color format (8-bit per component / 24-bit RGB) when available. + * Deep color provides higher accuracy within the same color range (sRGB) + * and doesn't enable wide color gamut / HDR support. + * Higher precision helps eliminating banding effect on smooth gradients. + * + * Effect of the flag will vary depending on platform: + * - used as a hint on systems with 24-bit RGB color defined as preferred pixels format + * but with 30-bit RGB color being activated systemwide (e.g. Windows); + * - ignored on systems with deep color defined as preferred pixel format (e.g. Linux / X11), + * deep 30-bit RGB color will be used regardless of the flag value; + * - ignored on configurations not supporting deep color (incompatible display / system / GPU / driver), + * standard 24-bit RGB color will be used instead. + * + * OFF by default. + */ + Standard_Boolean buffersDeepColor; + /** * Request stereoscopic context (with Quad Buffer). This flag requires support in OpenGL driver. * diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 4d2bac38b9..0f269886e9 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -243,7 +243,9 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) myColorMask (true), myAlphaToCoverage (false), myIsGlDebugCtx (false), + myIsWindowDeepColor (false), myIsSRgbWindow (false), + myIsSRgbActive (false), myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION), myResolutionRatio (1.0f), myLineWidthScale (1.0f), @@ -1529,6 +1531,11 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) } } + Graphic3d_Vec4i aWinBitsRGBA; + Graphic3d_Vec2i aWinBitsDepthStencil; + WindowBufferBits (aWinBitsRGBA, aWinBitsDepthStencil); + myIsWindowDeepColor = aWinBitsRGBA.r() >= 10; + // standard formats mySupportedFormats->Add (Image_Format_Gray); mySupportedFormats->Add (Image_Format_Alpha); @@ -1813,6 +1820,58 @@ void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) #endif } +// ======================================================================= +// function : WindowBufferBits +// purpose : +// ======================================================================= +void OpenGl_Context::WindowBufferBits (Graphic3d_Vec4i& theColorBits, + Graphic3d_Vec2i& theDepthStencilBits) const +{ + if (core11ffp != NULL + || myGapi == Aspect_GraphicsLibrary_OpenGLES) + { + // removed from core with no working alternative + core11fwd->glGetIntegerv (GL_RED_BITS, &theColorBits.r()); + core11fwd->glGetIntegerv (GL_GREEN_BITS, &theColorBits.g()); + core11fwd->glGetIntegerv (GL_BLUE_BITS, &theColorBits.b()); + core11fwd->glGetIntegerv (GL_ALPHA_BITS, &theColorBits.a()); + core11fwd->glGetIntegerv (GL_DEPTH_BITS, &theDepthStencilBits[0]); + core11fwd->glGetIntegerv (GL_STENCIL_BITS, &theDepthStencilBits[1]); + } + else + { + #if defined(HAVE_EGL) + // + #elif defined(_WIN32) + const int aPixFrmtIndex = GetPixelFormat ((HDC )myDisplay); + PIXELFORMATDESCRIPTOR aFormat; + memset (&aFormat, 0, sizeof(aFormat)); + aFormat.nSize = sizeof(aFormat); + DescribePixelFormat ((HDC )myDisplay, aPixFrmtIndex, sizeof(PIXELFORMATDESCRIPTOR), &aFormat); + theColorBits.SetValues (aFormat.cRedBits, aFormat.cGreenBits, aFormat.cBlueBits, aFormat.cAlphaBits); + theDepthStencilBits.SetValues (aFormat.cDepthBits, aFormat.cStencilBits); + #elif defined(HAVE_XLIB) + Display* aDisplay = (Display* )myDisplay; + XWindowAttributes aWinAttribs; + XGetWindowAttributes (aDisplay, (::Window )myWindow, &aWinAttribs); + XVisualInfo aVisInfo; + aVisInfo.visualid = aWinAttribs.visual->visualid; + aVisInfo.screen = DefaultScreen(aDisplay); + int aNbItems = 0; + std::unique_ptr aVis (XGetVisualInfo (aDisplay, VisualIDMask | VisualScreenMask, &aVisInfo, &aNbItems), &XFree); + if (aVis.get() != NULL) + { + glXGetConfig (aDisplay, aVis.get(), GLX_RED_SIZE, &theColorBits.r()); + glXGetConfig (aDisplay, aVis.get(), GLX_GREEN_SIZE, &theColorBits.g()); + glXGetConfig (aDisplay, aVis.get(), GLX_BLUE_SIZE, &theColorBits.b()); + glXGetConfig (aDisplay, aVis.get(), GLX_ALPHA_SIZE, &theColorBits.a()); + glXGetConfig (aDisplay, aVis.get(), GLX_DEPTH_SIZE, &theDepthStencilBits[0]); + glXGetConfig (aDisplay, aVis.get(), GLX_STENCIL_SIZE, &theDepthStencilBits[1]); + } + #endif + } +} + // ======================================================================= // function : DiagnosticInfo // purpose : @@ -1909,6 +1968,13 @@ void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString GLint aViewport[4] = {}; core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport); addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]); + + Graphic3d_Vec4i aWinBitsRGBA; + Graphic3d_Vec2i aWinBitsDepthStencil; + WindowBufferBits (aWinBitsRGBA, aWinBitsDepthStencil); + addInfo (theDict, "Window buffer", + TCollection_AsciiString() + "RGB" + aWinBitsRGBA.r() + " ALPHA" + aWinBitsRGBA.a() + + " DEPTH" + aWinBitsDepthStencil[0] + " STENCIL" + aWinBitsDepthStencil[1]); } if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0) diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index c7b4093305..b49f9cfcba 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -398,6 +398,10 @@ public: Standard_EXPORT void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict, Graphic3d_DiagnosticInfo theFlags) const; + //! Fetches information about window buffer pixel format. + Standard_EXPORT void WindowBufferBits (Graphic3d_Vec4i& theColorBits, + Graphic3d_Vec2i& theDepthStencilBits) const; + //! Access shared resource by its name. //! @param theKey - unique identifier; //! @return handle to shared resource or NULL. @@ -565,6 +569,9 @@ public: //! Overrides if window/surface buffer is sRGB-ready or not (initialized with the context). void SetWindowSRGB (bool theIsSRgb) { myIsSRgbWindow = theIsSRgb; } + //! Returns TRUE if window/surface buffer has deep color (10bit per component / 30bit RGB) or better precision. + bool IsWindowDeepColor() const { return myIsWindowDeepColor; } + //! Convert Quantity_ColorRGBA into vec4 //! with conversion or no conversion into non-linear sRGB //! basing on ToRenderSRGB() flag. @@ -1165,6 +1172,7 @@ private: //! @name fields tracking current state Standard_Boolean myAllowAlphaToCov; //!< flag allowing GL_SAMPLE_ALPHA_TO_COVERAGE usage Standard_Boolean myAlphaToCoverage; //!< flag indicating GL_SAMPLE_ALPHA_TO_COVERAGE state Standard_Boolean myIsGlDebugCtx; //!< debug context initialization state + Standard_Boolean myIsWindowDeepColor; //!< indicates that window buffer is has deep color pixel format Standard_Boolean myIsSRgbWindow; //!< indicates that window buffer is sRGB-ready Standard_Boolean myIsSRgbActive; //!< flag indicating GL_FRAMEBUFFER_SRGB state TCollection_AsciiString myVendor; //!< Graphics Driver's vendor diff --git a/src/OpenGl/OpenGl_DepthPeeling.cxx b/src/OpenGl/OpenGl_DepthPeeling.cxx index f89caa2976..b105a10af0 100644 --- a/src/OpenGl/OpenGl_DepthPeeling.cxx +++ b/src/OpenGl/OpenGl_DepthPeeling.cxx @@ -27,11 +27,11 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_DepthPeeling, OpenGl_NamedResource) OpenGl_DepthPeeling::OpenGl_DepthPeeling() : OpenGl_NamedResource ("depth_peeling") { - myDepthPeelFbosOit[0] = new OpenGl_FrameBuffer(); - myDepthPeelFbosOit[1] = new OpenGl_FrameBuffer(); - myFrontBackColorFbosOit[0] = new OpenGl_FrameBuffer(); - myFrontBackColorFbosOit[1] = new OpenGl_FrameBuffer(); - myBlendBackFboOit = new OpenGl_FrameBuffer(); + myDepthPeelFbosOit[0] = new OpenGl_FrameBuffer (myResourceId + ":fbo0"); + myDepthPeelFbosOit[1] = new OpenGl_FrameBuffer (myResourceId + ":fbo1"); + myFrontBackColorFbosOit[0] = new OpenGl_FrameBuffer (myResourceId + ":fbo0_color"); + myFrontBackColorFbosOit[1] = new OpenGl_FrameBuffer (myResourceId + ":fbo1_color"); + myBlendBackFboOit = new OpenGl_FrameBuffer (myResourceId + ":fbo_blend"); } // ======================================================================= diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index f7a4d95a7d..2d7d0328cb 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -22,7 +22,7 @@ #include #include -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer,OpenGl_Resource) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_NamedResource) namespace { @@ -66,8 +66,9 @@ namespace // function : OpenGl_FrameBuffer // purpose : // ======================================================================= -OpenGl_FrameBuffer::OpenGl_FrameBuffer() -: myInitVPSizeX (0), +OpenGl_FrameBuffer::OpenGl_FrameBuffer (const TCollection_AsciiString& theResourceId) +: OpenGl_NamedResource (theResourceId), + myInitVPSizeX (0), myInitVPSizeY (0), myVPSizeX (0), myVPSizeY (0), @@ -79,10 +80,10 @@ OpenGl_FrameBuffer::OpenGl_FrameBuffer() myIsOwnBuffer (false), myIsOwnColor (false), myIsOwnDepth (false), - myDepthStencilTexture (new OpenGl_Texture()) + myDepthStencilTexture (new OpenGl_Texture (theResourceId + ":depth_stencil")) { myColorFormats.Append (GL_RGBA8); - myColorTextures.Append (new OpenGl_Texture()); + myColorTextures.Append (new OpenGl_Texture (theResourceId + ":color")); } // ======================================================================= @@ -221,7 +222,9 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo } for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength) { - myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture()); + myColorTextures.Append (aLength < aTextures.Length() + ? aTextures.Value (aLength) + : new OpenGl_Texture (myResourceId + ":color" + aLength)); } myDepthFormat = theDepthStencilTexture->GetFormat(); @@ -343,7 +346,9 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo } for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength) { - myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture()); + myColorTextures.Append (aLength < aTextures.Length() + ? aTextures.Value (aLength) + : new OpenGl_Texture (myResourceId + ":color" + aLength)); } myDepthFormat = theDepthFormat; diff --git a/src/OpenGl/OpenGl_FrameBuffer.hxx b/src/OpenGl/OpenGl_FrameBuffer.hxx index 3071c04cdc..d3955eca00 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.hxx +++ b/src/OpenGl/OpenGl_FrameBuffer.hxx @@ -15,7 +15,7 @@ #ifndef OpenGl_FrameBuffer_HeaderFile #define OpenGl_FrameBuffer_HeaderFile -#include +#include #include #include @@ -25,16 +25,16 @@ class Image_PixMap; class OpenGl_Texture; -DEFINE_STANDARD_HANDLE(OpenGl_FrameBuffer, OpenGl_Resource) +DEFINE_STANDARD_HANDLE(OpenGl_FrameBuffer, OpenGl_NamedResource) //! Short declaration of useful collection types. typedef NCollection_Vector OpenGl_ColorFormats; //! Class implements FrameBuffer Object (FBO) resource //! intended for off-screen rendering. -class OpenGl_FrameBuffer : public OpenGl_Resource +class OpenGl_FrameBuffer : public OpenGl_NamedResource { - + DEFINE_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_NamedResource) public: //! Helpful constants @@ -57,7 +57,7 @@ public: public: //! Empty constructor - Standard_EXPORT OpenGl_FrameBuffer(); + Standard_EXPORT OpenGl_FrameBuffer (const TCollection_AsciiString& theResourceId = TCollection_AsciiString()); //! Destructor Standard_EXPORT virtual ~OpenGl_FrameBuffer(); @@ -371,10 +371,6 @@ protected: OpenGl_TextureArray myColorTextures; //!< color texture objects Handle(OpenGl_Texture) myDepthStencilTexture; //!< depth-stencil texture object -public: - - DEFINE_STANDARD_RTTIEXT(OpenGl_FrameBuffer,OpenGl_Resource) // Type definition - }; #endif // OPENGL_FRAME_BUFFER_H diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index b39fd6c199..8e348d9406 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -79,28 +79,30 @@ namespace #if defined(HAVE_EGL) //! Wrapper over eglChooseConfig() called with preferred defaults. - static EGLConfig chooseEglSurfConfig (EGLDisplay theDisplay) + static EGLConfig chooseEglSurfConfig (EGLDisplay theDisplay, + const Handle(OpenGl_Caps)& theCaps) { - EGLint aConfigAttribs[] = - { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 0, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - #if defined(OpenGl_USE_GLES2) - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - #else - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - #endif - EGL_NONE - }; - EGLConfig aCfg = NULL; EGLint aNbConfigs = 0; for (Standard_Integer aGlesVer = 3; aGlesVer >= 2; --aGlesVer) { + bool isDeepColor = theCaps->buffersDeepColor; + EGLint aConfigAttribs[] = + { + EGL_RED_SIZE, isDeepColor ? 10 : 8, + EGL_GREEN_SIZE, isDeepColor ? 10 : 8, + EGL_BLUE_SIZE, isDeepColor ? 10 : 8, + EGL_ALPHA_SIZE, 0, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + #if defined(OpenGl_USE_GLES2) + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #else + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + #endif + EGL_NONE + }; + #if defined(OpenGl_USE_GLES2) aConfigAttribs[6 * 2 + 1] = aGlesVer == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT; #else @@ -117,13 +119,30 @@ namespace } eglGetError(); - aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer - if (eglChooseConfig (theDisplay, aConfigAttribs, &aCfg, 1, &aNbConfigs) == EGL_TRUE - && aCfg != NULL) + if (isDeepColor) { - return aCfg; + // try config with smaller color buffer + aConfigAttribs[0 * 2 + 1] = 8; + aConfigAttribs[1 * 2 + 1] = 8; + aConfigAttribs[2 * 2 + 1] = 8; + if (eglChooseConfig (theDisplay, aConfigAttribs, &aCfg, 1, &aNbConfigs) == EGL_TRUE + && aCfg != NULL) + { + return aCfg; + } + eglGetError(); + } + + { + // try config with smaller depth buffer + aConfigAttribs[4 * 2 + 1] = 16; + if (eglChooseConfig (theDisplay, aConfigAttribs, &aCfg, 1, &aNbConfigs) == EGL_TRUE + && aCfg != NULL) + { + return aCfg; + } + eglGetError(); } - eglGetError(); } return aCfg; } @@ -327,7 +346,7 @@ Standard_Boolean OpenGl_GraphicDriver::InitContext() return Standard_False; } - myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay); + myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay, myCaps); if (myEglConfig == NULL) { ::Message::SendFail ("Error: EGL does not provide compatible configurations"); @@ -404,7 +423,7 @@ Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display t myEglConfig = theEglConfig; if (theEglConfig == NULL) { - myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay); + myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay, myCaps); if (myEglConfig == NULL) { ::Message::SendFail ("Error: EGL does not provide compatible configurations"); diff --git a/src/OpenGl/OpenGl_ShadowMap.cxx b/src/OpenGl/OpenGl_ShadowMap.cxx index fa803e97f1..f56f2241ab 100644 --- a/src/OpenGl/OpenGl_ShadowMap.cxx +++ b/src/OpenGl/OpenGl_ShadowMap.cxx @@ -29,7 +29,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShadowMap, OpenGl_NamedResource) // ======================================================================= OpenGl_ShadowMap::OpenGl_ShadowMap() : OpenGl_NamedResource ("shadow_map"), - myShadowMapFbo (new OpenGl_FrameBuffer()), + myShadowMapFbo (new OpenGl_FrameBuffer (myResourceId + ":fbo")), myShadowCamera (new Graphic3d_Camera()), myShadowMapBias (0.0f) { diff --git a/src/OpenGl/OpenGl_TextureFormat.cxx b/src/OpenGl/OpenGl_TextureFormat.cxx index 5fcc450efd..31f62cc39f 100644 --- a/src/OpenGl/OpenGl_TextureFormat.cxx +++ b/src/OpenGl/OpenGl_TextureFormat.cxx @@ -110,6 +110,7 @@ TCollection_AsciiString OpenGl_TextureFormat::FormatDataType (GLint theDataType) case GL_HALF_FLOAT: return "GL_HALF_FLOAT"; case 0x8D61: return "GL_HALF_FLOAT_OES"; case GL_UNSIGNED_INT_24_8: return "GL_UNSIGNED_INT_24_8"; + case GL_UNSIGNED_INT_2_10_10_10_REV: return "GL_UNSIGNED_INT_2_10_10_10_REV"; case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return "GL_FLOAT_32_UNSIGNED_INT_24_8_REV"; } return OpenGl_Context::FormatGlEnumHex (theDataType); @@ -586,6 +587,15 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindSizedFormat (const Handle(OpenGl_ } return aFormat; } + case GL_RGB10_A2: + { + aFormat.SetNbComponents (4); + aFormat.SetInternalFormat (theSizedFormat); + aFormat.SetPixelFormat (GL_RGBA); + aFormat.SetDataType (GL_UNSIGNED_INT_2_10_10_10_REV); + aFormat.SetImageFormat (Image_Format_RGBA); + return aFormat; + } // integer types case GL_R32I: { diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 819491c3e6..d398a4a9ec 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -158,21 +158,21 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, myNoShadingLight = new Graphic3d_LightSet(); myNoShadingLight->Add (aLight); - myMainSceneFbos[0] = new OpenGl_FrameBuffer(); - myMainSceneFbos[1] = new OpenGl_FrameBuffer(); - myMainSceneFbosOit[0] = new OpenGl_FrameBuffer(); - myMainSceneFbosOit[1] = new OpenGl_FrameBuffer(); - myImmediateSceneFbos[0] = new OpenGl_FrameBuffer(); - myImmediateSceneFbos[1] = new OpenGl_FrameBuffer(); - myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer(); - myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer(); - myXrSceneFbo = 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[0] = new OpenGl_FrameBuffer ("fbo0_main"); + myMainSceneFbos[1] = new OpenGl_FrameBuffer ("fbo1_main"); + myMainSceneFbosOit[0] = new OpenGl_FrameBuffer ("fbo0_main_oit"); + myMainSceneFbosOit[1] = new OpenGl_FrameBuffer ("fbo1_main_oit"); + myImmediateSceneFbos[0] = new OpenGl_FrameBuffer ("fbo0_imm"); + myImmediateSceneFbos[1] = new OpenGl_FrameBuffer ("fbo1_imm"); + myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer ("fbo0_imm_oit"); + myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer ("fbo1_imm_oit"); + myXrSceneFbo = new OpenGl_FrameBuffer ("fbo_xr"); + myOpenGlFBO = new OpenGl_FrameBuffer ("fbo_gl"); + myOpenGlFBO2 = new OpenGl_FrameBuffer ("fbo_gl2"); + myRaytraceFBO1[0] = new OpenGl_FrameBuffer ("fbo0_raytrace1"); + myRaytraceFBO1[1] = new OpenGl_FrameBuffer ("fbo1_raytrace1"); + myRaytraceFBO2[0] = new OpenGl_FrameBuffer ("fbo0_raytrace2"); + myRaytraceFBO2[1] = new OpenGl_FrameBuffer ("fbo1_raytrace2"); myDepthPeelingFbos = new OpenGl_DepthPeeling(); myShadowMaps = new OpenGl_ShadowMapArray(); } @@ -387,8 +387,25 @@ void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow, myHasFboBlit = Standard_True; Invalidate(); + // choose preferred FBO format + const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); + if (aCtx->IsWindowDeepColor() + && aCtx->IsGlGreaterEqual (3, 0)) + { + myFboColorFormat = GL_RGB10_A2; + } + else if (aCtx->HasSRGB()) + { + // note that GL_SRGB8 is not required to be renderable, unlike GL_RGB8, GL_RGBA8, GL_SRGB8_ALPHA8 + myFboColorFormat = GL_SRGB8_ALPHA8; + } + else + { + myFboColorFormat = GL_RGBA8; + } + // Environment texture resource does not support lazy initialization. - initTextureEnv (myWorkspace->GetGlContext()); + initTextureEnv (aCtx); } // ======================================================================= @@ -950,6 +967,19 @@ void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& t { TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio()); theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio; + if (myMainSceneFbos[0]->IsValid()) + { + TCollection_AsciiString anFboInfo; + if (const Handle(OpenGl_Texture)& aColorTex = myMainSceneFbos[0]->ColorTexture()) + { + anFboInfo += OpenGl_TextureFormat::FormatFormat (aColorTex->SizedFormat()); + } + if (const Handle(OpenGl_Texture)& aDepthTex = myMainSceneFbos[0]->DepthStencilTexture()) + { + anFboInfo = anFboInfo + " " + OpenGl_TextureFormat::FormatFormat (aDepthTex->SizedFormat()); + } + theDict.ChangeFromIndex (theDict.Add ("FBO buffer", anFboInfo)) = anFboInfo; + } } } diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index 788aa3553e..16545d39fc 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -340,7 +340,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, HWND aWinTmp = NULL; HDC aDevCtxTmp = NULL; HGLRC aRendCtxTmp = NULL; - if ((!theCaps->contextDebug && !theCaps->contextNoAccel && theCaps->contextCompatible) + if ((!theCaps->contextDebug && !theCaps->contextNoAccel && theCaps->contextCompatible && !theCaps->buffersDeepColor) || RegisterClassW (&aClass) == 0) { aClass.lpszClassName = NULL; @@ -404,7 +404,11 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, //WGL_SAMPLE_BUFFERS_ARB, 1, //WGL_SAMPLES_ARB, 8, - WGL_COLOR_BITS_ARB, 24, + //WGL_COLOR_BITS_ARB, 24, + WGL_RED_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, + WGL_GREEN_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, + WGL_BLUE_BITS_ARB, theCaps->buffersDeepColor ? 10 : 8, + WGL_ALPHA_BITS_ARB, theCaps->buffersDeepColor ? 2 : 8, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, // WGL_EXT_colorspace extension specifies if OpenGL should write into window buffer as into sRGB or RGB framebuffer @@ -415,7 +419,12 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, 0, 0, }; unsigned int aFrmtsNb = 0; - aChoosePixProc (aWindowDC, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb); + if (!aChoosePixProc (aWindowDC, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb) + && theCaps->buffersDeepColor) + { + /// TODO + Message::SendFail() << "Error: unable to find RGB10_A2 window buffer format!"; + } } // setup pixel format - may be set only once per window diff --git a/src/OpenGlTest/OpenGlTest_Commands.cxx b/src/OpenGlTest/OpenGlTest_Commands.cxx index be6785cf38..226b6e44b2 100644 --- a/src/OpenGlTest/OpenGlTest_Commands.cxx +++ b/src/OpenGlTest/OpenGlTest_Commands.cxx @@ -597,6 +597,7 @@ static int VCaps (Draw_Interpretor& theDI, theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n"; theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n"; theDI << "OpaqueAlpha: " << (aCaps->buffersOpaqueAlpha ? "1" : "0") << "\n"; + theDI << "DeepColor: " << (aCaps->buffersDeepColor ? "1" : "0") << "\n"; theDI << "NoExt:" << (aCaps->contextNoExtensions ? "1" : "0") << "\n"; theDI << "MaxVersion:" << aCaps->contextMajorVersionUpper << "." << aCaps->contextMinorVersionUpper << "\n"; theDI << "CompressTextures: " << (aCaps->compressedTexturesDisable ? "0" : "1") << "\n"; @@ -614,148 +615,90 @@ static int VCaps (Draw_Interpretor& theDI, continue; } else if (anArgCase == "-vsync" + || anArgCase == "-novsync" || anArgCase == "-swapinterval") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->swapInterval = toEnable; + aCaps->swapInterval = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-ffp") + else if (anArgCase == "-ffp" + || anArgCase == "-noffp") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->ffpEnable = toEnable; + aCaps->ffpEnable = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-polygonmode") + else if (anArgCase == "-polygonmode" + || anArgCase == "-nopolygonmode") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->usePolygonMode = toEnable; + aCaps->usePolygonMode = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-srgb") + else if (anArgCase == "-srgb" + || anArgCase == "-nosrgb") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->sRGBDisable = !toEnable; + aCaps->sRGBDisable = !Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-compressedtextures") + else if (anArgCase == "-compressedtextures" + || anArgCase == "-nocompressedtextures") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->compressedTexturesDisable = !toEnable; + aCaps->compressedTexturesDisable = !Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-vbo") + else if (anArgCase == "-vbo" + || anArgCase == "-novbo") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->vboDisable = !toEnable; + aCaps->vboDisable = !Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-sprite" || anArgCase == "-sprites") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->pntSpritesDisable = !toEnable; + aCaps->pntSpritesDisable = !Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-depthzerotoone" || anArgCase == "-zerotoonedepth" || anArgCase == "-usezerotoonedepth" || anArgCase == "-iszerotoonedepth") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->useZeroToOneDepth = toEnable; + aCaps->useZeroToOneDepth = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); } - else if (anArgCase == "-softmode") + else if (anArgCase == "-softmode" + || anArgCase == "-contextnoaccel") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->contextNoAccel = toEnable; + aCaps->contextNoAccel = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-opaquealpha" - || anArgCase == "-buffersOpaqueAlpha") + || anArgCase == "-noopaquealpha" + || anArgCase == "-buffersopaquealpha" + || anArgCase == "-nobuffersopaquealpha") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->buffersOpaqueAlpha = toEnable; + aCaps->buffersOpaqueAlpha = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); + } + else if (anArgCase == "-deepcolor" + || anArgCase == "-nodeepcolor" + || anArgCase == "-buffersdeepcolor" + || anArgCase == "-nobuffersdeepcolor") + { + aCaps->buffersDeepColor = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-winbuffer" || anArgCase == "-windowbuffer" + || anArgCase == "-nowinbuffer" + || anArgCase == "-nowindowbuffer" || anArgCase == "-usewinbuffer" || anArgCase == "-usewindowbuffer" || anArgCase == "-usesystembuffer") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->useSystemBuffer = toEnable; + aCaps->useSystemBuffer = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-accel" - || anArgCase == "-acceleration") + || anArgCase == "-acceleration" + || anArgCase == "-noaccel" + || anArgCase == "-noacceleration") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->contextNoAccel = !toEnable; + aCaps->contextNoAccel = !Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-compat" || anArgCase == "-compatprofile" || anArgCase == "-compatible" || anArgCase == "-compatibleprofile") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->contextCompatible = toEnable; + aCaps->contextCompatible = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); if (!aCaps->contextCompatible) { aCaps->ffpEnable = Standard_False; @@ -764,40 +707,24 @@ static int VCaps (Draw_Interpretor& theDI, else if (anArgCase == "-core" || anArgCase == "-coreprofile") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->contextCompatible = !toEnable; + aCaps->contextCompatible = !Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); if (!aCaps->contextCompatible) { aCaps->ffpEnable = Standard_False; } } else if (anArgCase == "-stereo" - || anArgCase == "-quadbuffer") + || anArgCase == "-quadbuffer" + || anArgCase == "-nostereo" + || anArgCase == "-noquadbuffer") { - Standard_Boolean toEnable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable)) - { - --anArgIter; - } - aCaps->contextStereo = toEnable; + aCaps->contextStereo = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-noext" || anArgCase == "-noextensions" || anArgCase == "-noextension") { - Standard_Boolean toDisable = Standard_True; - if (++anArgIter < theArgNb - && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable)) - { - --anArgIter; - } - aCaps->contextNoExtensions = toDisable; + aCaps->contextNoExtensions = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter); } else if (anArgCase == "-maxversion" || anArgCase == "-upperversion" @@ -859,7 +786,7 @@ void OpenGlTest::Commands (Draw_Interpretor& theCommands) "vcaps [-sRGB {0|1}] [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]" "\n\t\t: [-compatibleProfile {0|1}] [-compressedTextures {0|1}]" "\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}] [-opaqueAlpha {0|1}]" - "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]" + "\n\t\t: [-deepColor {0|1}] [-quadBuffer {0|1}] [-stereo {0|1}]" "\n\t\t: [-softMode {0|1}] [-noupdate|-update]" "\n\t\t: [-zeroToOneDepth {0|1}]" "\n\t\t: [-noExtensions {0|1}] [-maxVersion Major Minor]" @@ -877,10 +804,12 @@ void OpenGlTest::Commands (Draw_Interpretor& theCommands) "\n\t\t: opaqueAlpha - disable writes in alpha component of color buffer" "\n\t\t: winBuffer - allow using window buffer for rendering" "\n\t\t: zeroToOneDepth - use [0,1] depth range instead of [-1,1] range" + "\n\t\t: Window buffer creation options:" + "\n\t\t: quadbuffer - QuadBuffer for stereoscopic displays" + "\n\t\t: deepColor - window buffer with higher color precision (30bit instead of 24bit RGB)" "\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: noExtensions - disallow usage of extensions" "\n\t\t: maxVersion - force upper OpenGL version to be used" "\n\t\t: These parameters control alternative"