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";
}
실제로 질문에 코드를 포함해야합니다.이 링크는 곧 무효화되는 경향이 있지만,이 사이트의 질문과 대답은 다른 사람들이 유사한 문제를 해결할 수 있도록 장시간 머무를 예정입니다. – derhass
Noted. 방금 많은 양의 코드를 게시하는 것이 좋은 아이디어는 아니라고 생각했습니다. – Stealthmate