GLXContext CreateContext(Display *dpy, int screen, FBCONFIG config) { int pbSupport = QueryPbuffers(dpy, screen); #if defined(GLX_VERSION_1_3) if (pbSupport == 1) { /* GLX 1.3 */ GLXContext c; c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True); if (!c) { /* try indirect */ c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, False); } return c; } #endif #if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) if (pbSupport == 2) { GLXContext c; c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True); if (!c) { c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, False); } return c; } #endif return 0; }
/** * Tests for existence of the GLX_SGIX_pbuffer extension, * and creates an appropriate GLX pbuffer */ GLXPBuffer::GLXPBuffer(const int shadowMapSize, const bool sharedcontext, const bool shareobjects): m_pDisplay(0), m_glxPbuffer(0), m_glxContext(0), m_pOldDisplay(0), m_glxOldDrawable(0), m_glxOldContext(0), shadowMapSize(shadowMapSize), m_bSharedContext(sharedcontext), m_bShareObjects(shareobjects) { if (!GLX_SGIX_pbuffer) return; Display *pDisplay = glXGetCurrentDisplay(); int iScreen = DefaultScreen(pDisplay); GLXContext glxContext = glXGetCurrentContext(); int iConfigCount; GLXFBConfig *glxConfig; if (m_bSharedContext) glxConfig = glXGetFBConfigs(pDisplay, iScreen, &iConfigCount); else { int pf_attr[16] = { GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, 0 }; glxConfig = glXChooseFBConfigSGIX(pDisplay, iScreen, pf_attr, &iConfigCount); } if (!glxConfig) return; int pb_attr[16] = { GLX_LARGEST_PBUFFER, false, GLX_PRESERVED_CONTENTS, true, 0 }; m_glxPbuffer = glXCreateGLXPbufferSGIX(pDisplay, glxConfig[0], shadowMapSize, shadowMapSize, pb_attr); if (!m_glxPbuffer) return; if (m_bSharedContext) m_glxContext = glxContext; else { m_glxContext = glXCreateContextWithConfigSGIX(pDisplay, glxConfig[0], GLX_RGBA_TYPE, (m_bShareObjects?glxContext:NULL), true); if (!glxConfig) return; } m_pDisplay = pDisplay; }
/* * constructor (linux specific) */ PBuffer::PBuffer(int width,int height,int flags) : width(width), height(height), data(NULL) { Display *display = glXGetCurrentDisplay(); int screen = DefaultScreen(display); GLXContext old_context = glXGetCurrentContext(); std::vector<int> attrib; attrib.push_back(GLX_RENDER_TYPE); attrib.push_back(GLX_RGBA_BIT); attrib.push_back(GLX_DRAWABLE_TYPE); attrib.push_back(GLX_PBUFFER_BIT); if(flags & GEM_PBUFLAG_RGB || flags & GEM_PBUFLAG_RGBA) { attrib.push_back(GLX_RED_SIZE); attrib.push_back(flags & GEM_PBUFLAG_FLOAT ? 32 : 8); attrib.push_back(GLX_GREEN_SIZE); attrib.push_back(flags & GEM_PBUFLAG_FLOAT ? 32 : 8); attrib.push_back(GLX_BLUE_SIZE); attrib.push_back(flags & GEM_PBUFLAG_FLOAT ? 32 : 8); if(flags & GEM_PBUFLAG_RGBA) { attrib.push_back(GLX_ALPHA_SIZE); attrib.push_back(flags & GEM_PBUFLAG_FLOAT ? 32 : 8); } } if(flags & GEM_PBUFLAG_DEPTH) { attrib.push_back(GLX_DEPTH_SIZE); attrib.push_back(24); } if(flags & GEM_PBUFLAG_STENCIL) { attrib.push_back(GLX_STENCIL_SIZE); attrib.push_back(8); } if(flags & GEM_PBUFLAG_FLOAT) { attrib.push_back(GLX_FLOAT_COMPONENTS_NV); attrib.push_back(true); } if(flags & GEM_PBUFLAG_MULTISAMPLE_2 || flags & GEM_PBUFLAG_MULTISAMPLE_4) { attrib.push_back(GLX_SAMPLE_BUFFERS_ARB); attrib.push_back(true); attrib.push_back(GLX_SAMPLES_ARB); attrib.push_back(flags & GEM_PBUFLAG_MULTISAMPLE_2 ? 2 : 4); } attrib.push_back(0); std::vector<int> pattrib; pattrib.push_back(GLX_LARGEST_PBUFFER); pattrib.push_back(true); pattrib.push_back(GLX_PRESERVED_CONTENTS); pattrib.push_back(true); GLXPbuffer pbuffer; GLXContext context; try { int count; GLXFBConfig *config; if(GLXEW_SGIX_fbconfig && GLXEW_SGIX_pbuffer) { debug("using SGIX pbuffers\n"); pattrib.push_back(0); config = glXChooseFBConfigSGIX(display,screen,&attrib[0],&count); if(!config) throw("glXChooseFBConfigSGIX() failed"); pbuffer = glXCreateGLXPbufferSGIX(display,config[0],width,height,&pattrib[0]); if(!pbuffer) throw("glXCreateGLXPbufferSGIX() failed"); context = glXCreateContextWithConfigSGIX(display,config[0],GLX_RGBA_TYPE,old_context,true); if(!context) throw("glXCreateContextWithConfigSGIX() failed"); } else if (NULL!=glXChooseFBConfig) { /* LATER make a better check! */ debug("using GLX pbuffers"); pattrib.push_back(GLX_PBUFFER_WIDTH); pattrib.push_back(width); pattrib.push_back(GLX_PBUFFER_HEIGHT); pattrib.push_back(height); pattrib.push_back(0); config = glXChooseFBConfig(display,screen,&attrib[0],&count); if(!config) throw("glXChooseFBConfig() failed"); pbuffer = glXCreatePbuffer(display,config[0],&pattrib[0]); if(!pbuffer) throw("glXCreatePbuffer() failed"); XVisualInfo *visual = glXGetVisualFromFBConfig(display,config[0]); if(!visual) throw("glXGetVisualFromFBConfig() failed"); context = glXCreateContext(display,visual,old_context,true); if(!context) throw("glXCreateContext() failed"); } else { throw("your system lacks PBuffer support!"); } } catch(const char *err) { error("PBuffer::PBuffer(): %s",err); pbuffer = glXGetCurrentDrawable(); context = old_context; } data = new PBuffer_data; data->display = display; data->pbuffer = pbuffer; data->context = context; data->old_pbuffer = glXGetCurrentDrawable(); data->old_context = old_context; }
/* ARGSUSED5 */ /* Only Win32 uses gameMode parameter. */ GLUTwindow * __glutCreateWindow(GLUTwindow * parent, int x, int y, int width, int height, int gameMode) { GLUTwindow *window; XSetWindowAttributes wa; unsigned long attribMask; int winnum; int i; #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) GLXFBConfigSGIX fbc; #else void *fbc; #endif #if defined(_WIN32) WNDCLASS wc; int style; int pixelFormat; if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) { __glutOpenWin32Connection(NULL); } #else if (!__glutDisplay) { __glutOpenXConnection(NULL); } #endif if (__glutGameModeWindow) { __glutFatalError("cannot create windows in game mode."); } winnum = getUnusedWindowSlot(); window = (GLUTwindow *) malloc(sizeof(GLUTwindow)); if (!window) { __glutFatalError("out of memory."); } window->num = winnum; #if !defined(_WIN32) window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, &window->visAlloced, (void**) &fbc); if (!window->vis) { __glutFatalError( "visual with necessary capabilities not found."); } __glutSetupColormap(window->vis, &window->colormap, &window->cmap); #endif window->eventMask = StructureNotifyMask | ExposureMask; attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; wa.background_pixmap = None; wa.border_pixel = 0; wa.colormap = window->cmap; wa.event_mask = window->eventMask; if (parent) { if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) { wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK; } attribMask |= CWDontPropagate; wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; } else { wa.do_not_propagate_mask = 0; } /* Stash width and height before Win32's __glutAdjustCoords possibly overwrites the values. */ window->width = width; window->height = height; window->forceReshape = True; window->ignoreKeyRepeat = False; #if defined(_WIN32) __glutAdjustCoords(parent ? parent->win : NULL, &x, &y, &width, &height); if (parent) { style = WS_CHILD; } else { if (gameMode) { /* Game mode window should be a WS_POPUP window to ensure that the taskbar is hidden by it. A standard WS_OVERLAPPEDWINDOW does not hide the task bar. */ style = WS_POPUP | WS_MAXIMIZE; } else { /* A standard toplevel window with borders and such. */ style = WS_OVERLAPPEDWINDOW; } } window->win = CreateWindow("GLUT", "GLUT", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, x, y, width, height, parent ? parent->win : __glutRoot, NULL, GetModuleHandle(NULL), 0); window->hdc = GetDC(window->win); /* Must set the XHDC for fake glXChooseVisual & fake glXCreateContext & fake XAllocColorCells. */ XHDC = window->hdc; window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, &window->visAlloced, &fbc); if (!window->vis) { __glutFatalError( "pixel format with necessary capabilities not found."); } pixelFormat = window->vis->num; if (pixelFormat == 0) { __glutFatalError("ChoosePixelFormat failed during window create."); } if (!SetPixelFormat(window->hdc, pixelFormat, &window->vis->pfd)) { __glutFatalError("SetPixelFormat failed during window create."); } __glutSetupColormap(window->vis, &window->colormap, &window->cmap); /* Make sure subwindows get a windowStatus callback. */ if (parent) { PostMessage(parent->win, WM_ACTIVATE, 0, 0); } window->renderDc = window->hdc; #else /* X Window System */ window->win = XCreateWindow(__glutDisplay, parent == NULL ? __glutRoot : parent->win, x, y, width, height, 0, window->vis->depth, InputOutput, window->vis->visual, attribMask, &wa); #endif window->renderWin = window->win; #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) if (fbc) { window->ctx = glXCreateContextWithConfigSGIX(__glutDisplay, fbc, GLX_RGBA_TYPE_SGIX, None, __glutTryDirect); } else #endif { #ifdef _WIN32 window->ctx = wglCreateContext(window->hdc); #else window->ctx = glXCreateContext(__glutDisplay, window->vis, None, __glutTryDirect); #endif } if (!window->ctx) { __glutFatalError( "failed to create OpenGL rendering context."); } window->renderCtx = window->ctx; #if !defined(_WIN32) window->isDirect = glXIsDirect(__glutDisplay, window->ctx); if (__glutForceDirect) { if (!window->isDirect) { __glutFatalError("direct rendering not possible."); } } #endif window->parent = parent; if (parent) { window->siblings = parent->children; parent->children = window; } else { window->siblings = NULL; } window->overlay = NULL; window->children = NULL; window->display = defaultDisplay; window->reshape = __glutDefaultReshape; window->mouse = NULL; window->motion = NULL; window->passive = NULL; window->entry = NULL; window->keyboard = NULL; window->keyboardUp = NULL; window->windowStatus = NULL; window->visibility = NULL; window->special = NULL; window->specialUp = NULL; window->buttonBox = NULL; window->dials = NULL; window->spaceMotion = NULL; window->spaceRotate = NULL; window->spaceButton = NULL; window->tabletMotion = NULL; window->tabletButton = NULL; #ifdef _WIN32 window->joystick = NULL; window->joyPollInterval = 0; #endif window->tabletPos[0] = -1; window->tabletPos[1] = -1; window->shownState = 0; window->visState = -1; /* not VisibilityUnobscured, VisibilityPartiallyObscured, or VisibilityFullyObscured */ window->entryState = -1; /* not EnterNotify or LeaveNotify */ window->desiredConfMask = 0; window->buttonUses = 0; window->cursor = GLUT_CURSOR_INHERIT; /* Setup window to be mapped when glutMainLoop starts. */ window->workMask = GLUT_MAP_WORK; #ifdef _WIN32 if (gameMode) { /* When mapping a game mode window, just show the window. We have already created the game mode window with a maximize flag at creation time. Doing a ShowWindow(window->win, SW_SHOWNORMAL) would be wrong for a game mode window since it would unmaximize the window. */ window->desiredMapState = GameModeState; } else { window->desiredMapState = NormalState; } #else window->desiredMapState = NormalState; #endif window->prevWorkWin = __glutWindowWorkList; __glutWindowWorkList = window; /* Initially, no menus attached. */ for (i = 0; i < GLUT_MAX_MENUS; i++) { window->menu[i] = 0; } /* Add this new window to the window list. */ __glutWindowList[winnum] = window; /* Make the new window the current window. */ __glutSetWindow(window); __glutDetermineMesaSwapHackSupport(); if (window->treatAsSingle) { /* We do this because either the window really is single buffered (in which case this is redundant, but harmless, because this is the initial single-buffered context state); or we are treating a double buffered window as a single-buffered window because the system does not appear to export any suitable single- buffered visuals (in which the following are necessary). */ glDrawBuffer(GL_FRONT); glReadBuffer(GL_FRONT); } return window; }
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; }