Esempio n. 1
0
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;
}
Esempio n. 2
0
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

}
Esempio n. 6
0
/*
 * 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;
}
Esempio n. 7
0
/*
 * 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
}