XVisualInfo * GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config) { int pbSupport = QueryPbuffers(dpy, screen); #if defined(GLX_VERSION_1_3) if (pbSupport == 1) { return glXGetVisualFromFBConfig(dpy, config); } #endif #if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) if (pbSupport == 2) { return glXGetVisualFromFBConfigSGIX(dpy, config); } #endif return NULL; }
void VolumeRendererShell::InitDisplay(int width, int height, bool fullScreen, float left, float right, float bottom, float top) { #ifdef SAGE // GLX context GLXContext glXContext; // GLX pbuffer GLXFBConfigSGIX glXFBConfig = 0; // X screen int xScreen = 0; // Open display _xDisplay = XOpenDisplay(NULL); if (!_xDisplay) { fprintf(stderr, "VolumeRendererShell: Could not open X display.\n"); return; } // Get default screen xScreen = DefaultScreen(_xDisplay); // Double buffered, with depth buffer int fbAttribs[] = { GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, 1, GLX_STENCIL_SIZE, 0, None }; // Attributes int pbAttribs[] = { GLX_LARGEST_PBUFFER_SGIX, True, GLX_PRESERVED_CONTENTS_SGIX, False, None }; // Possible configurations GLXFBConfigSGIX* glXFBConfigs = NULL; int numberOfGLXFBConfigs; // Get list of possible frame buffer configurations glXFBConfigs = glXChooseFBConfigSGIX(_xDisplay, xScreen, fbAttribs, &numberOfGLXFBConfigs); if (numberOfGLXFBConfigs == 0 || !glXFBConfigs) { fprintf(stderr, "VolumeRendererShell: Choosing FBConfig failed.\n"); XCloseDisplay(_xDisplay); return; } // Create pbuffer using first config in the list that works for (int i = 0 ; i < numberOfGLXFBConfigs ; i++) { // Catch X errors with error handler int (*oldHandler)(Display*, XErrorEvent*); oldHandler = XSetErrorHandler(HandleXError); _xErrorFlag = 0; // Create pbuffer _glXPBuffer = glXCreateGLXPbufferSGIX(_xDisplay, glXFBConfigs[i], width, height, pbAttribs); // Restore original X error handler (void) XSetErrorHandler(oldHandler); // Found a working configuration if (!_xErrorFlag && _glXPBuffer != None) { glXFBConfig = glXFBConfigs[i]; break; } } // Clean up XFree(glXFBConfigs); // If a pbuffer couldn't be created if (_glXPBuffer == None) { fprintf(stderr, "VolumeRendererShell: Couldn't create pbuffer.\n"); XCloseDisplay(_xDisplay); return; } // Get corresponding XVisualInfo _xVisualInfo = glXGetVisualFromFBConfigSGIX(_xDisplay, glXFBConfig); if (!_xVisualInfo) { fprintf(stderr, "VolumeRendererShell: Can't get XVisualInfo.\n"); XCloseDisplay(_xDisplay); return; } // Create GLX context glXContext = glXCreateContext(_xDisplay, _xVisualInfo, NULL, True); if (!glXContext) { glXContext = glXCreateContext(_xDisplay, _xVisualInfo, NULL, False); if (!glXContext) { fprintf(stderr, "VolumeRendererShell: Couldn't create GLXContext.\n"); XFree(_xVisualInfo); XCloseDisplay(_xDisplay); return; } } // Bind context to pbuffer if (!glXMakeCurrent(_xDisplay, _glXPBuffer, glXContext)) { fprintf(stderr, "VolumeRendererShell: glXMakeCurrent failed.\n"); XFree(_xVisualInfo); XCloseDisplay(_xDisplay); return; } #else // Initialize SDL SDL_Init(SDL_INIT_VIDEO); // Set video mode if (fullScreen == false) { SDL_SetVideoMode(width, height, 0, SDL_DOUBLEBUF | SDL_OPENGL); } else { SDL_SetVideoMode(width, height, 0, SDL_DOUBLEBUF | SDL_OPENGL | SDL_FULLSCREEN); SDL_ShowCursor(SDL_DISABLE); } SDL_WM_SetCaption("Volume Renderer", NULL); #endif }
GLXContext Window::createGLXContext( GLXFBConfig* fbConfig ) { if( !_impl->xDisplay ) { sendError( ERROR_GLXWINDOW_NO_DISPLAY ); return 0; } if( !fbConfig ) { sendError( ERROR_SYSTEMWINDOW_NO_PIXELFORMAT ); return 0; } GLXContext shCtx = 0; const SystemWindow* shareWindow = getSharedContextWindow(); if( shareWindow ) { const WindowIF* shareGLXWindow = dynamic_cast< const WindowIF* >( shareWindow ); if( shareGLXWindow ) shCtx = shareGLXWindow->getGLXContext(); #ifdef EQUALIZER_USE_QT5WIDGETS else if( dynamic_cast< const qt::WindowIF* >( shareWindow )) { // allows sharing with Qt window shareWindow->makeCurrent(); shCtx = glXGetCurrentContext(); } #endif } int type = GLX_RGBA_TYPE; if( getIAttribute( IATTR_HINT_DRAWABLE ) == PBUFFER && ( getIAttribute( IATTR_PLANES_COLOR ) == RGBA16F || getIAttribute( IATTR_PLANES_COLOR ) == RGBA32F )) { type = GLX_RGBA_FLOAT_TYPE; } GLXContext context = 0; if( glXCreateContextAttribsARB && getIAttribute( IATTR_HINT_CORE_PROFILE ) == ON ) { int attribList[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, getIAttribute( IATTR_HINT_OPENGL_MAJOR ), GLX_CONTEXT_MINOR_VERSION_ARB, getIAttribute( IATTR_HINT_OPENGL_MINOR ), GLX_RENDER_TYPE, type, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; context = glXCreateContextAttribsARB( _impl->xDisplay, fbConfig[0], shCtx, True, attribList ); } else { if( GLXEW_VERSION_1_3 ) context = glXCreateNewContext( _impl->xDisplay, fbConfig[0], type, shCtx, True ); else context = glXCreateContextWithConfigSGIX( _impl->xDisplay, fbConfig[0], type, shCtx, True ); } #ifdef Darwin // WAR http://xquartz.macosforge.org/trac/ticket/466 if( !context ) { XVisualInfo* visInfo = GLXEW_VERSION_1_3 ? glXGetVisualFromFBConfig( _impl->xDisplay, fbConfig[0] ) : glXGetVisualFromFBConfigSGIX( _impl->xDisplay, fbConfig[0] ); if( !visInfo ) { std::vector<int> attributes; attributes.push_back( GLX_RGBA ); attributes.push_back( GLX_RED_SIZE ); attributes.push_back( 1 ); attributes.push_back( GLX_ALPHA_SIZE ); attributes.push_back( 1 ); attributes.push_back( GLX_DEPTH_SIZE ); attributes.push_back( 1 ); attributes.push_back( GLX_DOUBLEBUFFER ); attributes.push_back( None ); const int screen = DefaultScreen( _impl->xDisplay ); visInfo = glXChooseVisual( _impl->xDisplay, screen, &attributes.front( )); if( !visInfo ) { sendError( ERROR_GLXWINDOW_NO_VISUAL ); return 0; } } context = glXCreateContext( _impl->xDisplay, visInfo, shCtx, True ); XFree( visInfo ); } #endif if( !context ) { sendError( ERROR_GLXWINDOW_CREATECONTEXT_FAILED ); return 0; } return context; }
XID Window::_createGLXWindow( GLXFBConfig* fbConfig, const PixelViewport& pvp ) { LBASSERT( getIAttribute( IATTR_HINT_DRAWABLE ) != PBUFFER ); if( !_impl->xDisplay ) { sendError( ERROR_GLXWINDOW_NO_DISPLAY ); return 0; } if( !fbConfig ) { sendError( ERROR_SYSTEMWINDOW_NO_PIXELFORMAT ); return 0; } XVisualInfo* visInfo = GLXEW_VERSION_1_3 ? glXGetVisualFromFBConfig( _impl->xDisplay, fbConfig[0] ) : glXGetVisualFromFBConfigSGIX( _impl->xDisplay, fbConfig[0]); if( !visInfo ) { sendError( ERROR_GLXWINDOW_NO_VISUAL ); return 0; } const int screen = DefaultScreen( _impl->xDisplay ); XID parent = RootWindow( _impl->xDisplay, screen ); XSetWindowAttributes wa; wa.colormap = XCreateColormap( _impl->xDisplay, parent, visInfo->visual, AllocNone ); wa.background_pixmap = None; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | VisibilityChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; switch( getIAttribute( IATTR_HINT_DECORATION )) { case ON: wa.override_redirect = False; break; case OFF: wa.override_redirect = True; break; case AUTO: default: wa.override_redirect = getIAttribute( IATTR_HINT_FULLSCREEN ) == ON ? True : False; break; } XID drawable = XCreateWindow( _impl->xDisplay, parent, pvp.x, pvp.y, pvp.w, pvp.h, 0, visInfo->depth, InputOutput, visInfo->visual, CWBackPixmap | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect, &wa ); XFree( visInfo ); if( !drawable ) { sendError( ERROR_GLXWINDOW_CREATEWINDOW_FAILED ); return 0; } std::stringstream windowTitle; const std::string& name = getName(); if( name.empty( )) { windowTitle << "Equalizer"; #ifndef NDEBUG windowTitle << " (" << getpid() << ")"; #endif } else windowTitle << name; XStoreName( _impl->xDisplay, drawable, windowTitle.str().c_str( )); // Register for close window request from the window manager Atom deleteAtom = XInternAtom( _impl->xDisplay, "WM_DELETE_WINDOW", False ); XSetWMProtocols( _impl->xDisplay, drawable, &deleteAtom, 1 ); return drawable; }
/* * Do all the X / GLX setup stuff. */ static int Setup(int width, int height) { #if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) XVisualInfo *visInfo; GLXContext glCtx; /* Open the X display */ gDpy = XOpenDisplay(NULL); if (!gDpy) { printf("Error: couldn't open default X display.\n"); return 0; } /* Get default screen */ gScreen = DefaultScreen(gDpy); /* Test that pbuffers are available */ if (!QueryPbuffers(gDpy, gScreen)) { printf("Error: pbuffers not available on this screen\n"); XCloseDisplay(gDpy); return 0; } /* Create Pbuffer */ gPBuffer = MakePbuffer( gDpy, gScreen, width, height ); if (gPBuffer==None) { printf("Error: couldn't create pbuffer\n"); XCloseDisplay(gDpy); return 0; } /* Get corresponding XVisualInfo */ visInfo = glXGetVisualFromFBConfigSGIX(gDpy, gFBconfig); if (!visInfo) { printf("Error: can't get XVisualInfo from FBconfig\n"); XCloseDisplay(gDpy); return 0; } /* Create GLX context */ glCtx = glXCreateContext(gDpy, visInfo, NULL, True); if (!glCtx) { /* try indirect */ glCtx = glXCreateContext(gDpy, visInfo, NULL, False); if (!glCtx) { printf("Error: Couldn't create GLXContext\n"); XFree(visInfo); XCloseDisplay(gDpy); return 0; } else { printf("Warning: using indirect GLXContext\n"); } } /* Bind context to pbuffer */ if (!glXMakeCurrent(gDpy, gPBuffer, glCtx)) { printf("Error: glXMakeCurrent failed\n"); XFree(visInfo); XCloseDisplay(gDpy); return 0; } return 1; /* Success!! */ #else printf("Error: GLX_SGIX_fbconfig and/or GLX_SGIX_pbuffer extensions not" " available at compile-time.\n"); return 0; #endif }