/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ /* Note, elements of PixelBufferX11 have used Prodcer/RenderSurface_X11.cpp as both * a guide to use of X11/GLX and copiying directly in the case of setBorder(). * These elements are license under OSGPL as above, with Copyright (C) 2001-2004 Don Burns. */ #include #include #include #include using namespace osgViewer; static GLXFBConfig getFBConfigFromVisual(::Display* dpy, XVisualInfo* visualInfo) { #if defined(__APPLE__) || defined(_AIX) int screen = visualInfo->screen; int nelements; GLXFBConfig *configs = glXGetFBConfigs(dpy, screen, &nelements); for( int i = 0; i < nelements; i++ ) { int visual_id; if( glXGetFBConfigAttrib( dpy, configs[i], GLX_VISUAL_ID, &visual_id ) == 0 ) { if( (unsigned int)visual_id == visualInfo->visualid ) return configs[i]; } } return NULL; #else return glXGetFBConfigFromVisualSGIX( dpy, visualInfo ); #endif } PixelBufferX11::~PixelBufferX11() { close(true); } bool PixelBufferX11::createVisualInfo() { typedef std::vector Attributes; Attributes attributes; attributes.push_back(GLX_USE_GL); attributes.push_back(GLX_RGBA); if (_traits->doubleBuffer) attributes.push_back(GLX_DOUBLEBUFFER); attributes.push_back(GLX_RED_SIZE); attributes.push_back(_traits->red); attributes.push_back(GLX_GREEN_SIZE); attributes.push_back(_traits->green); attributes.push_back(GLX_BLUE_SIZE); attributes.push_back(_traits->blue); 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->sampleBuffers) { attributes.push_back(GLX_SAMPLES); attributes.push_back(_traits->samples); } #endif // TODO // GLX_AUX_BUFFERS // GLX_ACCUM_RED_SIZE // GLX_ACCUM_GREEN_SIZE attributes.push_back(None); _visualInfo = glXChooseVisual( _display, _traits->screenNum, &(attributes.front()) ); return _visualInfo != 0; } void PixelBufferX11::init() { if (_initialized) return; #ifdef GLX_VERSION_1_3 if (!_traits) { _valid = false; return; } if (_traits->target != 0) { // we don't support Pbuffer render to texture under GLX. _valid = false; return; } _display = XOpenDisplay(_traits->displayName().c_str()); unsigned int screen = _traits->screenNum; if (!_display) { osg::notify(osg::NOTICE)<<"Error: Unable to open display \"" << XDisplayName(_traits->displayName().c_str()) << "\"."<displayName().c_str()) <<" has no GLX extension." << std::endl; XCloseDisplay( _display ); _display = 0; _valid = false; return; } // osg::notify(osg::NOTICE)<<"GLX extension, errorBase="<(_traits->sharedContext); if (graphicsWindowX11) { sharedContextGLX = graphicsWindowX11->getGLXContext(); } else { PixelBufferX11* pixelBufferX11 = dynamic_cast(_traits->sharedContext); if (pixelBufferX11) { sharedContextGLX = pixelBufferX11->getGLXContext(); } } _glxContext = glXCreateContext( _display, _visualInfo, sharedContextGLX, True ); if (!_glxContext) { osg::notify(osg::NOTICE)<<"Error: Unable to create OpenGL graphics context."<visual, AllocNone); //swatt.colormap = DefaultColormap( _dpy, 10 ); swatt.background_pixel = 0; swatt.border_pixel = 0; swatt.event_mask = 0; unsigned long mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; bool overrideRedirect = false; if (overrideRedirect) { swatt.override_redirect = true; mask |= CWOverrideRedirect; } GLXFBConfig fbconfig = getFBConfigFromVisual( _display, _visualInfo ); typedef std::vector AttributeList; AttributeList attributes; attributes.push_back( GLX_PBUFFER_WIDTH ); attributes.push_back( _traits->width ); attributes.push_back( GLX_PBUFFER_HEIGHT ); attributes.push_back( _traits->height ); attributes.push_back( 0L ); _pbuffer = glXCreatePbuffer(_display, fbconfig, &attributes.front() ); if (!_pbuffer) { osg::notify(osg::NOTICE)<<"Error: Unable to create Window."<