【问题标题】:glXMakeCurrent() and glXSwapBuffers() throwing BadMatch (invalid parameter attributes) segfaultglXMakeCurrent() 和 glXSwapBuffers() 抛出 BadMatch(无效参数属性)段错误
【发布时间】:2015-12-18 18:00:47
【问题描述】:

我决定为 X 编写自己的窗口包装器类型的东西。我使用 opengl.org 中的示例来创建 OpenGL 3.0 上下文作为起点,并且一些我的代码是从那里纯粹复制粘贴的。我已经按原样尝试了这个示例并且它有效,但我真的不知道我在这里做错了什么。 基本上发生的是这样的:

我连接到默认显示器。

我初始化了一个 XVisualInfo 指针以用于创建窗口。

我使用帧缓冲配置初始化了一个 GLXContext 变量,它在调用 glXGetVisualFromConfig() 时返回所述视觉对象

我创建了一个窗口,使用上述视觉效果和一些属性。

我调用 glXMakeCurrent() 并抛出一个 BadMatch(无效参数属性)或者我使用我自己的错误处理程序,它说这是一个段错误。

我尝试跳过 glxMakeCurrent(),但它在 glXSwapBuffers() 上抛出相同的错误

具体错误如下:

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

我在这里完全没有想法。根据this,glXSwapBuffers 不应该抛出 BadMatch。

这是我的代码:

#include "X_Window.h"
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include < unistd.h >
#include < X11/Xlib.h >
#include < X11/Xutil.h >
#include  <GL/gl.h >
#include < GL/glx.h >
#include < iostream >

using namespace Deva;
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
//static bool isDisplayInitialized = 0;
static Display* display = 0;
static GLXContext context = 0;
static XVisualInfo* vinfo = 0;
static GLXFBConfig bestFbc = 0;



static bool isExtensionSupported(const char *extList, const char *extension)
{
    const char *start;
    const char *where, *terminator;

    where = strchr(extension, ' ');
    if (where || *extension == '\0')
        return false;

    for (start=extList;;)
    {
        where = strstr(start, extension);

        if (!where)
            break;

        terminator = where + strlen(extension);

        if ( where == start || *(where - 1) == ' ' )
            if ( *terminator == ' ' || *terminator == '\0' )
                return true;

        start = terminator;
    }

    return false;
}

static bool contextErrorOccurred = false;
static int contextErrorHandler( Display *dpy, XErrorEvent *ev )
{
    contextErrorOccurred = true;
    char * text;
    XGetErrorText(dpy, ev->error_code, text, 300);
    std::cout << text << std::endl;
    return 0;
}


static void initializeVisualInfo()
{
    static int visual_attribs[] =
    {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
        GLX_RED_SIZE        , 8,
        GLX_GREEN_SIZE      , 8,
        GLX_BLUE_SIZE       , 8,
        GLX_ALPHA_SIZE      , 8,
        GLX_DEPTH_SIZE      , 24,
        GLX_STENCIL_SIZE    , 8,
        GLX_DOUBLEBUFFER    , True,
        //GLX_SAMPLE_BUFFERS  , 1,
        //GLX_SAMPLES         , 4,
        None
    };

    int glx_major, glx_minor;

    if ( !glXQueryVersion( display, &glx_major, &glx_minor ) ||
            ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
    {
        printf("Invalid GLX version");
        exit(1);
    }

    int fbcount;
    GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);

    if (!fbc) exit(1);

    int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;

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

            if ( best_fbc < 0 || samp_buf && samples > best_num_samp )
                best_fbc = i, best_num_samp = samples;
            if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
                worst_fbc = i, worst_num_samp = samples;
        }
        XFree( vi );
    }
    bestFbc = fbc[ best_fbc ];

    XFree( fbc );

    vinfo = glXGetVisualFromFBConfig( display, bestFbc );
}

static void initializeContext()
{
    const char *glxExts = glXQueryExtensionsString( display,
                          DefaultScreen( display ) );

    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
    glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
                                 glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );

    context = 0;

    contextErrorOccurred = false;
    //int (*oldHandler)(Display*, XErrorEvent*) =
    //   XSetErrorHandler(&contextErrorHandler);

    if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
            !glXCreateContextAttribsARB )
    {
        context = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
    }

    else
    {
        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
        };

        context = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs);

        XSync( display, False );

        if ( !contextErrorOccurred && context );
        else
        {
            context_attribs[1] = 1;
            context_attribs[3] = 0;
            contextErrorOccurred = false;
            context = glXCreateContextAttribsARB( display, bestFbc, 0,
                                                  True, context_attribs );
        }
    }

    XSync( display, False );
}

DevaWindow* DevaWindow::createWindow(unsigned int width,
                                     unsigned int height,
                                     char window_name[],
                                     int x,
                                     int y)
{
    display = XOpenDisplay(NULL);
    if(!display)
    {
        std::cout << "Couldn't connect to display. Exiting...\n";
        exit(EXIT_FAILURE);
    }
    if(!vinfo) initializeVisualInfo();
    if(!context) initializeContext();
    return new DevaWindow(width, height, window_name, x, y);
}

DevaWindow::DevaWindow(
    unsigned int width,
    unsigned int height,
    char window_name[],
    int x,
    int y
) : width(width), height(height)
{

    //auto screen_num = DefaultScreen(display);
    XSetWindowAttributes attributes;
    attributes.background_pixmap = None;
    attributes.background_pixel = BlackPixel(display, vinfo->screen);
    attributes.border_pixmap = None;
    attributes.border_pixel = WhitePixel(display, vinfo->screen);
    attributes.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
    Colormap cmap;
    attributes.colormap = cmap = XCreateColormap( display,
                                 RootWindow( display, vinfo->screen ),
                                 vinfo->visual, AllocNone );

    unsigned long valuemask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBorderPixel | CWEventMask;

    std::cout << "VisualID Windows " << vinfo->visual->visualid << std::endl;
    window = XCreateWindow(display,
                           RootWindow(display, vinfo->screen),
                           x, y,
                           width, height,
                           2,
                           vinfo->depth,
                           InputOutput,
                           vinfo->visual,
                           valuemask,
                           &attributes);
    std::cout << "VIsual Window: " << vinfo <<std::endl;

    //XChangeWindowAttributes(display, window, valuemask, &attributes);

    XMapWindow(display, window);
    XEvent evnt;
    //XNextEvent(display, &evnt);
}

void DevaWindow::update()
{
    glXSwapBuffers(display, window);
    std::cout << "WHYYYYYYYYYYYYYY\n";
}

void DevaWindow::setContext()
{
    printf("Display %d, Window %i, Context %i\n", display, window, context);
    glXMakeCurrent(display, window, context);
    std::cout << "Good\n";
}

【问题讨论】:

  • 您实际上应该在问题中包含代码,那些链接往往很快就会失效,而本网站上的问题和答案旨在长期保留,以帮助其他有类似问题的人.
  • 注明。我只是认为发布大量代码不是一个好主意。

标签: opengl segmentation-fault glx


【解决方案1】:

您实际上基于视觉创建了一个XColorMap。但是,在调用XCreateWindow 时,您没有设置CWColorMap 属性位,因此在创建窗口时不会使用此颜色图。这可能会导致窗口与为该视觉对象创建的 GL 上下文不兼容。

【讨论】:

  • 我真的不敢相信我是多么愚蠢。先生,您拯救了我的一天。我很感激。
猜你喜欢
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多