Ejemplo n.º 1
0
static GLint getInternalFormat(void)
{
  switch (glctx.type) {
#ifdef CONFIG_GL_WIN32
  case GLTYPE_W32:
  {
  PIXELFORMATDESCRIPTOR pfd;
  HDC vo_hdc = vo_w32_get_dc(vo_w32_window);
  int pf = GetPixelFormat(vo_hdc);
  if (!DescribePixelFormat(vo_hdc, pf, sizeof pfd, &pfd)) {
    r_sz = g_sz = b_sz = a_sz = 0;
  } else {
    r_sz = pfd.cRedBits;
    g_sz = pfd.cGreenBits;
    b_sz = pfd.cBlueBits;
    a_sz = pfd.cAlphaBits;
  }
  vo_w32_release_dc(vo_w32_window, vo_hdc);
  }
  break;
#endif
#ifdef CONFIG_GL_X11
  case GLTYPE_X11:
  if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_RED_SIZE, &r_sz) != 0) r_sz = 0;
  if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_GREEN_SIZE, &g_sz) != 0) g_sz = 0;
  if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_BLUE_SIZE, &b_sz) != 0) b_sz = 0;
  if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_ALPHA_SIZE, &a_sz) != 0) a_sz = 0;
  break;
#endif
  }

  rgb_sz=r_sz+g_sz+b_sz;
  if(rgb_sz<=0) rgb_sz=24;

#ifdef TEXTUREFORMAT_ALWAYS
  return TEXTUREFORMAT_ALWAYS;
#else
  if(r_sz==3 && g_sz==3 && b_sz==2 && a_sz==0)
    return GL_R3_G3_B2;
  if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==0)
    return GL_RGB4;
  if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==0)
    return GL_RGB5;
  if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==0)
    return GL_RGB8;
  if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==0)
    return GL_RGB10;
  if(r_sz==2 && g_sz==2 && b_sz==2 && a_sz==2)
    return GL_RGBA2;
  if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==4)
    return GL_RGBA4;
  if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==1)
    return GL_RGB5_A1;
  if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==8)
    return GL_RGBA8;
  if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==2)
    return GL_RGB10_A2;
#endif
  return GL_RGB;
}
Ejemplo n.º 2
0
static int
checkOverlayAcceptability( XVisualInfo *vi, unsigned int mode )
{
	t_winstruct *window = &C3D_win;
	int value;
	
	/* Must support OpenGL */
	glXGetConfig( window->dpy, vi, GLX_USE_GL, &value );
	if ( !value )
		return 1;

	/* Must be color-index .*/
	glXGetConfig( window->dpy, vi, GLX_RGBA, &value );
	if ( value )
		return 1;
	
	
	/* Must match single/double buffering request. */
	glXGetConfig( window->dpy, vi, GLX_DOUBLEBUFFER, &value );
	if ( C3D_WIND_IS_DOUBLE( window->display_mode) != ( value != 0 ))
		return 1;
	
	/* Must match mono/stereo request */
	glXGetConfig( window->dpy, vi, GLX_STEREO, &value );
	if ( C3D_WIND_IS_STEREO(mode) != (value != 0))
		return 1;


	return 0;
}
Ejemplo n.º 3
0
//================================================================
  void*  GLB_Create () {
//================================================================
/// GLB_Create            create opengl-window (used by GUI_gl__)
 
  GtkWidget   *area;
  int         xscreen, i1;
  GdkScreen   *screen;
  GdkVisual   *visual;
  Window      root;
  XVisualInfo *xvisual;
  Colormap    xcolormap;
  int         attributes[] = {
                GLX_RGBA,
                GLX_RED_SIZE, 1,
                GLX_GREEN_SIZE, 1,
                GLX_BLUE_SIZE, 1,
                GLX_DOUBLEBUFFER, True,
                GLX_DEPTH_SIZE, 24,
                None };

  GLB_x_id = 0;   // reset

  area = gtk_drawing_area_new ();
  gtk_widget_set_double_buffered (area, FALSE);

  GLB_display = gdk_x11_get_default_xdisplay ();
  xscreen = DefaultScreen (GLB_display);
  screen = gdk_screen_get_default ();
    // printf(" screenNr = %d\n",gdk_screen_get_number(screen));

  xvisual = glXChooseVisual (GLB_display, xscreen, attributes);
    // printf(" xvisualid=%d\n",xvisual->visualid);

  visual = gdk_x11_screen_lookup_visual (screen, xvisual->visualid);

  root = RootWindow (GLB_display, xscreen);
  xcolormap = XCreateColormap (GLB_display, root, xvisual->visual, AllocNone);

  glXGetConfig (GLB_display, xvisual, GLX_RED_SIZE, &i1);
    printf(" GLX_RED_SIZE=%d\n",i1);
  glXGetConfig (GLB_display, xvisual, GLX_DEPTH_SIZE, &i1);
    printf(" GLX_DEPTH_SIZE=%d\n",i1);

// Gtk2 only:
  //colormap = gdk_x11_colormap_foreign_new (visual, xcolormap);
  //gtk_widget_set_colormap (area, colormap);

  GLB_x_context = glXCreateContext (GLB_display, xvisual, NULL, TRUE);
  // free (xvisual);

  glXWaitX();
  glXWaitGL();

  return area;

}
Ejemplo n.º 4
0
XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings)
{
    // Retrieve all the visuals
    int count;
    XVisualInfo* visuals = XGetVisualInfo(display, 0, NULL, &count);
    if (visuals)
    {
        // Evaluate all the returned visuals, and pick the best one
        int bestScore = 0xFFFF;
        XVisualInfo bestVisual;
        for (int i = 0; i < count; ++i)
        {
            // Check mandatory attributes
            int doubleBuffer;
            glXGetConfig(display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer);
            if (!doubleBuffer)
                continue;

            // Extract the components of the current visual
            int red, green, blue, alpha, depth, stencil, multiSampling, samples;
            glXGetConfig(display, &visuals[i], GLX_RED_SIZE,           &red);
            glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE,         &green);
            glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE,          &blue);
            glXGetConfig(display, &visuals[i], GLX_ALPHA_SIZE,         &alpha);
            glXGetConfig(display, &visuals[i], GLX_DEPTH_SIZE,         &depth);
            glXGetConfig(display, &visuals[i], GLX_STENCIL_SIZE,       &stencil);
            glXGetConfig(display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
            glXGetConfig(display, &visuals[i], GLX_SAMPLES_ARB,        &samples);

            // Evaluate the visual
            int color = red + green + blue + alpha;
            int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0);

            // If it's better than the current best, make it the new best
            if (score < bestScore)
            {
                bestScore = score;
                bestVisual = visuals[i];
            }
        }

        // Free the array of visuals
        XFree(visuals);

        return bestVisual;
    }
    else
    {
        // Should never happen...
        err() << "No GLX visual found. You should check your graphics driver" << std::endl;

        return XVisualInfo();
    }
}
Ejemplo n.º 5
0
/*
 * Queries the GL context about some attributes
 */
static int fghGetConfig( int attribute )
{
  int returnValue = 0;

  if( fgStructure.CurrentWindow )
      glXGetConfig( fgDisplay.Display, fgStructure.CurrentWindow->Window.VisualInfo,
                    attribute, &returnValue );

  return returnValue;
}
Ejemplo n.º 6
0
QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
{
    QPlatformWindowFormat format;
    int redSize     = 0;
    int greenSize   = 0;
    int blueSize    = 0;
    int alphaSize   = 0;
    int depthSize   = 0;
    int stencilSize = 0;
    int sampleBuffers = 0;
    int sampleCount = 0;
    int level       = 0;
    int rgba        = 0;
    int stereo      = 0;
    int accumSizeA  = 0;
    int accumSizeR  = 0;
    int accumSizeG  = 0;
    int accumSizeB  = 0;

    XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
    glXGetConfig(display,vi,GLX_RGBA,&rgba);
    XFree(vi);
    glXGetFBConfigAttrib(display, config, GLX_RED_SIZE,     &redSize);
    glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE,   &greenSize);
    glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE,    &blueSize);
    glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE,   &alphaSize);
    glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE,   &depthSize);
    glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
    glXGetFBConfigAttrib(display, config, GLX_SAMPLES,      &sampleBuffers);
    glXGetFBConfigAttrib(display, config, GLX_LEVEL,        &level);
    glXGetFBConfigAttrib(display, config, GLX_STEREO,       &stereo);
    glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
    glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
    glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
    glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);

    format.setRedBufferSize(redSize);
    format.setGreenBufferSize(greenSize);
    format.setBlueBufferSize(blueSize);
    format.setAlphaBufferSize(alphaSize);
    format.setDepthBufferSize(depthSize);
    format.setStencilBufferSize(stencilSize);
    format.setSampleBuffers(sampleBuffers);
    if (format.sampleBuffers()) {
        glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
        format.setSamples(sampleCount);
    }

    format.setDirectRendering(glXIsDirect(display, ctx));
    format.setRgba(rgba);
    format.setStereo(stereo);
    format.setAccumBufferSize(accumSizeB);

    return format;
}
Ejemplo n.º 7
0
void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo)
{
    // Update the creation settings from the chosen format
    int depth, stencil, multiSampling, samples;
    glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE,   &depth);
    glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);

    if (sfglx_ext_ARB_multisample == sfglx_LOAD_SUCCEEDED)
    {
        glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
        glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB,        &samples);
    }
    else
    {
        multiSampling = 0;
        samples = 0;
    }

    m_settings.depthBits         = static_cast<unsigned int>(depth);
    m_settings.stencilBits       = static_cast<unsigned int>(stencil);
    m_settings.antialiasingLevel = multiSampling ? samples : 0;
}
Ejemplo n.º 8
0
static int
checkOverlayAcceptability(XVisualInfo * vi, unsigned int mode)
{
  int value;

  /* Must support OpenGL. */
  glXGetConfig(__glutDisplay, vi, GLX_USE_GL, &value);
  if (!value)
    return 1;

  /* Must be color index. */
  glXGetConfig(__glutDisplay, vi, GLX_RGBA, &value);
  if (value)
    return 1;

  /* Must match single/double buffering request. */
  glXGetConfig(__glutDisplay, vi, GLX_DOUBLEBUFFER, &value);
  if (GLUT_WIND_IS_DOUBLE(mode) != (value != 0))
    return 1;

  /* Must match mono/stereo request. */
  glXGetConfig(__glutDisplay, vi, GLX_STEREO, &value);
  if (GLUT_WIND_IS_STEREO(mode) != (value != 0))
    return 1;

  /* Alpha and accumulation buffers incompatible with color
     index. */
  if (GLUT_WIND_HAS_ALPHA(mode) || GLUT_WIND_HAS_ACCUM(mode))
    return 1;

  /* Look for depth buffer if requested. */
  glXGetConfig(__glutDisplay, vi, GLX_DEPTH_SIZE, &value);
  if (GLUT_WIND_HAS_DEPTH(mode) && (value <= 0))
    return 1;

  /* Look for stencil buffer if requested. */
  glXGetConfig(__glutDisplay, vi, GLX_STENCIL_SIZE, &value);
  if (GLUT_WIND_HAS_STENCIL(mode) && (value <= 0))
    return 1;

#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
  /* XXX Multisampled overlay color index??  Pretty unlikely. */
  /* Look for multisampling if requested. */
  if (__glutIsSupportedByGLX("GLX_SGIS_multisample"))
    glXGetConfig(__glutDisplay, vi, GLX_SAMPLES_SGIS, &value);
  else
    value = 0;
  if (GLUT_WIND_IS_MULTISAMPLE(mode) && (value <= 0))
    return 1;
#endif

  return 0;
}
Ejemplo n.º 9
0
JNIEXPORT jint JNICALL GLX_NATIVE(glXGetConfig)
	(JNIEnv *env, jclass that, jint arg0, jobject arg1, jint arg2, jintArray arg3)
{
	XVisualInfo _arg1, *lparg1=NULL;
	jint *lparg3=NULL;
	jint rc = 0;
	GLX_NATIVE_ENTER(env, that, glXGetConfig_FUNC);
	if (arg1) if ((lparg1 = getXVisualInfoFields(env, arg1, &_arg1)) == NULL) goto fail;
	if (arg3) if ((lparg3 = (*env)->GetIntArrayElements(env, arg3, NULL)) == NULL) goto fail;
	rc = (jint)glXGetConfig(arg0, lparg1, arg2, lparg3);
fail:
	if (arg3 && lparg3) (*env)->ReleaseIntArrayElements(env, arg3, lparg3, 0);
	if (arg1 && lparg1) setXVisualInfoFields(env, arg1, lparg1);
	GLX_NATIVE_EXIT(env, that, glXGetConfig_FUNC);
	return rc;
}
Ejemplo n.º 10
0
WindowSystem::WindowSystem(Options& o) {
	// If running in "compare" mode we never actually use the window
	// system, so we don't initialize it here.  This allows us to run
	// on systems without graphics hardware/software.
	if (o.mode == Options::compare) {
		dpy = 0;
		GLXVersMajor = GLXVersMinor = 0;
		vip = 0;
		return;
	}

	// Open the X11 display:
	dpy = XOpenDisplay(o.dpyName.c_str());
	if (!dpy)
		throw CantOpenDisplay();

	// Verify that GLX is supported:
	int error_base, event_base;
	if (glXQueryExtension(dpy, &error_base, &event_base) == False)
		throw NoOpenGL();

	// Record version numbers for later use:
	if (glXQueryVersion(dpy, &GLXVersMajor, &GLXVersMinor) == False)
		throw Error();	// this should never happen :-)

	// Get the list of raw XVisualInfo structures:
	XVisualInfo vit;
	vit.screen = DefaultScreen(dpy);
	int n;
	vip = XGetVisualInfo(dpy, VisualScreenMask, &vit, &n);

	// Construct a vector of DrawingSurfaceConfigs corresponding to the
	// XVisualInfo structures that indicate they support OpenGL:
	vector<DrawingSurfaceConfig*> glxv;
	for (int i = 0; i < n; ++i) {
		int supportsOpenGL;
		glXGetConfig(dpy, &vip[i], GLX_USE_GL, &supportsOpenGL);
		if (supportsOpenGL)
			glxv.push_back(new DrawingSurfaceConfig (dpy, &vip[i]));
	}

	// Filter the basic list of DrawingSurfaceConfigs according to
	// constraints provided by the user.  (This makes it convenient
	// to run tests on just a subset of all available configs.)
	DrawingSurfaceFilter f(o.visFilter);	// may throw an exception!
	surfConfigs = f.filter(glxv, o.maxVisuals);
} // WindowSystem::WindowSystem
Ejemplo n.º 11
0
void XWindow::classicInit(void)
{
    XVisualInfo       *vi, visInfo;
    XWindowAttributes winAttr;

    XGetWindowAttributes(getDisplay(), getWindow(), &winAttr);

    // get the existing glWidget's visual-id
    memset(&visInfo, 0, sizeof(XVisualInfo));

    visInfo.visualid = XVisualIDFromVisual(winAttr.visual);

    // get new display-variable
    if(getDisplay() == NULL)
    {
        setDisplay(XOpenDisplay(DisplayString(getDisplay())));  
    }
        
    // get a visual for the glx context
    int nvis;
    
    vi = XGetVisualInfo(getDisplay(), VisualIDMask, &visInfo, &nvis);

    // is the visual GL-capable ?
    int useGL;
    glXGetConfig( getDisplay(), 
                  vi, 
                  GLX_USE_GL, 
                 &useGL );

    if (!useGL)
    {
        SFATAL << "Visual is not OpenGL-capable!" << std::endl;
        exit(0);
    }    
        
    // create the new context
    this->setContext(glXCreateContext(getDisplay(), vi, None, GL_TRUE));
        
    XFree(vi);
}
Ejemplo n.º 12
0
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
{
#if defined(HAS_GLX)
  int value;
  if (glXGetConfig(m_dpy, vInfo, GLX_RGBA, &value) || !value)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_DOUBLEBUFFER, &value) || !value)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_RED_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_GREEN_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_BLUE_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_ALPHA_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_DEPTH_SIZE, &value) || value < 8)
    return false;
#endif

#if defined(HAS_EGL)
  EGLConfig config = getEGLConfig(m_eglDisplay, vInfo);
  if (config == EGL_NO_CONFIG)
  {
    CLog::Log(LOGERROR, "Failed to determine egl config for visual info");
    return false;
  }
  EGLint value;

  if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &value) || value < 8)
    return false;
  if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &value) || value < 8)
    return false;
  if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &value) || value < 8)
    return false;
  if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &value) || value < 8)
    return false;
  if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_DEPTH_SIZE, &value) || value < 24)
    return false;
 
#endif
  return true;
}
Ejemplo n.º 13
0
bool CGLContextGLX::IsSuitableVisual(XVisualInfo *vInfo)
{
  int value;

  if (glXGetConfig(m_dpy, vInfo, GLX_RGBA, &value) || !value)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_DOUBLEBUFFER, &value) || !value)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_RED_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_GREEN_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_BLUE_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_ALPHA_SIZE, &value) || value < 8)
    return false;
  if (glXGetConfig(m_dpy, vInfo, GLX_DEPTH_SIZE, &value) || value < 8)
    return false;

  return true;
}
Ejemplo n.º 14
0
void get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
                   struct visual_attribs *attribs)
{
   const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);

   memset(attribs, 0, sizeof(struct visual_attribs));

   attribs->id = vInfo->visualid;
#if defined(__cplusplus) || defined(c_plusplus)
   attribs->klass = vInfo->c_class;
#else
   attribs->klass = vInfo->class;
#endif
   attribs->depth = vInfo->depth;
   attribs->redMask = vInfo->red_mask;
   attribs->greenMask = vInfo->green_mask;
   attribs->blueMask = vInfo->blue_mask;
   attribs->colormapSize = vInfo->colormap_size;
   attribs->bitsPerRGB = vInfo->bits_per_rgb;

   if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
      return;
   glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
   glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
   glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
   glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
   glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
   glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
   glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
   glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
   glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
   glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
   glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
   glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);

   /* transparent pixel value not implemented yet */
   attribs->transparent = 0;

   /* multisample tests not implemented yet */
   attribs->numSamples = 0;
   attribs->numMultisample = 0;

#if defined(GLX_EXT_visual_rating)
   if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
      glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
   }
   else {
      attribs->visualCaveat = GLX_NONE_EXT;
   }
#else
   attribs->visualCaveat = 0;
#endif
}
Ejemplo n.º 15
0
QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
    : QGraphicsSystem(), m_useX11GL(useX11GL)
{
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
    // only override the system defaults if the user hasn't already
    // picked a visual
    if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
        // find a double buffered, RGBA visual that supports OpenGL
        // and set that as the default visual for windows in Qt
        int i = 0;
        int spec[16];
        spec[i++] = GLX_RGBA;
        spec[i++] = GLX_DOUBLEBUFFER;

        if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) {
            spec[i++] = GLX_DEPTH_SIZE;
            spec[i++] = 8;
            spec[i++] = GLX_STENCIL_SIZE;
            spec[i++] = 8;
            spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
            spec[i++] = 1;
            spec[i++] = GLX_SAMPLES_ARB;
            spec[i++] = 4;
        }

        spec[i++] = XNone;

        XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
        if (vi) {
            X11->visual_id = vi->visualid;
            X11->visual_class = vi->c_class;

            QGLFormat format;
            int res;
            glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
            format.setPlane(res);
            glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
            format.setDoubleBuffer(res);
            glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
            format.setDepth(res);
            if (format.depth())
                format.setDepthBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_RGBA, &res);
            format.setRgba(res);
            glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
            format.setRedBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
            format.setGreenBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
            format.setBlueBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
            format.setAlpha(res);
            if (format.alpha())
                format.setAlphaBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
            format.setAccum(res);
            if (format.accum())
                format.setAccumBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
            format.setStencil(res);
            if (format.stencil())
                format.setStencilBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_STEREO, &res);
            format.setStereo(res);
            glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
            format.setSampleBuffers(res);
            if (format.sampleBuffers()) {
                glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
                format.setSamples(res);
            }

            QGLWindowSurface::surfaceFormat = format;
            XFree(vi);

            printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
        }
    }
#elif defined(Q_WS_WIN)
    QGLWindowSurface::surfaceFormat.setDoubleBuffer(true);

    qt_win_owndc_required = true;
#endif
}
Ejemplo n.º 16
0
void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
{
    XVisualInfo* visualInfo = NULL;

    // Save the creation settings
    m_settings = settings;

    // Get the context to share display lists with
    GLXContext toShare = shared ? shared->m_context : NULL;

    // Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code)
    if (m_settings.majorVersion >= 3)
    {
        const GLubyte* name = reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB");
        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(name));
        if (glXCreateContextAttribsARB)
        {
            // Select a GLXFB config that matches the requested context settings
            int nbConfigs = 0;
            int fbAttributes[] =
            {
                GLX_DEPTH_SIZE, static_cast<int>(settings.depthBits),
                GLX_STENCIL_SIZE, static_cast<int>(settings.stencilBits),
                GLX_SAMPLE_BUFFERS, settings.antialiasingLevel > 0,
                GLX_SAMPLES, static_cast<int>(settings.antialiasingLevel),
                GLX_RED_SIZE, 8,
                GLX_GREEN_SIZE, 8,
                GLX_BLUE_SIZE, 8,
                GLX_ALPHA_SIZE, bitsPerPixel == 32 ? 8 : 0,
                GLX_DOUBLEBUFFER, True,
                GLX_X_RENDERABLE, True,
                GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
                GLX_RENDER_TYPE, GLX_RGBA_BIT,
                GLX_CONFIG_CAVEAT, GLX_NONE,
                None
            };
            GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), fbAttributes, &nbConfigs);
            if (configs && nbConfigs)
            {
                while (!m_context && (m_settings.majorVersion >= 3))
                {
                    // Create the context
                    int attributes[] =
                    {
                        GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
                        GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
                        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
                        0, 0
                    };
                    m_context = glXCreateContextAttribsARB(m_display, configs[0], toShare, true, attributes);

                    if (m_context)
                    {
                        // Ok: retrieve the config's visual
                        visualInfo = glXGetVisualFromFBConfig(m_display, configs[0]);
                    }
                    else
                    {
                        // If we couldn't create the context, lower the version number and try again -- stop at 3.0
                        // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care
                        if (m_settings.minorVersion > 0)
                        {
                            // If the minor version is not 0, we decrease it and try again
                            m_settings.minorVersion--;
                        }
                        else
                        {
                            // If the minor version is 0, we decrease the major version
                            m_settings.majorVersion--;
                            m_settings.minorVersion = 9;
                        }
                    }
                }
                XFree(configs);
            }
        }
    }

    // If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context
    if (!m_context)
    {
        // set the context version to 2.0 (arbitrary)
        m_settings.majorVersion = 2;
        m_settings.minorVersion = 0;

        // Retrieve the attributes of the target window
        XWindowAttributes windowAttributes;
        if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
        {
            err() << "Failed to get the window attributes" << std::endl;
            return;
        }

        // Get its visual
        XVisualInfo tpl;
        tpl.screen   = DefaultScreen(m_display);
        tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
        int nbVisuals = 0;
        visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);

        // Create the context, using the target window's visual
        m_context = glXCreateContext(m_display, visualInfo, toShare, true);
        if (!m_context)
        {
            err() << "Failed to create an OpenGL context for this window" << std::endl;
            return;
        }
    }

    // Update the creation settings from the chosen format
    int depth, stencil, multiSampling, samples;
    glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE,         &depth);
    glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE,       &stencil);
    glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
    glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB,        &samples);
    m_settings.depthBits         = static_cast<unsigned int>(depth);
    m_settings.stencilBits       = static_cast<unsigned int>(stencil);
    m_settings.antialiasingLevel = multiSampling ? samples : 0;

    // Free the visual info
    XFree(visualInfo);
}
Ejemplo n.º 17
0
static void
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
                   struct visual_attribs *attribs)
{
   const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);

   memset(attribs, 0, sizeof(struct visual_attribs));

   attribs->id = vInfo->visualid;
#if defined(__cplusplus) || defined(c_plusplus)
   attribs->klass = vInfo->c_class;
#else
   attribs->klass = vInfo->class;
#endif
   attribs->depth = vInfo->depth;
   attribs->redMask = vInfo->red_mask;
   attribs->greenMask = vInfo->green_mask;
   attribs->blueMask = vInfo->blue_mask;
   attribs->colormapSize = vInfo->colormap_size;
   attribs->bitsPerRGB = vInfo->bits_per_rgb;

   if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
      return;
   glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
   glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
   glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
   glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
   glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
   glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
   glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
   glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
   glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
   glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
   glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
   glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
   glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);

   /* get transparent pixel stuff */
   glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
   if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
   }
   else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
   }

   /* multisample attribs */
#ifdef GLX_ARB_multisample
   if (strstr("GLX_ARB_multisample", ext) == 0) {
      glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
      glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
   }
#endif
   else {
      attribs->numSamples = 0;
      attribs->numMultisample = 0;
   }

#if defined(GLX_EXT_visual_rating)
   if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
      glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
   }
   else {
      attribs->visualCaveat = GLX_NONE_EXT;
   }
#else
   attribs->visualCaveat = 0;
#endif
}
Ejemplo n.º 18
0
GLFWvidmode* _glfwPlatformGetVideoModes(int* found)
{
    XVisualInfo* visuals;
    XVisualInfo dummy;
    int i, j, visualCount, sizeCount, rgbCount;
    int* rgbs;
    _GLFWvidsize* sizes;
    GLFWvidmode* result;

    visuals = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &visualCount);
    if (visuals == NULL)
    {
        _glfwSetError(GLFW_PLATFORM_ERROR,
                      "X11/GLX: Failed to retrieve the available visuals");
        return 0;
    }

    // Build array of available RGB channel depths

    rgbs = (int*) malloc(sizeof(int) * visualCount);
    rgbCount = 0;

    for (i = 0;  i < visualCount;  i++)
    {
        int gl, rgba, rgb, r, g, b;

        glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_USE_GL, &gl);
        glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_RGBA, &rgba);

        if (!gl || !rgba)
        {
            // The visual lacks OpenGL or true color, so skip it
            continue;
        }

        // Convert to RGB channel depths and encode
        _glfwSplitBPP(visuals[i].depth, &r, &g, &b);
        rgb = (r << 16) | (g << 8) | b;

        for (j = 0;  j < rgbCount;  j++)
        {
            if (rgbs[j] == rgb)
                break;
        }

        if (j < rgbCount)
        {
            // This channel depth is a duplicate, so skip it
            continue;
        }

        rgbs[rgbCount] = rgb;
        rgbCount++;
    }

    XFree(visuals);

    // Build all permutations of channel depths and resolutions

    sizes = getResolutions(&sizeCount);

    result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * rgbCount * sizeCount);
    *found = 0;

    for (i = 0;  i < rgbCount;  i++)
    {
        for (j = 0;  j < sizeCount;  j++)
        {
            result[*found].width     = sizes[j].width;
            result[*found].height    = sizes[j].height;
            result[*found].redBits   = (rgbs[i] >> 16) & 255;
            result[*found].greenBits = (rgbs[i] >> 8) & 255;
            result[*found].blueBits  = rgbs[i] & 255;

            (*found)++;
        }
    }

    free(sizes);
    free(rgbs);

    return result;
}
Ejemplo n.º 19
0
static void visualAttribs( Display * dpy, XVisualInfo * vi, VisualAttribs * attribs )
{
    memset( attribs, 0, sizeof( VisualAttribs ) );

    attribs->id = vi->visualid;
    attribs->c_class = vi->c_class;
    attribs->depth = vi->depth;
    attribs->redMask = vi->red_mask;
    attribs->greenMask = vi->green_mask;
    attribs->blueMask = vi->blue_mask;
    attribs->colormapSize = vi->colormap_size;
    attribs->bitsPerRGB = vi->bits_per_rgb;

    if ( glXGetConfig( dpy, vi, GLX_USE_GL, &attribs->supportsGL ) != 0 )
        return;
    attribs->accumAlphaSize = 0;
    glXGetConfig( dpy, vi, GLX_BUFFER_SIZE, &attribs->bufferSize );
    glXGetConfig( dpy, vi, GLX_LEVEL, &attribs->level );
    glXGetConfig( dpy, vi, GLX_RGBA, &attribs->rgba );
    glXGetConfig( dpy, vi, GLX_DOUBLEBUFFER, &attribs->doubleBuffer );
    glXGetConfig( dpy, vi, GLX_STEREO, &attribs->stereo );
    glXGetConfig( dpy, vi, GLX_AUX_BUFFERS, &attribs->auxBuffers );
    glXGetConfig( dpy, vi, GLX_RED_SIZE, &attribs->redSize );
    glXGetConfig( dpy, vi, GLX_GREEN_SIZE, &attribs->greenSize );
    glXGetConfig( dpy, vi, GLX_BLUE_SIZE, &attribs->blueSize );
    glXGetConfig( dpy, vi, GLX_ALPHA_SIZE, &attribs->alphaSize );
    glXGetConfig( dpy, vi, GLX_DEPTH_SIZE, &attribs->depthSize );
    glXGetConfig( dpy, vi, GLX_STENCIL_SIZE, &attribs->stencilSize );
    glXGetConfig( dpy, vi, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize );
    glXGetConfig( dpy, vi, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize );
    glXGetConfig( dpy, vi, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize );
    glXGetConfig( dpy, vi, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize );

    attribs->transparent = 0; // transparent pixel missing
    attribs->numSamples = 0; // multisample tests missing
    attribs->numMultisample = 0;

#if defined(GLX_EXT_visual_rating)
    const char *ext = glXQueryExtensionsString( dpy, vi->screen );
    if ( ext && strstr( ext, "GLX_EXT_visual_rating" ) )
        glXGetConfig(dpy, vi, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
    else
        attribs->visualCaveat = GLX_NONE_EXT;
#else
    attribs->visualCaveat = 0;
#endif
}
Ejemplo n.º 20
0
//--------------------------------------------------------------
// initialize graphics
BOOL mgLinuxGL21Support::initDisplay()
{
  mgDebug("------ try to create OpenGL 2.1 context, fullscreen=%s, multiSample=%s", 
    m_fullscreen?"true":"false", 
    m_multiSample?"true":"false");

  mgLinuxServices* system = (mgLinuxServices*) mgPlatform;

  // =-= some drivers are failing this test.  not clear we need it
#ifdef WORKED
  int glxMajor, glxMinor;
  glXQueryVersion(system->m_display, &glxMajor, &glxMinor);
  mgDebug("GLX version = %d.%d", glxMajor, glxMinor);

  int glxVersion = glxMajor * 100 + glxMinor;
  if (glxVersion < 103)
  {
    mgDebug("GLX version < 1.3");
    termDisplay();
    return false;
  }
#endif

  system->m_glrc = glXCreateContext(system->m_display, system->m_vi, NULL, true);
  if (system->m_glrc == NULL)
  {
    mgDebug("Could not glXCreateContext");
    termDisplay();
    return false;
  }

  glXMakeCurrent(system->m_display, system->m_window, system->m_glrc);

  m_depthBits = 16; // default
  glXGetConfig(system->m_display, system->m_vi, GLX_DEPTH_SIZE, &m_depthBits);
  mgDebug("%d depth bits", m_depthBits);

  // get the extension list again now that we have chosen driver
	GLenum err = glewInit();
  if (err != GLEW_OK)
  {
    mgDebug("Cannot initialize OpenGL - glewInit failed.");
    termDisplay();
    return false;
  }

  mgString errorMsg;
  if (!checkVersion(201, 102, errorMsg))
  {
    mgDebug("%s", (const char*) errorMsg);
    termDisplay();
    return false; 
  }

  if (m_swapImmediate)
  {
    PFNGLXSWAPINTERVALMESAPROC fnSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA");
    if (fnSwapIntervalMESA != NULL)
      (*fnSwapIntervalMESA) (0);
    else 
    {
      PFNGLXSWAPINTERVALSGIPROC fnSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI");
      if (fnSwapIntervalSGI != NULL)
        (*fnSwapIntervalSGI) (0);
      else mgDebug("Cannot find glXSwapInterval");
    }
  }

  if (system->getMultiSample())
    glEnable(GL_MULTISAMPLE);

  // compile the overlay shader
  mgDebug("compile overlay shader:");
  const char* attrNames[] = {"vertPoint", "vertTexCoord0"};
  const DWORD attrIndexes[] = {0, 1};
  m_overlayShader = compileShaderPair(GL21_OVERLAY_VERTEX_SHADER, GL21_OVERLAY_FRAGMENT_SHADER,
    2, attrNames, attrIndexes);

  return true;
}
Ejemplo n.º 21
0
bool fxwt::init_graphics(GraphicsInitParameters *gparams) {
	Display *dpy;
	Window win;
	info("Initializing GLX");

	if(!(dpy = XOpenDisplay(0))) {
		error("Could not connect to the X server");
		return false;
	}

	int screen = DefaultScreen(dpy);
	Window root_win = RootWindow(dpy, screen);

	info("Trying to set video mode %dx%dx%d, d:%d s:%d %s", gparams->x, gparams->y, gparams->bpp, gparams->depth_bits, gparams->stencil_bits, gparams->fullscreen ? "fullscreen" : "windowed");
	
	// determine color bits
	int color_bits = 1;
	if(!(gparams->dont_care_flags & DONT_CARE_BPP)) {
		switch(gparams->bpp) {
		case 32:
		case 24:
			color_bits = 8;
			break;

		case 16:
		case 15:
			color_bits = 5;
			break;

		case 12:
			color_bits = 4;
			break;

		default:
			error("%s: Tried to set unsupported pixel format: %d bpp", __func__, gparams->bpp);
		}
	}

	// determine stencil bits
	int stencil_bits = gparams->stencil_bits;
	if(gparams->dont_care_flags & DONT_CARE_STENCIL) {
		stencil_bits = 1;
	}

	// determine zbuffer bits
	int zbits = gparams->depth_bits == 32 ? 24 : gparams->depth_bits;
	if(gparams->dont_care_flags & DONT_CARE_BPP) {
		zbits = 1;
	}
	
	int glx_attrib[] = {
		GLX_RGBA, GLX_DOUBLEBUFFER,
		GLX_RED_SIZE, color_bits,
		GLX_GREEN_SIZE, color_bits,
		GLX_BLUE_SIZE, color_bits,
		GLX_DEPTH_SIZE, zbits,
		GLX_STENCIL_SIZE, stencil_bits,
		None
	};

	XVisualInfo *vis_info;
	if(!(vis_info = glXChooseVisual(dpy, screen, glx_attrib))) {
		error("%s: Could not set requested video mode", __func__);
		XCloseDisplay(dpy);
		return false;
	}

	// check the video mode we got
	int arbits, agbits, abbits, azbits, astencilbits;
	glXGetConfig(dpy, vis_info, GLX_RED_SIZE, &arbits);
	glXGetConfig(dpy, vis_info, GLX_GREEN_SIZE, &agbits);
	glXGetConfig(dpy, vis_info, GLX_BLUE_SIZE, &abbits);
	glXGetConfig(dpy, vis_info, GLX_DEPTH_SIZE, &azbits);
	glXGetConfig(dpy, vis_info, GLX_STENCIL_SIZE, &astencilbits);

	info("Initialized video mode:");
	info("    bpp: %d (%d%d%d)", arbits + agbits + abbits, arbits, agbits, abbits);
	info("zbuffer: %d", azbits);
	info("stencil: %d", astencilbits);

	/* if the dont_care_flags does not contain DONT_CARE_BPP and our color bits
	 * does not match, we should return failure, however we test against
	 * the difference allowing a +/-1 difference in order to allow for 16bpp
	 * formats of either 565 or 555 and consider them equal.
	 */
	if(!(gparams->dont_care_flags & DONT_CARE_BPP) && abs(arbits - color_bits) > 1 && abs(agbits - color_bits) > 1 && abs(abbits - color_bits) > 1) {
		error("%s: Could not set requested exact bpp mode", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// now if we don't have DONT_CARE_DEPTH in the dont_care_flags check for 
	// exact depth buffer format, however consider 24 and 32 bit the same
	if(!(gparams->dont_care_flags & DONT_CARE_DEPTH) && azbits != zbits) {
		if(!(zbits == 32 && azbits == 24 || zbits == 24 && azbits == 32)) {
			error("%s: Could not set requested exact zbuffer depth", __func__);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return false;
		}
	}

	// if we don't have DONT_CARE_STENCIL make sure we have the stencil format
	// that was asked.
	if(!(gparams->dont_care_flags & DONT_CARE_STENCIL) && astencilbits != gparams->stencil_bits) {
		error("%s: Could not set exact stencil format", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// everything is ok, create the context
	if(!(glx_ctx = glXCreateContext(dpy, vis_info, 0, True))) {
		error("%s: Failed to create GLX context", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	XSetWindowAttributes xattr;
	xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen);
	xattr.colormap = XCreateColormap(dpy, root_win, vis_info->visual, AllocNone);

	if(gparams->fullscreen) {
		// TODO: also test for "XFree86-VidModeExtension"
#ifdef USE_XF86VIDMODE
		info("Using XF86VidMode extension for fullscreen resolution switch.");
		
		XF86VidModeModeInfo **modes;
		XF86VidModeModeInfo *vid_mode = 0;
		int mode_count;
		
		XF86VidModeGetAllModeLines(dpy, screen, &mode_count, &modes);
		orig_mode = *modes[0];

		for(int i=0; i<mode_count; i++) {
			if(modes[i]->hdisplay == gparams->x && modes[i]->vdisplay == gparams->y) {
				vid_mode = modes[i];
			}
		}
		if(!vid_mode) {
			error("Could not set requested video mode");
			XFree(modes);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return -1;
		}
		
		XF86VidModeSwitchToMode(dpy, screen, vid_mode);
		XF86VidModeSetViewPort(dpy, screen, 0, 0);
		XFree(modes);

		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#else
		info("Resolution switching is not compiled or not supported by the X server, using a full-screen window.");

		XWindowAttributes root_attr;
		XGetWindowAttributes(dpy, root_win, &root_attr);

		gparams->x = root_attr.width;
		gparams->y = root_attr.height;
		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#endif	// USE_XF86VIDMODE

		fullscreen = true;
	} else {
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr);
	}

	long events = ExposureMask | StructureNotifyMask | KeyPressMask;	// expose and key events
	events |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask;	// mouse events
	XSelectInput(dpy, win, events);
		
	// set WM cooperation settings
	Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(dpy, win, &wm_delete, 1);

	XTextProperty tp_wname;
	static char *win_title = "3dengfx/X";
	XStringListToTextProperty(&win_title, 1, &tp_wname);
	XSetWMName(dpy, win, &tp_wname);
	XFree(tp_wname.value);

	XClassHint class_hint;
	class_hint.res_name = "3dengfx";
	class_hint.res_class = "3dengfx_graphics";
	XSetClassHint(dpy, win, &class_hint);

	XFree(vis_info);

	if(glXMakeCurrent(dpy, win, glx_ctx) == False) {
		error("%s: Failed to make the GLX context current", __func__);
		glXDestroyContext(dpy, glx_ctx);
		XDestroyWindow(dpy, win);
		XCloseDisplay(dpy);
		return false;
	}

	if(!glXIsDirect(dpy, glx_ctx)) {
		warning("using indirect rendering, which might be slow...");
	}

	XMapWindow(dpy, win);
	XFlush(dpy);

	fxwt_x_dpy = dpy;
	fxwt_x_win = win;
	
	return true;
}
const GrGLInterface* SkNativeGLContext::createGLContext() {
    fDisplay = XOpenDisplay(0);

    if (!fDisplay) {
        SkDebugf("Failed to open X display.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Get a matching FB config
    static int visual_attribs[] = {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
        None
    };

#ifdef GLX_1_3
    //SkDebugf("Getting matching framebuffer configs.\n");
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
                                          visual_attribs, &fbcount);
    if (!fbc) {
        SkDebugf("Failed to retrieve a framebuffer config.\n");
        this->destroyGLContext();
        return NULL;
    }
    //SkDebugf("Found %d matching FB configs.\n", fbcount);

    // Pick the FB config/visual with the most samples per pixel
    //SkDebugf("Getting XVisualInfos.\n");
    int best_fbc = -1, best_num_samp = -1;

    int i;
    for (i = 0; i < fbcount; ++i) {
        XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]);
        if (vi) {
            int samp_buf, samples;
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples);

            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
            //       " SAMPLES = %d\n",
            //        i, (unsigned int)vi->visualid, samp_buf, samples);

            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
                best_fbc = i, best_num_samp = samples;
        }
        XFree(vi);
    }

    GLXFBConfig bestFbc = fbc[best_fbc];

    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
    XFree(fbc);

    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);
#else
    int numVisuals;
    XVisualInfo visTemplate, *visReturn;

    visReturn = XGetVisualInfo(fDisplay, VisualNoMask, &visTemplate, &numVisuals);
    if (NULL == visReturn)
    {
        SkDebugf("Failed to get visual information.\n");
        this->destroyGLContext();
        return NULL;
    }

    int best = -1, best_num_samp = -1;

    for (int i = 0; i < numVisuals; ++i)
    {
        int samp_buf, samples;

        glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLE_BUFFERS, &samp_buf);
        glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLES, &samples);

        if (best < 0 || (samp_buf && samples > best_num_samp))
            best = i, best_num_samp = samples;
    }

    XVisualInfo temp = visReturn[best];
    XVisualInfo *vi = &temp;

    XFree(visReturn);
#endif

    fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);

    if (!fPixmap) {
        SkDebugf("Failed to create pixmap.\n");
        this->destroyGLContext();
        return NULL;
    }

    fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);

#ifdef GLX_1_3
    // Done with the visual info data
    XFree(vi);
#endif

    // Create the context

    // Install an X error handler so the application won't exit if GL 3.0
    // context allocation fails.
    //
    // Note this error handler is global.
    // All display connections in all threads of a process use the same
    // error handler, so be sure to guard against other threads issuing
    // X commands while this code is running.
    ctxErrorOccurred = false;
    int (*oldHandler)(Display*, XErrorEvent*) =
        XSetErrorHandler(&ctxErrorHandler);

    // Get the default screen's GLX extension list
    const char *glxExts = glXQueryExtensionsString(
        fDisplay, DefaultScreen(fDisplay)
    );
    // Check for the GLX_ARB_create_context extension string and the function.
    // If either is not present, use GLX 1.3 context creation method.
    if (!gluCheckExtension(
          reinterpret_cast<const GLubyte*>("GLX_ARB_create_context")
          , reinterpret_cast<const GLubyte*>(glxExts)))
    {
        //SkDebugf("GLX_ARB_create_context not found."
        //       " Using old-style GLX context.\n");
#ifdef GLX_1_3
        fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
#else
        fContext = glXCreateContext(fDisplay, vi, 0, True);
#endif

    }
#ifdef GLX_1_3
    else {
        //SkDebugf("Creating context.\n");

        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
            (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
        int context_attribs[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
            GLX_CONTEXT_MINOR_VERSION_ARB, 0,
            //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
            None
        };
        fContext = glXCreateContextAttribsARB(
            fDisplay, bestFbc, 0, True, context_attribs
        );

        // Sync to ensure any errors generated are processed.
        XSync(fDisplay, False);
        if (!ctxErrorOccurred && fContext) {
           //SkDebugf( "Created GL 3.0 context.\n" );
        } else {
            // Couldn't create GL 3.0 context.
            // Fall back to old-style 2.x context.
            // When a context version below 3.0 is requested,
            // implementations will return the newest context version compatible
            // with OpenGL versions less than version 3.0.

            // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
            context_attribs[1] = 1;
            // GLX_CONTEXT_MINOR_VERSION_ARB = 0
            context_attribs[3] = 0;

            ctxErrorOccurred = false;

            //SkDebugf("Failed to create GL 3.0 context."
            //       " Using old-style GLX context.\n");
            fContext = glXCreateContextAttribsARB(
                fDisplay, bestFbc, 0, True, context_attribs
            );
        }
    }
#endif

    // Sync to ensure any errors generated are processed.
    XSync(fDisplay, False);

    // Restore the original error handler
    XSetErrorHandler(oldHandler);

    if (ctxErrorOccurred || !fContext) {
        SkDebugf("Failed to create an OpenGL context.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Verify that context is a direct context
    if (!glXIsDirect(fDisplay, fContext)) {
        //SkDebugf("Indirect GLX rendering context obtained.\n");
    } else {
        //SkDebugf("Direct GLX rendering context obtained.\n");
    }

    //SkDebugf("Making context current.\n");
    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
      SkDebugf("Could not set the context.\n");
        this->destroyGLContext();
        return NULL;
    }

    const GrGLInterface* interface = GrGLCreateNativeInterface();
    if (!interface) {
        SkDebugf("Failed to create gl interface");
        this->destroyGLContext();
        return NULL;
    }
    return interface;
}
Ejemplo n.º 23
0
bool QGLContext::chooseContext( const QGLContext* shareContext )
{
    Display* disp = d->paintDevice->x11Display();
    vi = chooseVisual();
    if ( !vi )
	return FALSE;

    if ( deviceIsPixmap() &&
	 (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() ||
	  ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) )
    {
	XFree( vi );
	XVisualInfo appVisInfo;
	memset( &appVisInfo, 0, sizeof(XVisualInfo) );
	appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() );
	appVisInfo.screen = d->paintDevice->x11Screen();
	int nvis;
	vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis );
	if ( !vi )
	    return FALSE;

	int useGL;
	glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL );
	if ( !useGL )
	    return FALSE;	//# Chickening out already...
    }
    int res;
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res );
    glFormat.setPlane( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res );
    glFormat.setDoubleBuffer( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res );
    glFormat.setDepth( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res );
    glFormat.setRgba( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res );
    glFormat.setAlpha( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res );
    glFormat.setAccum( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res );
    glFormat.setStencil( res );
    glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res );
    glFormat.setStereo( res );

    Bool direct = format().directRendering() ? True : False;

    if ( shareContext &&
	 ( !shareContext->isValid() || !shareContext->cx ) ) {
#if defined(QT_CHECK_NULL)
	    qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
#endif
	    shareContext = 0;
    }

    // 1. Sharing between rgba and color-index will give wrong colors.
    // 2. Contexts cannot be shared btw. direct/non-direct renderers.
    // 3. Pixmaps cannot share contexts that are set up for direct rendering.
    if ( shareContext && (format().rgba() != shareContext->format().rgba() ||
			  (deviceIsPixmap() &&
			   glXIsDirect( disp, (GLXContext)shareContext->cx ))))
	shareContext = 0;

    cx = 0;
    if ( shareContext ) {
	cx = glXCreateContext( disp, (XVisualInfo *)vi,
			       (GLXContext)shareContext->cx, direct );
	if ( cx )
	    d->sharing = TRUE;
    }
    if ( !cx )
	cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct );
    if ( !cx )
	return FALSE;
    glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) );
    if ( deviceIsPixmap() ) {
#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
	gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi,
				      d->paintDevice->handle(),
				      choose_cmap( disp, (XVisualInfo *)vi ) );
#else
	gpm = (Q_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi,
					    d->paintDevice->handle() );
#endif
	if ( !gpm )
	    return FALSE;
    }
    return TRUE;
}
Ejemplo n.º 24
0
void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
{
    // Save the creation settings
    m_settings = settings;

    // Get the attributes of the target window
    XWindowAttributes windowAttributes;
    if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
    {
        err() << "Failed to get the window attributes" << std::endl;
        return;
    }

    // Setup the visual infos to match
    XVisualInfo tpl;
    tpl.depth    = windowAttributes.depth;
    tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
    tpl.screen   = DefaultScreen(m_display);

    // Get all the visuals matching the template
    int nbVisuals = 0;
    XVisualInfo* visuals = XGetVisualInfo(m_display, VisualDepthMask | VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
    if (!visuals || (nbVisuals == 0))
    {
        if (visuals)
            XFree(visuals);
        err() << "There is no valid visual for the selected screen" << std::endl;
        return;
    }

    // Find the best visual
    int          bestScore  = 0xFFFF;
    XVisualInfo* bestVisual = NULL;
    for (int i = 0; i < nbVisuals; ++i)
    {
        // Get the current visual attributes
        int RGBA, doubleBuffer, red, green, blue, alpha, depth, stencil, multiSampling, samples;
        glXGetConfig(m_display, &visuals[i], GLX_RGBA,               &RGBA);
        glXGetConfig(m_display, &visuals[i], GLX_DOUBLEBUFFER,       &doubleBuffer); 
        glXGetConfig(m_display, &visuals[i], GLX_RED_SIZE,           &red);
        glXGetConfig(m_display, &visuals[i], GLX_GREEN_SIZE,         &green); 
        glXGetConfig(m_display, &visuals[i], GLX_BLUE_SIZE,          &blue); 
        glXGetConfig(m_display, &visuals[i], GLX_ALPHA_SIZE,         &alpha); 
        glXGetConfig(m_display, &visuals[i], GLX_DEPTH_SIZE,         &depth);        
        glXGetConfig(m_display, &visuals[i], GLX_STENCIL_SIZE,       &stencil);
        glXGetConfig(m_display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling);        
        glXGetConfig(m_display, &visuals[i], GLX_SAMPLES_ARB,        &samples);

        // First check the mandatory parameters
        if ((RGBA == 0) || (doubleBuffer == 0))
            continue;

        // Evaluate the current configuration
        int color = red + green + blue + alpha;
        int score = evaluateFormat(bitsPerPixel, m_settings, color, depth, stencil, multiSampling ? samples : 0);

        // Keep it if it's better than the current best
        if (score < bestScore)
        {
            bestScore  = score;
            bestVisual = &visuals[i];
        }
    }

    // Make sure that we have found a visual
    if (!bestVisual)
    {
        err() << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
        return;
    }

    // Get the context to share display lists with
    GLXContext toShare = shared ? shared->m_context : NULL;

    // Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code)
    while (!m_context && (m_settings.majorVersion >= 3))
    {
        const GLubyte* name = reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB");
        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(name));
        if (glXCreateContextAttribsARB)
        {
            int nbConfigs = 0;
            GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), NULL, &nbConfigs);
            if (configs && nbConfigs)
            {
                // Create the context
                int attributes[] =
                {
                    GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
                    GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
                    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
                    0, 0
                };
                m_context = glXCreateContextAttribsARB(m_display, configs[0], toShare, true, attributes);
            }

            if (configs)
                XFree(configs);
        }

        // If we couldn't create the context, lower the version number and try again -- stop at 3.0
        // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care
        if (!m_context)
        {
            if (m_settings.minorVersion > 0)
            {
                // If the minor version is not 0, we decrease it and try again
                m_settings.minorVersion--;
            }
            else
            {
                // If the minor version is 0, we decrease the major version
                m_settings.majorVersion--;
                m_settings.minorVersion = 9;
            }
        }
    }

    // If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context
    if (!m_context)
    {
        // set the context version to 2.0 (arbitrary)
        m_settings.majorVersion = 2;
        m_settings.minorVersion = 0;

        m_context = glXCreateContext(m_display, bestVisual, toShare, true);
        if (!m_context)
        {
            err() << "Failed to create an OpenGL context for this window" << std::endl;
            return;
        }
    }

    // Update the creation settings from the chosen format
    int depth, stencil, multiSampling, samples;
    glXGetConfig(m_display, bestVisual, GLX_DEPTH_SIZE,         &depth);
    glXGetConfig(m_display, bestVisual, GLX_STENCIL_SIZE,       &stencil);
    glXGetConfig(m_display, bestVisual, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);        
    glXGetConfig(m_display, bestVisual, GLX_SAMPLES_ARB,        &samples);
    m_settings.depthBits         = static_cast<unsigned int>(depth);
    m_settings.stencilBits       = static_cast<unsigned int>(stencil);
    m_settings.antialiasingLevel = multiSampling ? samples : 0;

    // Change the target window's colormap so that it matches the context's one
    ::Window root = RootWindow(m_display, DefaultScreen(m_display));
    Colormap colorMap = XCreateColormap(m_display, root, bestVisual->visual, AllocNone);
    XSetWindowColormap(m_display, m_window, colorMap);

    // Free the temporary visuals array
    XFree(visuals);
}
Ejemplo n.º 25
0
void SkOSWindow::initWindow(int requestedMSAASampleCount, AttachmentInfo* info) {
    if (fMSAASampleCount != requestedMSAASampleCount) {
        this->closeWindow();
    }
    // presence of fDisplay means we already have a window
    if (NULL != fUnixWindow.fDisplay) {
        if (NULL != info) {
            if (NULL != fVi) {
                glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
                glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
            } else {
                info->fSampleCount = 0;
                info->fStencilBits = 0;
            }
        }
        return;
    }
    fUnixWindow.fDisplay = XOpenDisplay(NULL);
    Display* dsp = fUnixWindow.fDisplay;
    if (NULL == dsp) {
        SkDebugf("Could not open an X Display");
        return;
    }
    // Attempt to create a window that supports GL
    GLint att[] = {
        GLX_RGBA,
        GLX_DEPTH_SIZE, 24,
        GLX_DOUBLEBUFFER,
        GLX_STENCIL_SIZE, 8,
        None
    };
    SkASSERT(NULL == fVi);
    if (requestedMSAASampleCount > 0) {
        static const GLint kAttCount = SK_ARRAY_COUNT(att);
        GLint msaaAtt[kAttCount + 4];
        memcpy(msaaAtt, att, sizeof(att));
        SkASSERT(None == msaaAtt[kAttCount - 1]);
        msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
        msaaAtt[kAttCount + 0] = 1;
        msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
        msaaAtt[kAttCount + 2] = requestedMSAASampleCount;
        msaaAtt[kAttCount + 3] = None;
        fVi = glXChooseVisual(dsp, DefaultScreen(dsp), msaaAtt);
        fMSAASampleCount = requestedMSAASampleCount;
    }
    if (NULL == fVi) {
        fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att);
        fMSAASampleCount = 0;
    }

    if (fVi) {
        if (NULL != info) {
            glXGetConfig(dsp, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
            glXGetConfig(dsp, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
        }
        Colormap colorMap = XCreateColormap(dsp,
                                            RootWindow(dsp, fVi->screen),
                                            fVi->visual,
                                             AllocNone);
        XSetWindowAttributes swa;
        swa.colormap = colorMap;
        swa.event_mask = EVENT_MASK;
        fUnixWindow.fWin = XCreateWindow(dsp,
                                         RootWindow(dsp, fVi->screen),
                                         0, 0, // x, y
                                         WIDTH, HEIGHT,
                                         0, // border width
                                         fVi->depth,
                                         InputOutput,
                                         fVi->visual,
                                         CWEventMask | CWColormap,
                                         &swa);
    } else {
        if (NULL != info) {
            info->fSampleCount = 0;
            info->fStencilBits = 0;
        }
        // Create a simple window instead.  We will not be able to show GL
        fUnixWindow.fWin = XCreateSimpleWindow(dsp,
                                               DefaultRootWindow(dsp),
                                               0, 0,  // x, y
                                               WIDTH, HEIGHT,
                                               0,     // border width
                                               0,     // border value
                                               0);    // background value
    }
    this->mapWindowAndWait();
    fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL);
}
Ejemplo n.º 26
0
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
    Q_D(QGLContext);
    const QX11Info *xinfo = qt_x11Info(d->paintDevice);

    Display* disp = xinfo->display();
    d->vi = chooseVisual();
    if (!d->vi)
        return false;

    if (deviceIsPixmap() &&
         (((XVisualInfo*)d->vi)->depth != xinfo->depth() ||
          ((XVisualInfo*)d->vi)->screen != xinfo->screen()))
    {
        XFree(d->vi);
        XVisualInfo appVisInfo;
        memset(&appVisInfo, 0, sizeof(XVisualInfo));
        appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual());
        appVisInfo.screen = xinfo->screen();
        int nvis;
        d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis);
        if (!d->vi)
            return false;

        int useGL;
        glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL);
        if (!useGL)
            return false;        //# Chickening out already...
    }
    int res;
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res);
    d->glFormat.setPlane(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res);
    d->glFormat.setDoubleBuffer(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res);
    d->glFormat.setDepth(res);
    if (d->glFormat.depth())
        d->glFormat.setDepthBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res);
    d->glFormat.setRgba(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res);
    d->glFormat.setRedBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res);
    d->glFormat.setGreenBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res);
    d->glFormat.setBlueBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res);
    d->glFormat.setAlpha(res);
    if (d->glFormat.alpha())
        d->glFormat.setAlphaBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res);
    d->glFormat.setAccum(res);
    if (d->glFormat.accum())
        d->glFormat.setAccumBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res);
    d->glFormat.setStencil(res);
    if (d->glFormat.stencil())
        d->glFormat.setStencilBufferSize(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res);
    d->glFormat.setStereo(res);
    glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res);
    d->glFormat.setSampleBuffers(res);
    if (d->glFormat.sampleBuffers()) {
        glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res);
        d->glFormat.setSamples(res);
    }

    Bool direct = format().directRendering() ? True : False;

    if (shareContext &&
         (!shareContext->isValid() || !shareContext->d_func()->cx)) {
            qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
            shareContext = 0;
    }

    // 1. Sharing between rgba and color-index will give wrong colors.
    // 2. Contexts cannot be shared btw. direct/non-direct renderers.
    // 3. Pixmaps cannot share contexts that are set up for direct rendering.
    // 4. If the contexts are not created on the same screen, they can't be shared

    if (shareContext
        && (format().rgba() != shareContext->format().rgba()
            || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx))
            || (shareContext->d_func()->screen != xinfo->screen())))
    {
        shareContext = 0;
    }

    d->cx = 0;
    if (shareContext) {
        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,
                               (GLXContext)shareContext->d_func()->cx, direct);
        d->screen = ((XVisualInfo*)d->vi)->screen;
        if (d->cx) {
            QGLContext *share = const_cast<QGLContext *>(shareContext);
            d->sharing = true;
            share->d_func()->sharing = true;
        }
    }
    if (!d->cx) {
        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);
        d->screen = ((XVisualInfo*)d->vi)->screen;
    }
    if (!d->cx)
        return false;
    d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx));
    if (deviceIsPixmap()) {
#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
        d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi,
                                        qt_x11Handle(d->paintDevice),
                                        qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi));
#else
        d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi,
                                              qt_x11Handle(d->paintDevice));
#endif
        if (!d->gpm)
            return false;
    }
    QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));
    if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
        if (d->glFormat.swapInterval() == -1)
            d->glFormat.setSwapInterval(0);
    } else {
        d->glFormat.setSwapInterval(-1);
    }
    return true;
}
Ejemplo n.º 27
0
bool wxGLCanvas::Create( wxWindow *parent, 
                         const wxGLContext *shared,
                         const wxGLCanvas *shared_context_of,
                         wxWindowID id,
                         const wxPoint& pos, const wxSize& size, 
			 long style, const wxString& name,
                         int *attribList, 
			 const wxPalette& palette)
{
    XVisualInfo *vi, vi_templ;
    XWindowAttributes xwa;
    int val, n;

    m_sharedContext = (wxGLContext*)shared;  // const_cast
    m_sharedContextOf = (wxGLCanvas*)shared_context_of;  // const_cast
    m_glContext = (wxGLContext*) NULL;

    Display* display = (Display*) wxGetDisplay();

    // Check for the presence of the GLX extension
    if(!glXQueryExtension(display, NULL, NULL)) {
	wxLogDebug(wxT("wxGLCanvas: GLX extension is missing\n"));
	return FALSE;
    }

    if(attribList) {
      int data[512], arg=0, p=0;
       
      while( (attribList[arg]!=0) && (p<512) )
      {
        switch( attribList[arg++] )
        {
          case WX_GL_RGBA: data[p++] = GLX_RGBA; break;
          case WX_GL_BUFFER_SIZE:
            data[p++]=GLX_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_LEVEL:
            data[p++]=GLX_LEVEL; data[p++]=attribList[arg++]; break;
          case WX_GL_DOUBLEBUFFER: data[p++] = GLX_DOUBLEBUFFER; break;
          case WX_GL_STEREO: data[p++] = GLX_STEREO; break;
          case WX_GL_AUX_BUFFERS:
            data[p++]=GLX_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_RED:
            data[p++]=GLX_RED_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_GREEN:
            data[p++]=GLX_GREEN_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_BLUE:
            data[p++]=GLX_BLUE_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_ALPHA:
            data[p++]=GLX_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_DEPTH_SIZE: 
            data[p++]=GLX_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_STENCIL_SIZE: 
            data[p++]=GLX_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_ACCUM_RED:
            data[p++]=GLX_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_ACCUM_GREEN:
            data[p++]=GLX_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_ACCUM_BLUE:
            data[p++]=GLX_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
          case WX_GL_MIN_ACCUM_ALPHA:
            data[p++]=GLX_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
          default:
            break;
        }
      }       
      data[p] = 0; 

      attribList = (int*) data;
      // Get an appropriate visual
      vi = glXChooseVisual(display, DefaultScreen(display), attribList);
      if(!vi) return FALSE;
      
      // Here we should make sure that vi is the same visual as the
      // one used by the xwindow drawable in wxCanvas.  However,
      // there is currently no mechanism for this in wx_canvs.cc.
    } else {
	// By default, we use the visual of xwindow
        // NI: is this really senseful ? opengl in e.g. color index mode ?
	XGetWindowAttributes(display, (Window)wxGetClientAreaWindow(this), &xwa);
	vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
	vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
	if(!vi) return FALSE;
	glXGetConfig(display, vi, GLX_USE_GL, &val);
	if(!val) return FALSE;
	// Basically, this is it.  It should be possible to use vi
	// in glXCreateContext() below.  But this fails with Mesa.
	// I notified the Mesa author about it; there may be a fix.
#ifdef OLD_MESA
	// Construct an attribute list matching the visual
	int a_list[32];
	n = 0;
	if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual
	    a_list[n++] = GLX_RGBA;
	    a_list[n++] = GLX_RED_SIZE;
	    a_list[n++] = bitcount(vi->red_mask);
	    a_list[n++] = GLX_GREEN_SIZE;
	    a_list[n++] = bitcount(vi->green_mask);
	    a_list[n++] = GLX_BLUE_SIZE;
	    a_list[n++] = bitcount(vi->blue_mask);
	    glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val);
	    a_list[n++] = GLX_ALPHA_SIZE;
	    a_list[n++] = val;
	} else { // Color index visual
	    glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val);
	    a_list[n++] = GLX_BUFFER_SIZE;
	    a_list[n++] = val;
	}
	a_list[n] = None;
	// XFree(vi);
	vi = glXChooseVisual(display, DefaultScreen(display), a_list);
	if(!vi) return FALSE;
#endif /* OLD_MESA */
    }

    m_vi = vi;  // safe for later use
    
    wxCHECK_MSG( m_vi, FALSE, wxT("required visual couldn't be found") );

    // Create the GLX context and make it current

    wxGLContext *share= m_sharedContext;
    if (share==NULL && m_sharedContextOf) 
        share = m_sharedContextOf->GetContext();

    m_glContext = new wxGLContext( TRUE, this, wxNullPalette, share );

#ifndef OLD_MESA
    // XFree(vi);
#endif
    SetCurrent();

    return TRUE;
}
Ejemplo n.º 28
0
static bool gfx_ctx_glx_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   XEvent event;
   bool true_full = false, windowed_full;
   int val, x_off = 0, y_off = 0;
   XVisualInfo *vi = NULL;
   XSetWindowAttributes swa = {0};
   int (*old_handler)(Display*, XErrorEvent*) = NULL;
   driver_t *driver = driver_get_ptr();
   gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data;
   struct sigaction sa = {{0}};
   settings_t *settings    = config_get_ptr();

   sa.sa_handler = glx_sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

   if (!glx)
      return false;

   windowed_full = settings->video.windowed_fullscreen;
   true_full = false;

   vi = glXGetVisualFromFBConfig(glx->g_dpy, glx->g_fbc);
   if (!vi)
      goto error;

   swa.colormap = glx->g_cmap = XCreateColormap(glx->g_dpy,
         RootWindow(glx->g_dpy, vi->screen), vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
      ButtonReleaseMask | ButtonPressMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(glx->g_dpy, width, height, &glx->g_desktop_mode))
      {
         glx->g_should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (settings->video.monitor_index)
      glx->g_screen = settings->video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || glx->g_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;

      if (x11_get_xinerama_coord(glx->g_dpy, glx->g_screen,
               &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", glx->g_screen);
      else
         RARCH_LOG("[GLX]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   glx->g_win = XCreateWindow(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(glx->g_dpy, glx->g_win, 0);

   glx->g_glx_win = glXCreateWindow(glx->g_dpy, glx->g_fbc, glx->g_win, 0);

   x11_set_window_attr(glx->g_dpy, glx->g_win);

   if (fullscreen)
      x11_show_mouse(glx->g_dpy, glx->g_win, false);

   if (true_full)
   {
      RARCH_LOG("[GLX]: Using true fullscreen.\n");
      XMapRaised(glx->g_dpy, glx->g_win);
   }
   else if (fullscreen) /* We attempted true fullscreen, but failed. Attempt using windowed fullscreen. */
   {
      XMapRaised(glx->g_dpy, glx->g_win);
      RARCH_LOG("[GLX]: Using windowed fullscreen.\n");
      /* We have to move the window to the screen we want to go fullscreen on first.
       * x_off and y_off usually get ignored in XCreateWindow().
       */
      x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(glx->g_dpy, glx->g_win);
   }
   else
   {
      XMapWindow(glx->g_dpy, glx->g_win);
      // If we want to map the window on a different screen, we'll have to do it by force.
      // Otherwise, we should try to let the window manager sort it out.
      // x_off and y_off usually get ignored in XCreateWindow().
      if (glx->g_screen)
         x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height);
   }

   XIfEvent(glx->g_dpy, &event, glx_wait_notify, NULL);

   if (!glx->g_ctx)
   {
      if (glx->g_core_es || glx->g_debug)
      {
         int attribs[16];
         int *aptr = attribs;

         if (glx->g_core_es)
         {
            *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB;
            *aptr++ = g_major;
            *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB;
            *aptr++ = g_minor;

            if (glx->g_core_es_core)
            {
               /* Technically, we don't have core/compat until 3.2.
                * Version 3.1 is either compat or not depending on GL_ARB_compatibility.
                */
               *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB;
#ifdef HAVE_OPENGLES2
               *aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT;
#else
               *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#endif
            }
         }

         if (glx->g_debug)
         {
            *aptr++ = GLX_CONTEXT_FLAGS_ARB;
            *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB;
         }

         *aptr = None;
         glx->g_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, NULL, True, attribs);
         if (glx->g_use_hw_ctx)
         {
            RARCH_LOG("[GLX]: Creating shared HW context.\n");
            glx->g_hw_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, glx->g_ctx, True, attribs);
            if (!glx->g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }
      else
      {
         glx->g_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, 0, True);
         if (glx->g_use_hw_ctx)
         {
            glx->g_hw_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, glx->g_ctx, True);
            if (!glx->g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }

      if (!glx->g_ctx)
      {
         RARCH_ERR("[GLX]: Failed to create new context.\n");
         goto error;
      }
   }
   else
   {
      driver->video_cache_context_ack = true;
      RARCH_LOG("[GLX]: Using cached GL context.\n");
   }

   glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, glx->g_ctx);
   XSync(glx->g_dpy, False);

   g_quit_atom = XInternAtom(glx->g_dpy, "WM_DELETE_WINDOW", False);
   if (g_quit_atom)
      XSetWMProtocols(glx->g_dpy, glx->g_win, &g_quit_atom, 1);

   glXGetConfig(glx->g_dpy, vi, GLX_DOUBLEBUFFER, &val);
   glx->g_is_double = val;

   if (glx->g_is_double)
   {
      const char *swap_func = NULL;

      g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
      g_pglSwapIntervalSGI = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
      g_pglSwapInterval    = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");

      if (g_pglSwapIntervalEXT)
         swap_func = "glXSwapIntervalEXT";
      else if (g_pglSwapInterval)
         swap_func = "glXSwapIntervalMESA";
      else if (g_pglSwapIntervalSGI)
         swap_func = "glXSwapIntervalSGI";

      if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI)
         RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
      else
         RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func);
   }
   else
      RARCH_WARN("[GLX]: Context is not double buffered!.\n");

   gfx_ctx_glx_swap_interval(data, glx->g_interval);

   /* This can blow up on some drivers. It's not fatal, so override errors for this call. */
   old_handler = XSetErrorHandler(glx_nul_handler);
   XSetInputFocus(glx->g_dpy, glx->g_win, RevertToNone, CurrentTime);
   XSync(glx->g_dpy, False);
   XSetErrorHandler(old_handler);

   XFree(vi);
   glx->g_has_focus = true;

   if (!x11_create_input_context(glx->g_dpy, glx->g_win, &glx->g_xim, &glx->g_xic))
      goto error;

   driver->display_type  = RARCH_DISPLAY_X11;
   driver->video_display = (uintptr_t)glx->g_dpy;
   driver->video_window  = (uintptr_t)glx->g_win;
   glx->g_true_full = true_full;

   return true;

error:
   if (vi)
      XFree(vi);

   ctx_glx_destroy_resources(glx);

   if (glx)
      free(glx);

   return false;
}
Ejemplo n.º 29
0
int CreateWindow(int display)
{
  int err = 0;
  glutDisplay *glut_dpy = (glutDisplay *)display;
  glutWindow *glut_win = NULL;
  XVisualInfo *glx_visual = NULL;
  int glx_visual_attr[5];
  int i = 0;

  glut_win = calloc(1, sizeof(glutWindow));
  FIU_CHECK(glut_win);
  if (!glut_win) {
    printf("glut_win calloc error\n");
    return 0;
  }

  memcpy(&glut_win->attribs, &glut_dpy->attribs, sizeof(struct attributes));

  memset(glx_visual_attr, 0, sizeof(glx_visual_attr));
  glx_visual_attr[i++] = GLX_RGBA;
  if (glut_win->attribs.double_buffer) {
    glx_visual_attr[i++] = GLX_DOUBLEBUFFER;
  }
  if (glut_win->attribs.depth_size) {
    glx_visual_attr[i++] = GLX_DEPTH_SIZE;
    glx_visual_attr[i++] = glut_win->attribs.depth_size;
  }
  glx_visual_attr[i] = None;
  glx_visual = glXChooseVisual(glut_dpy->x11_dpy, 0, glx_visual_attr);
  if (!glx_visual) {
    printf("glXChooseVisual error\n");
    goto error;
  }

  glut_win->x11_win = create_window((int)glut_dpy->x11_dpy, glut_win->attribs.win_posx, glut_win->attribs.win_posy, glut_win->attribs.win_width, glut_win->attribs.win_height, 0, &err);
  if (err == -1) {
    goto error;
  }

  glut_win->glx_ctx = glXCreateContext(glut_dpy->x11_dpy, glx_visual, NULL, True);
  if (!glut_win->glx_ctx) {
    printf("glXCreateContext error\n");
    goto error;
  }

  if (glut_win->attribs.depth_size) {
    err = glXGetConfig(glut_dpy->x11_dpy, glx_visual, GLX_DEPTH_SIZE, &glut_win->attribs.depth_size);
    if (err) {
      printf("glXCreateContext error\n");
      goto error;
    }
  }

  free(glx_visual);

  return (int)glut_win;

error:
  if (glut_win->glx_ctx) {
    glXDestroyContext(glut_dpy->x11_dpy, glut_win->glx_ctx);
  }
  if (glut_win->x11_win) {
    destroy_window((int)glut_dpy->x11_dpy, glut_win->x11_win);
  }
  if (glx_visual) {
    free(glx_visual);
  }
  free(glut_win);
  return 0;
}
Ejemplo n.º 30
0
//--------------------------------------------------------------
// initialize graphics
BOOL mgLinuxGL33Support::initDisplay()
{
  mgDebug("------ try to create OpenGL 3.3 context, fullscreen=%s, multiSample=%s", 
    m_fullscreen?"true":"false", 
    m_multiSample?"true":"false");

  mgLinuxServices* platform = (mgLinuxServices*) mgPlatform;

  // =-= some drivers are failing this test.  not clear we need it
#ifdef WORKED
  int glxMajor, glxMinor;
  glXQueryVersion(platform->m_display, &glxMajor, &glxMinor);
  mgDebug("GLX version = %d.%d", glxMajor, glxMinor);

  int glxVersion = glxMajor * 100 + glxMinor;
  if (glxVersion < 103)
  {
    mgDebug("GLX version < 1.3");
    termDisplay();
    return false;
  }
#endif

  PFNGLXCREATECONTEXTATTRIBSARBPROC fnCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB");
  PFNGLGETSTRINGIPROC fnGetStringi = (PFNGLGETSTRINGIPROC)glXGetProcAddress((const GLubyte*) "glGetStringi");
  if (fnCreateContextAttribsARB == NULL || fnGetStringi == NULL)
  {
    mgDebug("Could not locate OpenGL functions");
    termDisplay();
    return false;
  }

  platform->m_glrc = (*fnCreateContextAttribsARB) (platform->m_display, platform->m_bestFbc, NULL, true, GL33_CREATE_ATTRIBUTES);
  if (platform->m_glrc == NULL)
  {
    mgDebug("glXCreateContextAttribsARB 3.3 returns NULL.  Trying 3.2");
    platform->m_glrc = (*fnCreateContextAttribsARB) (platform->m_display, platform->m_bestFbc, NULL, true, GL32_CREATE_ATTRIBUTES);
    if (platform->m_glrc == NULL)
    {
      mgDebug("glXCreateContextAttribsARB 3.2 returns NULL.  I give up.");
      termDisplay();
      return false;
    }
  }

  glXMakeCurrent(platform->m_display, platform->m_window, platform->m_glrc);

  m_depthBits = 16; // default
  glXGetConfig(platform->m_display, platform->m_vi, GLX_DEPTH_SIZE, &m_depthBits);
  mgDebug("%d depth bits", m_depthBits);

  // build an extension list for glew with glGetStringi
  mgString extList;
  int i = 0;
  for (; ; i++)
  {
    const GLubyte* ext = (*fnGetStringi)(GL_EXTENSIONS, i);
    if (ext == NULL)
      break;
    extList += (const char*) ext;
    extList += " ";
  }
  mgDebug("glGetStringi returns %d extensions", i);
  checkError();  // clear error from requesting last extension

  // save extensions list for glew
  glExtensions = (GLubyte*) new char[1+extList.length()];
  strcpy((char*) glExtensions, (const char*) extList);

	GLenum err = glewInit();
  if (err != GLEW_OK)
  {
    mgDebug("Cannot initialize OpenGL - glewInit failed.");
    termDisplay();
    return false;
  }

  // accept OpenGL 3.2, but need #version 330 shader
  mgString errorMsg;
  if (!checkVersion(302, 303, errorMsg))
  {
    mgDebug("%s", (const char*) errorMsg);
    termDisplay();
    return false;
  }

  if (m_swapImmediate)
  {
    PFNGLXSWAPINTERVALMESAPROC fnSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA");
    if (fnSwapIntervalMESA != NULL)
      (*fnSwapIntervalMESA) (0);
    else 
    {
      PFNGLXSWAPINTERVALSGIPROC fnSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI");
      if (fnSwapIntervalSGI != NULL)
        (*fnSwapIntervalSGI) (0);
      else mgDebug("Cannot find glXSwapInterval");
    }
  }

  if (m_multiSample)
    glEnable(GL_MULTISAMPLE);

  // compile the overlay shader
  mgDebug("compile overlay shader:");
  const char* attrNames[] = {"vertPoint", "vertTexCoord0"};
  const DWORD attrIndexes[] = {0, 1};
  m_overlayShader = compileShaderPair(GL33_OVERLAY_VERTEX_SHADER, GL33_OVERLAY_FRAGMENT_SHADER,
    2, attrNames, attrIndexes);

  if (m_overlayShader == 0)
  {
    mgDebug("Cannot compile overlay shader.");
    termDisplay();
    return false;
  }

  const char* vendor = (const char*) glGetString(GL_VENDOR);
  if (vendor != NULL)
    mgDebug(":OpenGL device vendor: %s", (const char*) vendor);
  const char* renderer = (const char*) glGetString(GL_RENDERER);
  if (renderer != NULL)
    mgDebug(":OpenGL device renderer: %s", (const char*) renderer);
  const char* versionStr = (const char*) glGetString(GL_VERSION);
  if (versionStr != NULL)
    mgDebug(":OpenGL version: %s", (const char*) versionStr);
  const char* shaderVersionStr = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
  if (shaderVersionStr != NULL)
    mgDebug(":OpenGL shader version: %s", (const char*) shaderVersionStr);

// report all the GL limits
  GLint value;
#define GLREPORT(sym) value = INT_MAX; glGetIntegerv(sym, &value); if (value != INT_MAX) mgDebug(":%s: %d", #sym, value);
  GLREPORT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
  GLREPORT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_VARYING_COMPONENTS);
  GLREPORT(GL_MAX_COMBINED_UNIFORM_BLOCKS);
  GLREPORT(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
  GLREPORT(GL_MAX_DRAW_BUFFERS);
  GLREPORT(GL_MAX_ELEMENTS_INDICES);
  GLREPORT(GL_MAX_ELEMENTS_VERTICES);
  GLREPORT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
  GLREPORT(GL_MAX_FRAGMENT_INPUT_COMPONENTS);
  GLREPORT(GL_MIN_PROGRAM_TEXEL_OFFSET);
  GLREPORT(GL_MAX_PROGRAM_TEXEL_OFFSET);
  GLREPORT(GL_MAX_RECTANGLE_TEXTURE_SIZE);
  GLREPORT(GL_MAX_TEXTURE_IMAGE_UNITS);
  GLREPORT(GL_MAX_TEXTURE_LOD_BIAS);
  GLREPORT(GL_MAX_TEXTURE_SIZE);
  GLREPORT(GL_MAX_RENDERBUFFER_SIZE);
  GLREPORT(GL_MAX_ARRAY_TEXTURE_LAYERS);
  GLREPORT(GL_MAX_TEXTURE_BUFFER_SIZE);
  GLREPORT(GL_MAX_UNIFORM_BLOCK_SIZE);
  GLREPORT(GL_MAX_VARYING_FLOATS);
  GLREPORT(GL_MAX_VERTEX_ATTRIBS);
  GLREPORT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
  GLREPORT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS);
  GLREPORT(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_VERTEX_OUTPUT_COMPONENTS);
  GLREPORT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS);
  GLREPORT(GL_MAX_SAMPLE_MASK_WORDS);
  GLREPORT(GL_MAX_COLOR_TEXTURE_SAMPLES);
  GLREPORT(GL_MAX_DEPTH_TEXTURE_SAMPLES);
  GLREPORT(GL_MAX_DEPTH_TEXTURE_SAMPLES);
  GLREPORT(GL_MAX_INTEGER_SAMPLES);
  GLREPORT(GL_MAX_UNIFORM_BUFFER_BINDINGS);
  GLREPORT(GL_MAX_UNIFORM_BLOCK_SIZE);
  GLREPORT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
  GLREPORT(GL_MAX_VERTEX_UNIFORM_BLOCKS);
  GLREPORT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS);
  GLREPORT(GL_MAX_GEOMETRY_INPUT_COMPONENTS);
  GLREPORT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS);

#undef GLREPORT
  return true;
}