From 58655684c042afd50b62d8cc2dff3a325d0b0bfb Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 29 Aug 2013 15:45:45 +0400 Subject: [PATCH] 0024123: Create debug OpenGL context when requested (GL_ARB_debug_output) Introduce new OpenGl_Caps class for unified graphic driver options access. New command vgldebug to request debug OpenGL context. OpenGl_Window - create debug OpenGL context when requested (WGL-only). OpenGl_Context - destroy arbTBO, arbIns members. Workaround namespace collisions with Xlib macros Eliminate new warning (unused argument in OpenGl_Context::debugCallbackWrap) --- src/InterfaceGraphic/InterfaceGraphic_X11.hxx | 79 +++++------ src/OpenGl/FILES | 3 + src/OpenGl/OpenGl_ArbDbg.hxx | 36 +++++ src/OpenGl/OpenGl_Caps.cxx | 54 ++++++++ src/OpenGl/OpenGl_Caps.hxx | 64 +++++++++ src/OpenGl/OpenGl_Context.cxx | 122 +++++++++++++++-- src/OpenGl/OpenGl_Context.hxx | 15 ++- src/OpenGl/OpenGl_GraphicDriver.cxx | 15 +-- src/OpenGl/OpenGl_GraphicDriver.hxx | 16 ++- src/OpenGl/OpenGl_GraphicDriver_7.cxx | 2 +- src/OpenGl/OpenGl_PrimitiveArray.cxx | 3 +- src/OpenGl/OpenGl_Text.cxx | 2 +- src/OpenGl/OpenGl_Window.cxx | 125 ++++++++++++++++-- src/OpenGl/OpenGl_Window.hxx | 2 + src/OpenGl/OpenGl_Window_1.mm | 3 +- src/OpenGl/OpenGl_Workspace.cxx | 5 +- src/OpenGl/OpenGl_Workspace.hxx | 1 + src/ViewerTest/ViewerTest_ObjectCommands.cxx | 2 +- src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 8 +- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 110 +++++++++------ 20 files changed, 541 insertions(+), 126 deletions(-) create mode 100644 src/OpenGl/OpenGl_ArbDbg.hxx create mode 100644 src/OpenGl/OpenGl_Caps.cxx create mode 100644 src/OpenGl/OpenGl_Caps.hxx diff --git a/src/InterfaceGraphic/InterfaceGraphic_X11.hxx b/src/InterfaceGraphic/InterfaceGraphic_X11.hxx index 3d39fb645b..a597cfd88c 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_X11.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_X11.hxx @@ -16,48 +16,53 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. +#ifndef _WIN32 #ifndef InterfaceGraphic_X11Header -# define InterfaceGraphic_X11Header +#define InterfaceGraphic_X11Header -# ifndef WNT -# include +#include -# include -# include -# include -# include +#include +#include +#include +#include -# if defined (sun) || defined (SUNOS) || defined (__alpha) || defined (DECOSF1) || defined (sgi) || defined (IRIX) || defined (__hpux)|| defined (HPUX) -# ifndef icon_width -# include -# endif - -# endif /* SUNOS or DECOSF1 or SOLARIS or HPUX or IRIX */ - -# ifdef ULTRIX - -# ifndef icon_width -/* le contenu de #include sur SUN */ -#define icon_width 16 -#define icon_height 16 -static unsigned char icon_bits[] = { - 0xff, 0xff, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xaa, 0x05, 0xd0, 0x0b, 0xa0, +#if defined (sun) || defined (SUNOS) || defined (__alpha) || defined (DECOSF1) || defined (sgi) || defined (IRIX) || defined (__hpux)|| defined (HPUX) + #ifndef icon_width + #include + #endif +#endif // SUNOS or DECOSF1 or SOLARIS or HPUX or IRIX +#if defined(ULTRIX) && !defined(icon_width) + #define icon_width 16 + #define icon_height 16 + static unsigned char icon_bits[] = + { + 0xff, 0xff, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xaa, 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, - 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xff, 0xff}; -# endif + 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xff, 0xff + }; +#endif // ULTRIX -# endif /* ULTRIX */ -# define WINDOW Window -# define DISPLAY Display -# define GLCONTEXT GLXContext -# define GLDRAWABLE GLXDrawable +// workaround name conflicts with OCCT methods (in class TopoDS_Shape for example) +#ifdef Convex + #undef Convex +#endif +#ifdef Status + #undef Status +#endif -# define GET_GL_CONTEXT() glXGetCurrentContext() -# define GET_GLDEV_CONTEXT() glXGetCurrentDrawable() -# define GL_MAKE_CURRENT(a,b,c) glXMakeCurrent(a,b,c) +#define WINDOW Window +#define DISPLAY Display +#define GLCONTEXT GLXContext +#define GLDRAWABLE GLXDrawable -# ifndef EXPORT -# define EXPORT -# endif /* EXPORT */ -# endif /* WNT */ -#endif /* InterfaceGraphic_X11Header */ +#define GET_GL_CONTEXT() glXGetCurrentContext() +#define GET_GLDEV_CONTEXT() glXGetCurrentDrawable() +#define GL_MAKE_CURRENT(a,b,c) glXMakeCurrent(a,b,c) + +#ifndef EXPORT + #define EXPORT +#endif // EXPORT + +#endif // InterfaceGraphic_X11Header +#endif // _WIN32 diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index ad1f9b7a48..51d8949bbe 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -87,6 +87,8 @@ OpenGl_transform_persistence.hxx OpenGl_Font.hxx OpenGl_Font.cxx OpenGl_tgl_funcs.hxx +OpenGl_Caps.hxx +OpenGl_Caps.cxx Handle_OpenGl_Context.hxx OpenGl_Context.hxx OpenGl_Context.cxx @@ -94,6 +96,7 @@ OpenGl_Context_1.mm OpenGl_ArbIns.hxx OpenGl_ArbTBO.hxx OpenGl_ArbVBO.hxx +OpenGl_ArbDbg.hxx OpenGl_ExtFBO.hxx OpenGl_ExtGS.hxx glext.h diff --git a/src/OpenGl/OpenGl_ArbDbg.hxx b/src/OpenGl/OpenGl_ArbDbg.hxx new file mode 100644 index 0000000000..0514d98686 --- /dev/null +++ b/src/OpenGl/OpenGl_ArbDbg.hxx @@ -0,0 +1,36 @@ +// Created on: 2013-08-25 +// Created by: Kirill GAVRILOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_ArbDbg_H__ +#define _OpenGl_ArbDbg_H__ + +#include + +//! Debug context routines +struct OpenGl_ArbDbg +{ + + PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB; + PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB; + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; + PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB; + +}; + +#endif // _OpenGl_ArbDbg_H__ diff --git a/src/OpenGl/OpenGl_Caps.cxx b/src/OpenGl/OpenGl_Caps.cxx new file mode 100644 index 0000000000..86a679e924 --- /dev/null +++ b/src/OpenGl/OpenGl_Caps.cxx @@ -0,0 +1,54 @@ +// Created on: 2013-08-25 +// Created by: Kirill GAVRILOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#include + +IMPLEMENT_STANDARD_HANDLE (OpenGl_Caps, Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Caps, Standard_Transient) + +// ======================================================================= +// function : OpenGl_Caps +// purpose : +// ======================================================================= +OpenGl_Caps::OpenGl_Caps() +: vboDisable (Standard_False), + contextDebug (Standard_False) +{ + // +} + +// ======================================================================= +// function : operator= +// purpose : +// ======================================================================= +OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy) +{ + vboDisable = theCopy.vboDisable; + contextDebug = theCopy.contextDebug; + return *this; +} + +// ======================================================================= +// function : ~OpenGl_Caps +// purpose : +// ======================================================================= +OpenGl_Caps::~OpenGl_Caps() +{ + // +} diff --git a/src/OpenGl/OpenGl_Caps.hxx b/src/OpenGl/OpenGl_Caps.hxx new file mode 100644 index 0000000000..04e5bc2a7c --- /dev/null +++ b/src/OpenGl/OpenGl_Caps.hxx @@ -0,0 +1,64 @@ +// Created on: 2013-08-25 +// Created by: Kirill GAVRILOV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_Caps_H__ +#define _OpenGl_Caps_H__ + +#include +#include +#include + +//! Class to define graphich driver capabilities. +//! Notice that these options will be ignored if particular functionality does not provided by GL driver +class OpenGl_Caps : public Standard_Transient +{ + +public: //! @name flags to disable particular functionality + + Standard_Boolean vboDisable; //!< flag permits VBO usage, will significantly affect performance (OFF by default) + +public: //! @name context creation parameters + + Standard_Boolean contextDebug; //!< request debug GL context (requires support in OpenGL driver), useful for debugging of visualization code (OFF by default, currently implemented only fow Windows) + +public: //! @name class methods + + //! Default constructor - initialize with most optimal values. + Standard_EXPORT OpenGl_Caps(); + + //! Destructor. + Standard_EXPORT virtual ~OpenGl_Caps(); + + //! Copy maker. + Standard_EXPORT OpenGl_Caps& operator= (const OpenGl_Caps& theCopy); + +private: + + //! Not implemented + OpenGl_Caps (const OpenGl_Caps& ); + +public: + + DEFINE_STANDARD_RTTI(OpenGl_Caps) // Type definition + +}; + +DEFINE_STANDARD_HANDLE(OpenGl_Caps, Standard_Transient) + +#endif // _OpenGl_Caps_H__ diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index bf702ff8e3..b9842105b5 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -17,7 +17,7 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) #include #endif @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ #include -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) // #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) #include @@ -69,16 +70,18 @@ namespace // function : OpenGl_Context // purpose : // ======================================================================= -OpenGl_Context::OpenGl_Context() +OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) : core12 (NULL), core13 (NULL), core14 (NULL), core15 (NULL), core20 (NULL), + caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()), arbNPTW(Standard_False), arbVBO (NULL), arbTBO (NULL), arbIns (NULL), + arbDbg (NULL), extFBO (NULL), extGS (NULL), extBgra(Standard_False), @@ -134,6 +137,9 @@ OpenGl_Context::~OpenGl_Context() delete myGlCore20; delete arbVBO; + delete arbTBO; + delete arbIns; + delete arbDbg; delete extFBO; delete extGS; } @@ -178,7 +184,7 @@ void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx) // ======================================================================= Standard_Boolean OpenGl_Context::IsCurrent() const { -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) if (myWindowDC == NULL || myGContext == NULL) { return Standard_False; @@ -203,7 +209,7 @@ Standard_Boolean OpenGl_Context::IsCurrent() const // ======================================================================= Standard_Boolean OpenGl_Context::MakeCurrent() { -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) if (myWindowDC == NULL || myGContext == NULL) { Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!"); @@ -257,7 +263,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent() // ======================================================================= void OpenGl_Context::SwapBuffers() { -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) if ((HDC )myWindowDC != NULL) { ::SwapBuffers ((HDC )myWindowDC); @@ -279,7 +285,7 @@ void OpenGl_Context::SwapBuffers() // ======================================================================= void* OpenGl_Context::findProc (const char* theFuncName) { -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) return wglGetProcAddress (theFuncName); #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL; @@ -299,7 +305,6 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const std::cerr << "CheckExtension called with NULL string!\n"; return Standard_False; } - const size_t anExtNameLen = strlen (theExtName); // available since OpenGL 3.0 // and the ONLY way to check extensions with OpenGL 3.1+ core profile @@ -326,11 +331,26 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n"; return Standard_False; } + return CheckExtension (anExtString, theExtName); +} + +// ======================================================================= +// function : CheckExtension +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString, + const char* theExtName) +{ + if (theExtString == NULL) + { + return Standard_False; + } // Search for theExtName in the extensions string. // Use of strstr() is not sufficient because extension names can be prefixes of other extension names. - char* aPtrIter = (char* )anExtString; - const char* aPtrEnd = aPtrIter + strlen (anExtString); + char* aPtrIter = (char* )theExtString; + const char* aPtrEnd = aPtrIter + strlen (theExtString); + const size_t anExtNameLen = strlen (theExtName); while (aPtrIter < aPtrEnd) { const size_t n = strcspn (aPtrIter, " "); @@ -356,7 +376,7 @@ Standard_Boolean OpenGl_Context::Init() return Standard_True; } -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) myWindowDC = (Aspect_Handle )wglGetCurrentDC(); myGContext = (Aspect_RenderingContext )wglGetCurrentContext(); #else @@ -380,7 +400,7 @@ Standard_Boolean OpenGl_Context::Init() // function : Init // purpose : // ======================================================================= -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow, const Aspect_Handle theWindowDC, const Aspect_RenderingContext theGContext) @@ -393,7 +413,7 @@ Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow, #endif { Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!"); -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) myWindow = theWindow; myGContext = theGContext; myWindowDC = theWindowDC; @@ -505,6 +525,60 @@ void OpenGl_Context::readGlVersion() } } +static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN"; +static Standard_CString THE_DBGMSG_SOURCES[] = +{ + "OpenGL", // GL_DEBUG_SOURCE_API_ARB + "Window System", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB + "Shader Compiler", // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB + "Third Party", // GL_DEBUG_SOURCE_THIRD_PARTY_ARB + "Application", // GL_DEBUG_SOURCE_APPLICATION_ARB + "Other" // GL_DEBUG_SOURCE_OTHER_ARB +}; + +static Standard_CString THE_DBGMSG_TYPES[] = +{ + "Error", // GL_DEBUG_TYPE_ERROR_ARB + "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB + "Undefined behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB + "Portability", // GL_DEBUG_TYPE_PORTABILITY_ARB + "Performance", // GL_DEBUG_TYPE_PERFORMANCE_ARB + "Other" // GL_DEBUG_TYPE_OTHER_ARB +}; + +static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH_ARB +static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB +static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW_ARB + +static void APIENTRY debugCallbackWrap(unsigned int theSource, + unsigned int theType, + unsigned int theId, + unsigned int theSeverity, + int /*theLength*/, + const char* theMessage, + void* /*theUserParam*/) +{ + //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam; + Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB + && theSource <= GL_DEBUG_SOURCE_OTHER_ARB) + ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB] + : THE_DBGMSG_UNKNOWN; + Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB + && theType <= GL_DEBUG_TYPE_OTHER_ARB) + ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB] + : THE_DBGMSG_UNKNOWN; + Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB + ? THE_DBGMSG_SEV_HIGH + : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB + ? THE_DBGMSG_SEV_MEDIUM + : THE_DBGMSG_SEV_LOW); + std::cerr << "Source:" << aSrc + << " | Type:" << aType + << " | ID:" << theId + << " | Severity:" << aSev + << " | Message:\n " << theMessage << "\n"; +} + // ======================================================================= // function : init // purpose : @@ -526,6 +600,28 @@ void OpenGl_Context::init() glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax); } + // initialize debug context extension + if (CheckExtension ("GL_ARB_debug_output")) + { + arbDbg = new OpenGl_ArbDbg(); + memset (arbDbg, 0, sizeof(OpenGl_ArbDbg)); // nullify whole structure + if (!FindProcShort (arbDbg, glDebugMessageControlARB) + || !FindProcShort (arbDbg, glDebugMessageInsertARB) + || !FindProcShort (arbDbg, glDebugMessageCallbackARB) + || !FindProcShort (arbDbg, glGetDebugMessageLogARB)) + { + delete arbDbg; + arbDbg = NULL; + } + if (arbDbg != NULL + && caps->contextDebug) + { + // setup default callback + arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this); + glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + } + } + // initialize VBO extension (ARB) if (CheckExtension ("GL_ARB_vertex_buffer_object")) { diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index a35b36ee86..ecdc69c8e9 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ struct OpenGl_GlCore20; struct OpenGl_ArbVBO; struct OpenGl_ArbTBO; struct OpenGl_ArbIns; +struct OpenGl_ArbDbg; struct OpenGl_ExtFBO; struct OpenGl_ExtGS; @@ -102,7 +104,7 @@ public: public: //! Empty constructor. You should call Init() to perform initialization with bound GL context. - Standard_EXPORT OpenGl_Context(); + Standard_EXPORT OpenGl_Context (const Handle(OpenGl_Caps)& theCaps = NULL); //! Destructor. Standard_EXPORT virtual ~OpenGl_Context(); @@ -115,7 +117,7 @@ public: //! GL context should be active! Standard_EXPORT Standard_Boolean Init(); -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) Standard_EXPORT Standard_Boolean Init (const Aspect_Handle theWindow, const Aspect_Handle theWindowDC, const Aspect_RenderingContext theGContext); @@ -130,6 +132,10 @@ public: //! Check if theExtName extension is supported by active GL context. Standard_EXPORT Standard_Boolean CheckExtension (const char* theExtName) const; + //! Check if theExtName extension is in extensions string. + Standard_EXPORT static Standard_Boolean CheckExtension (const char* theExtString, + const char* theExtName); + //! Auxiliary template to retrieve GL function pointer. //! Pointer to function retrieved from library is statically casted //! to requested type - there no way to check real signature of exported function. @@ -257,12 +263,15 @@ public: // core profiles OpenGl_GlCore15* core15; OpenGl_GlCore20* core20; + Handle(OpenGl_Caps) caps; //!< context options + public: // extensions Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two OpenGl_ArbVBO* arbVBO; //!< GL_ARB_vertex_buffer_object OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced + OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output OpenGl_ExtFBO* extFBO; //!< GL_EXT_framebuffer_object OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4 Standard_Boolean extBgra; //!< GL_EXT_bgra @@ -272,7 +281,7 @@ public: // extensions private: // system-dependent fields -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) Aspect_Handle myWindow; //!< window handle (owner of GL context) : HWND Aspect_Handle myWindowDC; //!< Device Descriptor handle : HDC Aspect_RenderingContext myGContext; //!< Rendering Context handle : HGLRC diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 74e8d3b8ea..be8fcd7b01 100755 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -35,9 +35,6 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver) namespace { - // Global switch - shared by whole TKOpenGl module. To be removed. - static Standard_Boolean TheToUseVbo = Standard_True; - static const Handle(OpenGl_Context) TheNullGlCtx; }; @@ -67,6 +64,7 @@ extern "C" { // ======================================================================= OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Standard_CString theShrName) : Graphic3d_GraphicDriver (theShrName), + myCaps (new OpenGl_Caps()), myMapOfView (1, NCollection_BaseAllocator::CommonBaseAllocator()), myMapOfWS (1, NCollection_BaseAllocator::CommonBaseAllocator()), myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()), @@ -94,22 +92,13 @@ Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const return 16.; } -// ======================================================================= -// function : ToUseVBO -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_GraphicDriver::ToUseVBO() -{ - return TheToUseVbo; -} - // ======================================================================= // function : EnableVBO // purpose : // ======================================================================= void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn) { - TheToUseVbo = theToTurnOn; + myCaps->vboDisable = !theToTurnOn; } // ======================================================================= diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index e909f50b29..0f076b3095 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -86,7 +86,7 @@ class OpenGl_GraphicDriver : public Graphic3d_GraphicDriver public: //! Constructor - Standard_EXPORT OpenGl_GraphicDriver (const Standard_CString theShrName); + Standard_EXPORT OpenGl_GraphicDriver (const Standard_CString theShrName = "TKOpenGl"); Standard_EXPORT Standard_Boolean Begin (const Handle(Aspect_DisplayConnection)& theDisplayConnection); Standard_EXPORT void End (); @@ -296,8 +296,17 @@ public: public: - //! Returns true if VBO usage does not forbidden. - Standard_EXPORT static Standard_Boolean ToUseVBO(); + //! @return the visualization options + inline const OpenGl_Caps& Options() const + { + return *myCaps.operator->(); + } + + //! @return the visualization options + inline OpenGl_Caps& ChangeOptions() + { + return *myCaps.operator->(); + } //! VBO usage can be forbidden by this method even if it is supported by GL driver. //! Notice that disabling of VBO will cause rendering performance degradation. @@ -327,6 +336,7 @@ public: private: + Handle(OpenGl_Caps) myCaps; NCollection_DataMap myMapOfView; NCollection_DataMap myMapOfWS; NCollection_DataMap myMapOfStructure; diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index 39cbeed44c..4e91e47723 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -501,7 +501,7 @@ Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView) if (aWS.IsNull()) { Handle(OpenGl_Context) aShareCtx = GetSharedContext(); - aWS = new OpenGl_Workspace (openglDisplay, theCView.DefWindow, theCView.GContext, aShareCtx); + aWS = new OpenGl_Workspace (openglDisplay, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx); openglDisplay->SetWindow (theCView.DefWindow.XWindow, aWS); } diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 02a14a6db0..fdc0f02b14 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -597,7 +597,8 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace } // create VBOs on first render call - if (!myIsVboInit && OpenGl_GraphicDriver::ToUseVBO() && theWorkspace->GetGlContext()->core15 != NULL) + const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); + if (!myIsVboInit && !aCtx->caps->vboDisable && aCtx->core15 != NULL) { BuildVBO (theWorkspace); myIsVboInit = Standard_True; diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index 04dcf0e35a..6280229610 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -635,7 +635,7 @@ void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx, aFormatter.Append (theCtx, myString, *myFont.operator->()); aFormatter.Format(); - if (OpenGl_GraphicDriver::ToUseVBO() && theCtx->core15 != NULL) + if (!theCtx->caps->vboDisable && theCtx->core15 != NULL) { aFormatter.Result (theCtx, myTextures, myVertsVbo, myTCrdsVbo); } diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index a05ec8295a..415d26a4d1 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -38,7 +38,30 @@ namespace { static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } }; -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) + + // WGL_ARB_create_context_profile +#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB + #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 + #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 + #define WGL_CONTEXT_FLAGS_ARB 0x2094 + #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + + // WGL_CONTEXT_FLAGS bits + #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 + #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 + + // WGL_CONTEXT_PROFILE_MASK_ARB bits + #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#endif // WGL_CONTEXT_MAJOR_VERSION_ARB + + static LRESULT CALLBACK wndProcDummy (HWND theWin, UINT theMsg, WPARAM theParamW, LPARAM theParamL) + { + return DefWindowProcW (theWin, theMsg, theParamW, theParamL); + } + static int find_pixel_format (HDC theDevCtx, PIXELFORMATDESCRIPTOR& thePixelFrmt, const Standard_Boolean theIsDoubleBuff) @@ -139,11 +162,12 @@ namespace OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, const CALL_DEF_WINDOW& theCWindow, Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, const Handle(OpenGl_Context)& theShareCtx) : myDisplay (theDisplay), - myGlContext (new OpenGl_Context()), + myGlContext (new OpenGl_Context (theCaps)), myOwnGContext (theGContext == 0), -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) mySysPalInUse (FALSE), #endif myWidth ((Standard_Integer )theCWindow.dx), @@ -156,7 +180,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, myBgColor.rgb[1] = theCWindow.Background.g; myBgColor.rgb[2] = theCWindow.Background.b; -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) HWND aWindow = (HWND )theCWindow.XWindow; HDC aWindowDC = GetDC (aWindow); HGLRC aGContext = (HGLRC )theGContext; @@ -201,9 +225,92 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, return; } + HGLRC aSlaveCtx = !theShareCtx.IsNull() ? (HGLRC )theShareCtx->myGContext : NULL; if (aGContext == NULL) { - aGContext = wglCreateContext (aWindowDC); + // create temporary context to retrieve advanced context creation procedures + HMODULE aModule = GetModuleHandleW(NULL); + WNDCLASSW aClass; memset (&aClass, 0, sizeof(aClass)); + aClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + aClass.lpfnWndProc = wndProcDummy; + aClass.hInstance = aModule; + aClass.lpszClassName = L"OpenGl_WindowTmp"; + HWND aWinTmp = NULL; + HDC aDevCtxTmp = NULL; + HGLRC aRendCtxTmp = NULL; + if (!theCaps->contextDebug + || RegisterClassW (&aClass) == 0) + { + aClass.lpszClassName = NULL; + } + if (aClass.lpszClassName != NULL) + { + aWinTmp = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, + aClass.lpszClassName, L"OpenGl_WindowTmp", + WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, + 2, 2, 4, 4, + NULL, NULL, aModule, NULL); + } + if (aWinTmp != NULL) + { + aDevCtxTmp = GetDC (aWinTmp); + SetPixelFormat (aDevCtxTmp, aPixelFrmtId, &aPixelFrmt); + aRendCtxTmp = wglCreateContext (aDevCtxTmp); + } + if (aRendCtxTmp != NULL) + { + wglMakeCurrent (aDevCtxTmp, aRendCtxTmp); + + typedef const char* (WINAPI *wglGetExtensionsStringARB_t)(HDC theDeviceContext); + typedef HGLRC (WINAPI *wglCreateContextAttribsARB_t)(HDC theDevCtx, + HGLRC theShareContext, + const int* theAttribs); + wglGetExtensionsStringARB_t aGetExtensions = (wglGetExtensionsStringARB_t )wglGetProcAddress ("wglGetExtensionsStringARB"); + wglCreateContextAttribsARB_t aCreateCtxProc = (wglCreateContextAttribsARB_t )wglGetProcAddress ("wglCreateContextAttribsARB"); + const char* aWglExts = aGetExtensions (wglGetCurrentDC()); + if (aCreateCtxProc != NULL + && OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_create_context_profile")) + { + // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified + // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB. + int aCtxAttribs[] = + { + //WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + //WGL_CONTEXT_MINOR_VERSION_ARB, 2, + //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + 0, 0 + }; + + aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs); + if (aGContext != NULL) + { + aSlaveCtx = NULL; + } + } + } + + if (aRendCtxTmp != NULL) + { + wglDeleteContext (aRendCtxTmp); + } + if (aDevCtxTmp != NULL) + { + ReleaseDC (aWinTmp, aDevCtxTmp); + } + if (aWinTmp != NULL) + { + DestroyWindow (aWinTmp); + } + if (aClass.lpszClassName != NULL) + { + UnregisterClassW (aClass.lpszClassName, aModule); + } + + if (aGContext == NULL) + { + aGContext = wglCreateContext (aWindowDC); + } if (aGContext == NULL) { ReleaseDC (aWindow, aWindowDC); @@ -216,7 +323,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, } // all GL context within one OpenGl_GraphicDriver should be shared! - if (!theShareCtx.IsNull() && wglShareLists ((HGLRC )theShareCtx->myGContext, aGContext) != TRUE) + if (aSlaveCtx != NULL && wglShareLists (aSlaveCtx, aGContext) != TRUE) { TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: "); aMsg += (int )GetLastError(); @@ -409,7 +516,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, // ======================================================================= OpenGl_Window::~OpenGl_Window() { -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) HWND aWindow = (HWND )myGlContext->myWindow; HDC aWindowDC = (HDC )myGlContext->myWindowDC; HGLRC aGContext = (HGLRC )myGlContext->myGContext; @@ -468,7 +575,7 @@ void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow) myWidth = (Standard_Integer )theCWindow.dx; myHeight = (Standard_Integer )theCWindow.dy; -#if (!defined(_WIN32) && !defined(__WIN32__)) +#if !defined(_WIN32) XResizeWindow (aDisp, myGlContext->myWindow, (unsigned int )myWidth, (unsigned int )myHeight); XSync (aDisp, False); #endif @@ -525,7 +632,7 @@ void OpenGl_Window::Init() if (!Activate()) return; -#if (defined(_WIN32) || defined(__WIN32__)) +#if defined(_WIN32) RECT cr; GetClientRect ((HWND )myGlContext->myWindow, &cr); myWidth = cr.right - cr.left; diff --git a/src/OpenGl/OpenGl_Window.hxx b/src/OpenGl/OpenGl_Window.hxx index 9cd61e7057..aeb60e5bb9 100644 --- a/src/OpenGl/OpenGl_Window.hxx +++ b/src/OpenGl/OpenGl_Window.hxx @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -39,6 +40,7 @@ public: OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, const CALL_DEF_WINDOW& theCWindow, Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, const Handle(OpenGl_Context)& theShareCtx); //! Destructor diff --git a/src/OpenGl/OpenGl_Window_1.mm b/src/OpenGl/OpenGl_Window_1.mm index dce08ac5d9..2b7e2f68a3 100644 --- a/src/OpenGl/OpenGl_Window_1.mm +++ b/src/OpenGl/OpenGl_Window_1.mm @@ -52,9 +52,10 @@ namespace OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay, const CALL_DEF_WINDOW& theCWindow, Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, const Handle(OpenGl_Context)& theShareCtx) : myDisplay (theDisplay), - myGlContext (new OpenGl_Context()), + myGlContext (new OpenGl_Context (theCaps)), myOwnGContext (theGContext == 0), myWidth ((Standard_Integer )theCWindow.dx), myHeight ((Standard_Integer )theCWindow.dy), diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 10ec9d5692..22507903fa 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -32,7 +32,7 @@ #include -#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE) +#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) #include #endif @@ -70,8 +70,9 @@ namespace OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay, const CALL_DEF_WINDOW& theCWindow, Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, const Handle(OpenGl_Context)& theShareCtx) -: OpenGl_Window (theDisplay, theCWindow, theGContext, theShareCtx), +: OpenGl_Window (theDisplay, theCWindow, theGContext, theCaps, theShareCtx), NamedStatus (0), HighlightColor (&myDefaultHighlightColor), // diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index b0c06d0bf6..351127a9b0 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -70,6 +70,7 @@ public: OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay, const CALL_DEF_WINDOW& theCWindow, Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, const Handle(OpenGl_Context)& theShareCtx); //! Destructor diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 444a365c7a..e1c85058d6 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -2759,7 +2759,7 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c else if (argc < 3) { std::cout << "Use: " << argv[0] - << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToEnableVBO=1] [NumberOfViewerUpdate=1] [ToShowEdges=0]\n"; + << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n"; return 1; } diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index 6244fb3368..a30169dbe4 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -419,8 +419,6 @@ static int VImmediateFront (Draw_Interpretor& /*theDI*/, if (theArgNb < 2) { - //theDI << "VBO: " << aDriver->ToUseVBO() << "\n"; - //return 0; std::cerr << "Wrong number of arguments.\n"; return 1; } @@ -449,11 +447,15 @@ static int VGlInfo (Draw_Interpretor& theDI, if (theArgNb <= 1) { + Standard_CString aDebugInfo = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS), + "GL_ARB_debug_output") + ? " GLdebug = ON\n" : ""; theDI << "OpenGL info:\n" << " GLvendor = '" << (const char* )glGetString(GL_VENDOR) << "'\n" << " GLdevice = '" << (const char* )glGetString(GL_RENDERER) << "'\n" << " GLversion = '" << (const char* )glGetString(GL_VERSION) << "'\n" - << " GLSLversion = '" << (const char* )glGetString(GL_SHADING_LANGUAGE_VERSION) << "'\n"; + << " GLSLversion = '" << (const char* )glGetString(GL_SHADING_LANGUAGE_VERSION) << "'\n" + << aDebugInfo; return 0; } diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index eacdc3d484..b1705d70ff 100755 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -25,10 +25,7 @@ # include #endif -#ifdef WNT -#include -#endif - +#include #include #include #include @@ -36,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -79,7 +76,7 @@ #include #include -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) #include #include @@ -109,7 +106,7 @@ Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv); extern const Handle(NIS_InteractiveContext)& TheNISContext(); extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(); -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) static Handle(WNT_Window)& VT_GetWindow() { static Handle(WNT_Window) WNTWin; return WNTWin; @@ -144,11 +141,11 @@ static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDis GetDisplayConnection() = theDisplayConnection; } -#if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) +#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow) { Aspect_Handle aWindowHandle = NULL; -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow); if (!aWindow.IsNull()) return aWindow->HWindow(); @@ -164,9 +161,9 @@ Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow) static Standard_Boolean MyHLRIsOn = Standard_False; NCollection_DoubleMap ViewerTest_myViews; -static NCollection_DoubleMap ViewerTest_myContexts; +static NCollection_DoubleMap ViewerTest_myContexts; static NCollection_DoubleMap ViewerTest_myDrivers; - +static OpenGl_Caps ViewerTest_myDefaultCaps; #define ZCLIPWIDTH 1. @@ -209,7 +206,7 @@ static LRESULT WINAPI AdvViewerWindowProc( const Handle(MMgt_TShared)& ViewerTest::WClass() { static Handle(MMgt_TShared) theWClass; -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) if (theWClass.IsNull()) { theWClass = new WNT_WClass ("GW3D_Class", AdvViewerWindowProc, @@ -409,7 +406,7 @@ Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theVie void SetWindowTitle (const Handle(Aspect_Window)& theWindow, Standard_CString theTitle) { -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) SetWindowText ((HWND)Handle(WNT_Window)::DownCast(theWindow)->HWindow(), theTitle); #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) @@ -488,15 +485,13 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft // window fit in the small screens (actual for remote desktops, see #23003). // The position corresponds to the window's client area, thus some // gap is added for window frame to be visible. - Standard_Integer aPxLeft = 20; Standard_Integer aPxTop = 40; Standard_Integer aPxWidth = 409; Standard_Integer aPxHeight = 409; Standard_Boolean toCreateViewer = Standard_False; - - Handle(Graphic3d_GraphicDriver) aGraphicDriver; + Handle(OpenGl_GraphicDriver) aGraphicDriver; ViewerTest_Names aViewNames(theViewName); if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ())) aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName(ViewerTest_myViews, "View")); @@ -514,7 +509,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft if (!ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName())) { // Get connection string - #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) + #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) TCollection_AsciiString aDisplayName(theDisplayName); if (aDisplayName.IsEmpty()) SetDisplayConnection (new Aspect_DisplayConnection ()); @@ -524,13 +519,15 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft #else SetDisplayConnection (new Aspect_DisplayConnection ()); #endif - aGraphicDriver = Graphic3d::InitGraphicDriver (GetDisplayConnection()); + aGraphicDriver = new OpenGl_GraphicDriver(); + aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps; + aGraphicDriver->Begin (GetDisplayConnection()); ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver); toCreateViewer = Standard_True; } else { - aGraphicDriver = ViewerTest_myDrivers.Find1(aViewNames.GetDriverName()); + aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName())); } //Dispose the window if input parameters are default @@ -3776,41 +3773,74 @@ static int VFps (Draw_Interpretor& theDI, return 0; } +//============================================================================== +//function : VGlDebug +//purpose : +//============================================================================== + +static int VGlDebug (Draw_Interpretor& theDI, + Standard_Integer theArgNb, + const char** theArgVec) +{ + if (theArgNb < 2) + { + Handle(V3d_View) aView = ViewerTest::CurrentView(); + if (aView.IsNull()) + { + std::cerr << "No active view. Please call vinit.\n"; + return 0; + } + + Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS), + "GL_ARB_debug_output"); + std::cout << "Active graphic driver: debug " << (isActive ? "ON" : "OFF") << "\n"; + theDI << (isActive ? "1" : "0"); + return 0; + } + + ViewerTest_myDefaultCaps.contextDebug = Draw::Atoi (theArgVec[1]) != 0; + return 0; +} //============================================================================== //function : VVbo //purpose : //============================================================================== -static int VVbo (Draw_Interpretor& /*theDI*/, +static int VVbo (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { + const Standard_Boolean toSet = (theArgNb > 1); + const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1; + if (toSet) + { + ViewerTest_myDefaultCaps.vboDisable = toUseVbo; + } + // get the context Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext(); if (aContextAIS.IsNull()) { - std::cerr << "No active view. Please call vinit.\n"; + if (!toSet) + { + std::cerr << "No active view!\n"; + } return 1; } - - Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver(); - - if (aDriver.IsNull()) + Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver()); + if (!aDriver.IsNull()) { - std::cerr << "Graphic driver not available.\n"; - return 1; + if (!toSet) + { + theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n"; + } + else + { + aDriver->ChangeOptions().vboDisable = toUseVbo; + } } - if (theArgNb < 2) - { - //theDI << "VBO: " << aDriver->ToUseVBO() << "\n"; - //return 0; - std::cerr << "Wrong number of arguments.\n"; - return 1; - } - - aDriver->EnableVBO (Draw::Atoi(theArgVec[1]) != 0); return 0; } @@ -3832,7 +3862,6 @@ static int VMemGpu (Draw_Interpretor& theDI, } Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver(); - if (aDriver.IsNull()) { std::cerr << "Graphic driver not available.\n"; @@ -4860,8 +4889,13 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) theCommands.Add ("vfps", "vfps [framesNb=100] : estimate average frame rate for active view", __FILE__, VFps, group); + theCommands.Add ("vgldebug", + "vgldebug [{0|1}] : request debug GL context, should be called before vinit\n" + " : this function is implemented only for Windows\n" + " : GL_ARB_debug_output extension should be exported by OpenGL driver!", + __FILE__, VGlDebug, group); theCommands.Add ("vvbo", - "vvbo {0|1} : turn VBO usage On/Off; affects only newly displayed objects", + "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects", __FILE__, VVbo, group); theCommands.Add ("vmemgpu", "vmemgpu [f]: print system-dependent GPU memory information if available;"