【问题标题】:XLib with GLX Error Produced when Calling XCreateWindow()调用 XCreateWindow() 时产生带有 GLX 错误的 XLib
【发布时间】:2012-02-21 19:52:27
【问题描述】:

从原始帖子编辑和简化:

我收到以下错误:

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() 时,代码在窗口对象中崩溃(见下文):

应用对象

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

【问题讨论】:

  • 发布一个完整的、最小的示例来演示该问题。
  • 我正试图这样做。我有一个简单的 c 示例,我将其封装在类中。 C 代码保持不变,但当放在我的类中时,一切都崩溃了。我试图理解为什么。我会看看我能做什么。
  • @genpfault:我已将示例更新为我正在尝试做的最简单的形式,并且能够重现错误。非常感谢您的进一步见解。

标签: c++ c opengl xlib glx


【解决方案1】:

这对我来说不会出错:

// 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;
}

刚刚从valuemask 中取出CWCursor

灵感来自this page

【讨论】:

  • 什么操作系统,你有来自 NVida/Radeon 的驱动程序吗?
  • Debian 稳定版,软件 Mesa (7.7.1) over VNC。
  • 好的,我的 Ubuntu 10.04 lappy w/Sandy Bridge 图形失败了。
  • 过去几天我一直在测试/调试我的应用程序。似乎发行版之间的行为和编译存在很多差异。我现在让它在计时器上渲染。但是当我在 RHEL 6.1 上快速移动窗口时,渲染循环会崩溃。在 Ubuntu 10.04 上没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
  • 1970-01-01
相关资源
最近更新 更多