From 8926f0e9c253a1781e6cdbde96ec467324bb105c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 21 Aug 2017 11:40:45 +0100 Subject: [PATCH] Using a PR from Sando Mani for requestioning a specific GL version as a base, cleaned up formattating, made the new code paths simpler and added clean up of memory --- include/osgViewer/api/X11/GraphicsWindowX11 | 2 + src/osgViewer/GraphicsWindowX11.cpp | 77 ++++++++++++++++++--- src/osgViewer/StatsHandler.cpp | 6 -- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 9086bda1e..1efb990fe 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -37,6 +37,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub _parent(0), _window(0), _visualInfo(0), + _fbConfig(0), #ifdef OSG_USE_EGL _eglDisplay(0), _eglSurface(0), @@ -176,6 +177,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub Window _parent; Window _window; XVisualInfo* _visualInfo; + GLXFBConfig _fbConfig; #ifdef OSG_USE_EGL EGLDisplay _eglDisplay; diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 02729a8dd..a6eccfef6 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -43,6 +43,7 @@ #endif #include +#include using namespace osgViewer; @@ -326,13 +327,10 @@ bool GraphicsWindowX11::createVisualInfo() typedef std::vector Attributes; Attributes attributes; - attributes.push_back(GLX_USE_GL); + attributes.push_back(GLX_RENDER_TYPE); attributes.push_back(GLX_RGBA_BIT); - attributes.push_back(GLX_RGBA); - - if (_traits->doubleBuffer) attributes.push_back(GLX_DOUBLEBUFFER); - - if (_traits->quadBufferStereo) attributes.push_back(GLX_STEREO); + if (_traits->doubleBuffer) { attributes.push_back(GLX_DOUBLEBUFFER); attributes.push_back(True); } + if (_traits->quadBufferStereo) { attributes.push_back(GLX_STEREO); attributes.push_back(True); } attributes.push_back(GLX_RED_SIZE); attributes.push_back(_traits->red); attributes.push_back(GLX_GREEN_SIZE); attributes.push_back(_traits->green); @@ -340,14 +338,11 @@ bool GraphicsWindowX11::createVisualInfo() attributes.push_back(GLX_DEPTH_SIZE); attributes.push_back(_traits->depth); if (_traits->alpha) { attributes.push_back(GLX_ALPHA_SIZE); attributes.push_back(_traits->alpha); } - if (_traits->stencil) { attributes.push_back(GLX_STENCIL_SIZE); attributes.push_back(_traits->stencil); } #if defined(GLX_SAMPLE_BUFFERS) && defined (GLX_SAMPLES) - if (_traits->sampleBuffers) { attributes.push_back(GLX_SAMPLE_BUFFERS); attributes.push_back(_traits->sampleBuffers); } if (_traits->samples) { attributes.push_back(GLX_SAMPLES); attributes.push_back(_traits->samples); } - #endif // TODO // GLX_AUX_BUFFERS @@ -356,7 +351,16 @@ bool GraphicsWindowX11::createVisualInfo() attributes.push_back(None); - _visualInfo = glXChooseVisual( _display, _traits->screenNum, &(attributes.front()) ); + int numFbConfigs = 0; + GLXFBConfig* fbConfigs = glXChooseFBConfig(_display, _traits->screenNum, attributes.data(), &numFbConfigs); + if (numFbConfigs > 0) + { + _fbConfig = fbConfigs[0]; + } + + XFree(fbConfigs); + + _visualInfo = glXGetVisualFromFBConfig(_display, _fbConfig); #endif } @@ -893,7 +897,58 @@ void GraphicsWindowX11::init() #else - _context = glXCreateContext( _display, _visualInfo, sharedContext, True ); + typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + + const char* glx_str = glXQueryExtensionsString(_display, _traits->screenNum); + std::string glx_string; if (glx_str) glx_string = glx_str; + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + if (glx_string.find("GLX_ARB_create_context")!=std::string::npos) + { + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + } + + bool supportsProfiles = glx_string.find("GLX_ARB_create_context")!=std::string::npos; + + + if (glXCreateContextAttribsARB) + { + OSG_INFO << "Attempting to create GL context:" << std::endl; + OSG_INFO << " * version: " << _traits->glContextVersion << std::endl; + OSG_INFO << " * context flags: " << _traits->glContextFlags << std::endl; + OSG_INFO << " * profile: " << _traits->glContextProfileMask << std::endl; + + std::vector contextAttributes; + + std::size_t pos = _traits->glContextVersion.find("."); + int majorVersion = std::atoi(_traits->glContextVersion.substr(0, pos).c_str()); + int minorVersion = pos == std::string::npos ? 0 : std::atoi(_traits->glContextVersion.substr(pos + 1).c_str()); + + contextAttributes.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB); + contextAttributes.push_back(majorVersion); + contextAttributes.push_back(GLX_CONTEXT_MINOR_VERSION_ARB); + contextAttributes.push_back(minorVersion); + + // If asking for OpenGL 3.2 or newer we should also specify a profile + float glVersion = static_cast(majorVersion)+static_cast(minorVersion)*0.1f; + if (glVersion>=3.2 && supportsProfiles && _traits->glContextProfileMask != 0) + { + contextAttributes.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); + contextAttributes.push_back(_traits->glContextProfileMask); + } + if (_traits->glContextFlags != 0) + { + contextAttributes.push_back(GLX_CONTEXT_FLAGS_ARB); + contextAttributes.push_back(_traits->glContextFlags); + } + contextAttributes.push_back(None); + + _context = glXCreateContextAttribsARB( _display, _fbConfig, sharedContext, True, contextAttributes.data() ); + } + else + { + _context = glXCreateContext( _display, _visualInfo, sharedContext, True ); + } if (!_context) { diff --git a/src/osgViewer/StatsHandler.cpp b/src/osgViewer/StatsHandler.cpp index 48c514d84..665ce4acf 100644 --- a/src/osgViewer/StatsHandler.cpp +++ b/src/osgViewer/StatsHandler.cpp @@ -767,12 +767,6 @@ struct BlockDrawCallback : public virtual osg::Drawable::DrawCallback vertices->dirty(); - osg::DrawArrays* drawArrays = dynamic_cast(geom->getPrimitiveSet(0)); - if(drawArrays) - { - drawArrays->setCount(vi); - } - drawable->drawImplementation(renderInfo); }