调用XCreateWindow()时产生的GLX错误的XLib

时间:2012-02-21 19:52:27

标签: c++ c opengl xlib glx

从原始帖子编辑和简化:

我收到以下错误:

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对象

#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);
    }
}
  

窗口对象

#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对象

#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
                );
}
  

驱动器

#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属性的问题。

1 个答案:

答案 0 :(得分: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;
}

刚从CWCursor中取出valuemask

this page的启发。