FBCONFIG * ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs) { int pbSupport = QueryPbuffers(dpy, screen); #if defined(GLX_VERSION_1_3) if (pbSupport == 1) { return glXChooseFBConfig(dpy, screen, attribs, nConfigs); } #endif #if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) if (pbSupport == 2) { return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs); } #endif return NULL; }
FBCONFIG * GetAllFBConfigs(Display *dpy, int screen, int *nConfigs) { int pbSupport = QueryPbuffers(dpy, screen); #if defined(GLX_VERSION_1_3) if (pbSupport == 1) { return glXGetFBConfigs(dpy, screen, nConfigs); } #endif #if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) if (pbSupport == 2) { /* The GLX_SGIX_fbconfig extensions says to pass NULL to get list * of all available configurations. */ return glXChooseFBConfigSGIX(dpy, screen, NULL, nConfigs); } #endif return NULL; }
/** * 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; }
bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) { // Store the dimensions myWidth = width; myHeight = height; // Define the PBuffer attributes int visualAttributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, (depthBuffer ? 24 : 0), 0 }; int PBufferAttributes[] = { GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, 0 }; // Get the available FB configurations int nbConfigs = 0; GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs); if (!configs || !nbConfigs) { Err() << "Impossible to create render image (failed to find a suitable pixel format for PBuffer)" << std::endl; return false; } // Create the P-Buffer myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, configs[0], width, height, PBufferAttributes); if (!myPBuffer) { Err() << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl; XFree(configs); return false; } // Check the actual size of the P-Buffer unsigned int actualWidth, actualHeight; glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_WIDTH_SGIX, &actualWidth); glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_HEIGHT_SGIX, &actualHeight); if ((actualWidth != width) || (actualHeight != height)) { Err() << "Impossible to create render image (failed to match the requested size). " << "Size: " << actualWidth << "x" << actualHeight << " - " << "Requested: " << width << "x" << height << std::endl; XFree(configs); return false; } // We'll have to share the P-Buffer context with the current context GLXDrawable currentDrawable = glXGetCurrentDrawable(); GLXContext currentContext = glXGetCurrentContext(); if (currentContext) glXMakeCurrent(myDisplay, NULL, NULL); // Create the context XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]); myContext = glXCreateContext(myDisplay, visual, currentContext, true); if (!myContext) { Err() << "Impossible to create render image (failed to create the OpenGL context)" << std::endl; XFree(configs); XFree(visual); return false; } // Restore the previous active context if (currentContext) glXMakeCurrent(myDisplay, currentDrawable, currentContext); // Cleanup resources XFree(configs); XFree(visual); return true; }
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 }
/* * 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; }
/* * Create the pbuffer and return a GLXPbufferSGIX handle. */ static GLXPbufferSGIX MakePbuffer( Display *dpy, int screen, int width, int height ) { #define NUM_FB_CONFIGS 4 char fbString[NUM_FB_CONFIGS][100] = { "Single Buffered, depth buffer", "Double Buffered, depth buffer", "Single Buffered, no depth buffer", "Double Buffered, no depth buffer" }; int fbAttribs[NUM_FB_CONFIGS][100] = { { /* Single buffered, with depth buffer */ 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, 0, GLX_STENCIL_SIZE, 0, None }, { /* Double buffered, with depth buffer */ 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 }, { /* Single bufferd, without depth buffer */ 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, 0, GLX_DOUBLEBUFFER, 0, GLX_STENCIL_SIZE, 0, None }, { /* Double bufferd, without depth buffer */ 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, 0, GLX_DOUBLEBUFFER, 1, GLX_STENCIL_SIZE, 0, None } }; int pbAttribs[] = { GLX_LARGEST_PBUFFER_SGIX, True, GLX_PRESERVED_CONTENTS_SGIX, False, None }; GLXFBConfigSGIX *fbConfigs; GLXPbufferSGIX pBuffer = None; int nConfigs; int i; int attempt; for (attempt=0; attempt<NUM_FB_CONFIGS; attempt++) { /* Get list of possible frame buffer configurations */ fbConfigs = glXChooseFBConfigSGIX(dpy, screen, fbAttribs[attempt], &nConfigs); if (nConfigs==0 || !fbConfigs) { printf("Error: glxChooseFBConfigSGIX failed\n"); XCloseDisplay(dpy); return 0; } #ifdef DEBUG for (i=0;i<nConfigs;i++) { printf("Config %d\n", i); PrintFBConfigInfo(dpy, fbConfigs[i], 0); } #endif /* Create the pbuffer using first fbConfig in the list that works. */ for (i=0;i<nConfigs;i++) { pBuffer = CreatePbuffer(dpy, fbConfigs[i], width, height, pbAttribs); if (pBuffer) { gFBconfig = fbConfigs[i]; gWidth = width; gHeight = height; break; } } if (pBuffer!=None) { break; } } if (pBuffer) { printf("Using: %s\n", fbString[attempt]); } XFree(fbConfigs); return pBuffer; #undef NUM_FB_CONFIGS }