2012-02-21 51 views
1

編輯時從原來的職位簡化生產GLX錯誤:XLIB與調用XCreateWindow()

我收到以下錯誤:

X Error of failed request: BadMatch (invalid parameter attributes) 
    Major opcode of failed request: 1 (X_CreateWindow) 
    Serial number of failed request: 38 
    Current serial number in output stream: 41 

從我的角度來看,代碼在崩潰使用下面的代碼窗口對象(見下文)調用XCreateWindow()時:

app object

#ifndef APP_H 
#define APP_H 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <X11/Xlib.h> 
#include <GL/glx.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 

class app 
{ 
public: 
    app(); 
    void run(); 
    Display *getDisplay(); 
    Display *_xDisplay; 
}; 

#endif // APP_H 

#include "app.h" 

app::app() 
{ 
    _xDisplay = XOpenDisplay(NULL); 
    if (_xDisplay == NULL) 
     throw "Failed to get XDisplay"; 
} 

Display *app::getDisplay() 
{ 
    return _xDisplay; 
} 

void app::run() 
{ 
    static bool run = true; 
    static Display *lDisplay = _xDisplay; 
    XEvent xEvent; 
    while (run) 
    { 
     do 
     { 
      XNextEvent(lDisplay, &xEvent); 
      switch (xEvent.type) 
      { 
      } 
     } while (_xDisplay); 
    } 
} 

window object

#ifndef WINDOW_H 
#define WINDOW_H 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <X11/Xlib.h> 
#include <GL/glx.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include "app.h" 

class app; 
class ogldevice; 

class window 
{ 
public: 
    window(app *a); 
    app *a; 
    ogldevice *od; 
    Window xWindow; 
}; 

#endif // WINDOW_H 

#include "window.h" 
#include "ogldevice.h" 

window::window(app *a) : 
    a(a) 
{ 
    int width = 800; 
    int height = 800; 
    od = new ogldevice(a); 

    Display *xDisplay = a->getDisplay(); 
    unsigned long valuemask = CWEventMask | CWBackPixel | CWBorderPixel | CWCursor; 

    XSetWindowAttributes xAttributes; 
    xAttributes.border_pixel = 0; 
    xAttributes.colormap = od->glxDevice.glxColorMap; 
    xAttributes.event_mask = ExposureMask | KeyPressMask | ButtonPress | 
           StructureNotifyMask | ButtonReleaseMask | 
           KeyReleaseMask | EnterWindowMask | LeaveWindowMask | 
           PointerMotionMask | Button1MotionMask | VisibilityChangeMask | 
           ColormapChangeMask; 

    xWindow = XCreateWindow(
       xDisplay, 
       RootWindow(xDisplay, od->glxDevice.xVisual->screen), 
       0, 0, 
       width, height, 
       0, 
       od->glxDevice.xVisual->depth, 
       InputOutput, 
       od->glxDevice.xVisual->visual, 
       valuemask, 
       &xAttributes 
       ); 

     XSetStandardProperties(
        xDisplay, 
        xWindow, 
        "glxsimple", 
        "glxsimple", 
        None, 
        NULL, 
        0, 
        NULL 
       ); 

     XMapWindow(a->getDisplay(), xWindow); 
} 

ogldevice object

#ifndef OGLDEVICE_H 
#define OGLDEVICE_H 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <X11/Xlib.h> 
#include <GL/glx.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 

class app; 

class ogldevice 
{ 
public: 
    ogldevice(app *a); 
    struct GlxDevice 
    { 
     XVisualInfo *xVisual; 
     Colormap glxColorMap; 
     GLXContext glxContext; 
    } glxDevice; 
    app *a; 
}; 

#endif // OGLDEVICE_H 

#include "ogldevice.h" 
#include "app.h" 

ogldevice::ogldevice(app *a) : 
    a(a) 
{ 
    int errno, extension; 
    if (!glXQueryExtension(a->getDisplay(), &errno, &extension)) 
    { 
     throw "Glx Extension not Supported"; 
    } 

    static int glx_attributes[] = { 
     GLX_RGBA, 
     GLX_RED_SIZE, 4, 
     GLX_GREEN_SIZE, 4, 
     GLX_BLUE_SIZE, 4, 
     GLX_DOUBLEBUFFER, 
     None 
    }; 

    glxDevice.xVisual = glXChooseVisual(
       a->getDisplay(), 
       DefaultScreen(a->getDisplay()), 
       glx_attributes 
       ); 

    if (glxDevice.xVisual == NULL) 
     throw "Failure to get Double Buffer"; 

    glxDevice.glxContext = glXCreateContext(
       a->getDisplay(), 
       glxDevice.xVisual, 
       None, /* Don't share display lists */ 
       True 
       ); 

    if (glxDevice.glxContext == NULL) 
     throw "Failure to get GLX Context"; 

    glxDevice.glxColorMap = XCreateColormap(
       a->getDisplay(), 
       RootWindow(a->getDisplay(), glxDevice.xVisual->screen), 
       glxDevice.xVisual->visual, 
       AllocNone 
       ); 
} 

driver

#include "app.h" 
#include "window.h" 

int main(int argc, char *argv[]) 
{ 
    app *a = new app(); 
    window *w = new window(a); 
    a->run(); 

    delete a; 
    delete w; 

    return 0; 
} 

我的Fedora 14,RHEL 6.1和Ubuntu 10.04 LTS運行時,得到同樣的錯誤。這導致我相信這是我傳遞給glxChooseVisual的glx屬性的一個問題。

+0

發佈一個完整的,最小的示例來演示問題。 – genpfault 2012-02-21 20:06:33

+0

我正在努力做到這一點。我有一個簡單的例子,我拿了包裝在課堂上。 C代碼保持不變,但是當放在我的課堂時,它全部崩潰。我試圖理解爲什麼。我會看看我能做些什麼。 – user1224210 2012-02-21 20:18:03

+0

@genpfault:我已將示例更新爲我正在嘗試執行的最簡單形式,並且能夠重現錯誤。您的進一步洞察力非常令人滿意。 – user1224210 2012-02-21 20:58:59

回答

0

這並不會報錯了我:

// compile like so: 
// g++ gltest.cpp -lX11 -lGL 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <X11/Xlib.h> 
#include <GL/glx.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 


class app 
{ 
public: 
    app() 
    { 
     _xDisplay = XOpenDisplay(NULL); 
     if (_xDisplay == NULL) 
      throw "Failed to get XDisplay"; 
    } 

    void run() 
    { 
     static bool run = true; 
     static Display *lDisplay = _xDisplay; 
     XEvent xEvent; 
     while (run) 
     { 
      do 
      { 
       XNextEvent(lDisplay, &xEvent); 
       switch (xEvent.type) 
       { 
       } 
      } while (_xDisplay); 
     } 
    } 

    Display *getDisplay() 
    { 
     return _xDisplay; 
    } 

    Display *_xDisplay; 
}; 


class ogldevice 
{ 
public: 
    ogldevice(app *a) : a(a) 
    { 
     int errno, extension; 
     if (!glXQueryExtension(a->getDisplay(), &errno, &extension)) 
     { 
      throw "Glx Extension not Supported"; 
     } 

     static int glx_attributes[] = 
      { 
      GLX_RGBA, 
      GLX_RED_SIZE, 4, 
      GLX_GREEN_SIZE, 4, 
      GLX_BLUE_SIZE, 4, 
      GLX_DOUBLEBUFFER, 
      None 
      }; 

     glxDevice.xVisual = glXChooseVisual 
      (
      a->getDisplay(), 
      DefaultScreen(a->getDisplay()), 
      glx_attributes 
      ); 

     if (glxDevice.xVisual == NULL) 
      throw "Failure to get Double Buffer"; 

     glxDevice.glxContext = glXCreateContext 
      (
      a->getDisplay(), 
      glxDevice.xVisual, 
      None, /* Don't share display lists */ 
      True 
      ); 

     if (glxDevice.glxContext == NULL) 
      throw "Failure to get GLX Context"; 

     glxDevice.glxColorMap = XCreateColormap 
      (
      a->getDisplay(), 
      RootWindow(a->getDisplay(), glxDevice.xVisual->screen), 
      glxDevice.xVisual->visual, 
      AllocNone 
      ); 
    } 

    struct GlxDevice 
    { 
     XVisualInfo *xVisual; 
     Colormap glxColorMap; 
     GLXContext glxContext; 
    } glxDevice; 

    app *a; 
}; 


class window 
{ 
public: 
    window(app *a) : a(a) 
    { 
     int width = 800; 
     int height = 800; 
     od = new ogldevice(a); 

     Display *xDisplay = a->getDisplay(); 
     unsigned long valuemask = CWEventMask | CWBackPixel | CWBorderPixel; 

     XSetWindowAttributes xAttributes; 
     xAttributes.border_pixel = 0; 
     xAttributes.colormap = od->glxDevice.glxColorMap; 
     xAttributes.event_mask = 
      ExposureMask | KeyPressMask | ButtonPress | 
      StructureNotifyMask | ButtonReleaseMask | 
      KeyReleaseMask | EnterWindowMask | LeaveWindowMask | 
      PointerMotionMask | Button1MotionMask | VisibilityChangeMask | 
      ColormapChangeMask; 

     xWindow = XCreateWindow 
      (
      xDisplay, 
      RootWindow(xDisplay, od->glxDevice.xVisual->screen), 
      0, 0, 
      width, height, 
      0, 
      od->glxDevice.xVisual->depth, 
      InputOutput, 
      od->glxDevice.xVisual->visual, 
      valuemask, 
      &xAttributes 
      ); 

     XSetStandardProperties 
      (
      xDisplay, 
      xWindow, 
      "glxsimple", 
      "glxsimple", 
      None, 
      NULL, 
      0, 
      NULL 
      ); 

     XMapWindow(a->getDisplay(), xWindow); 
    } 

    app *a; 
    ogldevice *od; 
    Window xWindow; 
}; 


int main(int argc, char *argv[]) 
{ 
    app *a = new app(); 
    window *w = new window(a); 
    a->run(); 

    delete a; 
    delete w; 

    return 0; 
} 

剛接手CWCursorvaluemask

this page的啓發。

+0

什麼操作系統,你有NVida/Radeon的驅動程序? – user1224210 2012-02-21 22:34:51

+0

Debian Stable,通過VNC的軟件Mesa(7.7.1)。 – genpfault 2012-02-21 22:38:03

+0

好的,在我的Ubuntu 10.04 lappy w/Sandy Bridge圖形上失敗。 – genpfault 2012-02-22 03:47:59