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)
// 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 <stdio.h>
+#include <stdio.h>
-# include <X11/Xlib.h>
-# include <X11/Xutil.h>
-# include <X11/Xatom.h>
-# include <GL/glx.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <GL/glx.h>
-# if defined (sun) || defined (SUNOS) || defined (__alpha) || defined (DECOSF1) || defined (sgi) || defined (IRIX) || defined (__hpux)|| defined (HPUX)
-# ifndef icon_width
-# include <X11/bitmaps/icon>
-# endif
+#if defined (sun) || defined (SUNOS) || defined (__alpha) || defined (DECOSF1) || defined (sgi) || defined (IRIX) || defined (__hpux)|| defined (HPUX)
+ #ifndef icon_width
+ #include <X11/bitmaps/icon>
+ #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 // ULTRIX
-# endif /* SUNOS or DECOSF1 or SOLARIS or HPUX or IRIX */
+// workaround name conflicts with OCCT methods (in class TopoDS_Shape for example)
+#ifdef Convex
+ #undef Convex
+#endif
+#ifdef Status
+ #undef Status
+#endif
-# ifdef ULTRIX
+#define WINDOW Window
+#define DISPLAY Display
+#define GLCONTEXT GLXContext
+#define GLDRAWABLE GLXDrawable
-# ifndef icon_width
-/* le contenu de #include <X11/bitmaps/icon> 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,
- 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0,
- 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xff, 0xff};
-# endif
-
-# endif /* ULTRIX */
-# define WINDOW Window
-# define DISPLAY Display
-# define GLCONTEXT GLXContext
-# define GLDRAWABLE GLXDrawable
-
-# 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 /* 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
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
OpenGl_ArbIns.hxx
OpenGl_ArbTBO.hxx
OpenGl_ArbVBO.hxx
+OpenGl_ArbDbg.hxx
OpenGl_ExtFBO.hxx
OpenGl_ExtGS.hxx
glext.h
--- /dev/null
+// 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 <OpenGl_GlCore12.hxx>
+
+//! Debug context routines
+struct OpenGl_ArbDbg
+{
+
+ PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
+ PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
+ PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
+ PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
+
+};
+
+#endif // _OpenGl_ArbDbg_H__
--- /dev/null
+// 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 <OpenGl_Caps.hxx>
+
+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()
+{
+ //
+}
--- /dev/null
+// 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 <Standard_DefineHandle.hxx>
+#include <Standard_Transient.hxx>
+#include <Handle_Standard_Transient.hxx>
+
+//! 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__
// 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 <windows.h>
#endif
#include <OpenGl_ArbVBO.hxx>
#include <OpenGl_ArbTBO.hxx>
#include <OpenGl_ArbIns.hxx>
+#include <OpenGl_ArbDbg.hxx>
#include <OpenGl_ExtFBO.hxx>
#include <OpenGl_ExtGS.hxx>
#include <OpenGl_GlCore20.hxx>
#include <Standard_ProgramError.hxx>
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
//
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
#include <dlfcn.h>
// 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),
delete myGlCore20;
delete arbVBO;
+ delete arbTBO;
+ delete arbIns;
+ delete arbDbg;
delete extFBO;
delete extGS;
}
// =======================================================================
Standard_Boolean OpenGl_Context::IsCurrent() const
{
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
if (myWindowDC == NULL || myGContext == NULL)
{
return Standard_False;
// =======================================================================
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!");
// =======================================================================
void OpenGl_Context::SwapBuffers()
{
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
if ((HDC )myWindowDC != NULL)
{
::SwapBuffers ((HDC )myWindowDC);
// =======================================================================
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;
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
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, " ");
return Standard_True;
}
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
myWindowDC = (Aspect_Handle )wglGetCurrentDC();
myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
#else
// 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)
#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;
}
}
+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 :
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"))
{
#include <NCollection_DataMap.hxx>
#include <NCollection_Handle.hxx>
#include <NCollection_Queue.hxx>
+#include <OpenGl_Caps.hxx>
#include <OpenGl_Resource.hxx>
#include <Standard_Transient.hxx>
#include <TCollection_AsciiString.hxx>
struct OpenGl_ArbVBO;
struct OpenGl_ArbTBO;
struct OpenGl_ArbIns;
+struct OpenGl_ArbDbg;
struct OpenGl_ExtFBO;
struct OpenGl_ExtGS;
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();
//! 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);
//! 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.
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
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
namespace
{
- // Global switch - shared by whole TKOpenGl module. To be removed.
- static Standard_Boolean TheToUseVbo = Standard_True;
-
static const Handle(OpenGl_Context) TheNullGlCtx;
};
// =======================================================================
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()),
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;
}
// =======================================================================
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 ();
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.
private:
+ Handle(OpenGl_Caps) myCaps;
NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)> myMapOfView;
NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)> myMapOfWS;
NCollection_DataMap<Standard_Integer, OpenGl_Structure*> myMapOfStructure;
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);
}
}
// 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;
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);
}
{
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)
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),
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;
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);
}
// 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();
// =======================================================================
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;
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
if (!Activate())
return;
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
RECT cr;
GetClientRect ((HWND )myGlContext->myWindow, &cr);
myWidth = cr.right - cr.left;
#include <OpenGl_GlCore11.hxx>
#include <InterfaceGraphic_Aspect.hxx>
+#include <OpenGl_Caps.hxx>
#include <Handle_OpenGl_Context.hxx>
#include <Handle_OpenGl_Display.hxx>
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
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),
#include <Graphic3d_TextureParams.hxx>
-#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
+#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
#include <OpenGl_AVIWriter.hxx>
#endif
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),
//
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
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;
}
if (theArgNb < 2)
{
- //theDI << "VBO: " << aDriver->ToUseVBO() << "\n";
- //return 0;
std::cerr << "Wrong number of arguments.\n";
return 1;
}
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;
}
# include <config.h>
#endif
-#ifdef WNT
-#include <windows.h>
-#endif
-
+#include <OpenGl_GlCore20.hxx>
#include <AIS_Shape.hxx>
#include <AIS_Drawer.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
#include <DBRep.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
-#include <Graphic3d_GraphicDriver.hxx>
#include <Graphic3d_ExportFormat.hxx>
#include <Graphic3d_NameOfTextureEnv.hxx>
#include <Graphic3d_TextureEnv.hxx>
#include <Draw_Appli.hxx>
#include <Aspect_PrintAlgo.hxx>
#include <Image_AlienPixMap.hxx>
+#include <OpenGl_GraphicDriver.hxx>
#include <OSD_Timer.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_HSequenceOfReal.hxx>
#include <Visual3d_Layer.hxx>
#include <cstdlib>
-#if defined(_WIN32) || defined(__WIN32__)
+#if defined(_WIN32)
#include <WNT_WClass.hxx>
#include <WNT_Window.hxx>
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;
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();
static Standard_Boolean MyHLRIsOn = Standard_False;
NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
-static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
+static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
-
+static OpenGl_Caps ViewerTest_myDefaultCaps;
#define ZCLIPWIDTH 1.
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,
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)
// 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<Handle(V3d_View)>(ViewerTest_myViews, "View"));
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 ());
#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
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)
{
- // get the context
- Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
- if (aContextAIS.IsNull())
+ const Standard_Boolean toSet = (theArgNb > 1);
+ const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
+ if (toSet)
{
- std::cerr << "No active view. Please call vinit.\n";
- return 1;
+ ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
}
- Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
-
- if (aDriver.IsNull())
+ // get the context
+ Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
+ if (aContextAIS.IsNull())
{
- std::cerr << "Graphic driver not available.\n";
+ if (!toSet)
+ {
+ std::cerr << "No active view!\n";
+ }
return 1;
}
-
- if (theArgNb < 2)
+ Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
+ if (!aDriver.IsNull())
{
- //theDI << "VBO: " << aDriver->ToUseVBO() << "\n";
- //return 0;
- std::cerr << "Wrong number of arguments.\n";
- return 1;
+ if (!toSet)
+ {
+ theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
+ }
+ else
+ {
+ aDriver->ChangeOptions().vboDisable = toUseVbo;
+ }
}
- aDriver->EnableVBO (Draw::Atoi(theArgVec[1]) != 0);
return 0;
}
}
Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
-
if (aDriver.IsNull())
{
std::cerr << "Graphic driver not available.\n";
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;"