2015-01-25 23 views
1

X 용으로 자체 창 래퍼 종류를 작성하기로 결정했습니다. OpenGL 3.0을 만들기 위해이 예제를 opengl.org에서 사용했습니다 문맥을 시작점으로하고, 내 코드의 일부는이 거기부터 순수 복사 붙여 넣기입니다. 예제를 그대로 사용해 보았지만 효과가있었습니다.하지만 여기서 내가 잘못하고있는 것을 실제로 알지 못합니다. 기본적으로 발생하는 현상은 다음과 같습니다.glXMakeCurrent() 및 glXSwapBuffers() BadMatch (잘못된 매개 변수 특성) throwing segfault

기본 디스플레이에 연결됩니다.

창 만들기에 사용할 XVisualInfo 포인터를 초기화합니다.

나는 반환하는 프레임 버퍼 구성을 사용하여 GLXContext 변수를 초기화 상기 시각 glXGetVisualFromConfig를 호출 할 때()

나는 말했다 시각 및 일부 속성을 사용하여 창을 만들 수 있습니다.

glXMakeCurrent()를 호출하고 BadMatch (잘못된 매개 변수 특성)를 throw합니다. 또는 segfault라고하는 자체 오류 처리기를 사용합니다.

은 내가 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를 throw하지 않습니다.

#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"; 
} 
+0

실제로 질문에 코드를 포함해야합니다.이 링크는 곧 무효화되는 경향이 있지만,이 사이트의 질문과 대답은 다른 사람들이 유사한 문제를 해결할 수 있도록 장시간 머무를 예정입니다. – derhass

+0

Noted. 방금 많은 양의 코드를 게시하는 것이 좋은 아이디어는 아니라고 생각했습니다. – Stealthmate

답변

1

당신은 실제로 시각을 기반으로 XColorMap를 만들 :

여기 내 코드입니다. 그러나 XCreateWindow을 호출 할 때 CWColorMap 특성 비트를 설정하지 않으므로이 색 맵은 창을 만들 때 사용되지 않습니다. 이로 인해 해당 비주얼에 대해 생성 된 GL 컨텍스트와 호환되지 않는 창이 발생할 수 있습니다.

+0

나는 솔직히 내가 얼마나 어리 석 었는지 믿을 수 없다. 너, 나의 하루를 구했다. 나는 고맙다. – Stealthmate