예제 #1
0
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

}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
/*
 * 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
}