static support_mode is_supported(const char *extensions, const array<long, 2> &version, const char *name, long major, long minor, long major_es, long minor_es) { #if DXX_USE_OGLES static_cast<void>(major); static_cast<void>(minor); if ( (major_es > 0) && ((version[0] > major_es) || (version[0] == major_es && version[1] >= minor_es)) ) return SUPPORT_CORE; #else static_cast<void>(major_es); static_cast<void>(minor_es); if ( (major > 0) && ((version[0] > major) || (version[0] == major && version[1] >= minor)) ) return SUPPORT_CORE; #endif if (is_ext_supported(extensions, name)) return SUPPORT_EXT; return NO_SUPPORT; }
int main() { GLXFBConfig fbconfig; Vec2u screen_dim { 1200, 900 }; // create window { int buffer_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 }; g_pctx.display = XOpenDisplay(NULL); if (!g_pctx.display) zabort("failed to create display"); int xscreen = XDefaultScreen(g_pctx.display), num_fbconfigs; GLXFBConfig *fbconfigs = glXChooseFBConfig(g_pctx.display, xscreen, buffer_attribs, &num_fbconfigs); if (!fbconfigs) zabort("Failed to retrieve frame buffer configs"); int best_fbc = -1, best_num_samp = -1; for (int i = 0; i < num_fbconfigs; ++i) { XVisualInfo *visual = glXGetVisualFromFBConfig(g_pctx.display, fbconfigs[i]); if (visual) { int samp_buf, samples; glXGetFBConfigAttrib(g_pctx.display, fbconfigs[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(g_pctx.display, fbconfigs[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(visual); } if (best_fbc < 0) zabort("failed to get a frame buffer"); fbconfig = fbconfigs[0]; XFree(fbconfigs); XVisualInfo *visual = glXGetVisualFromFBConfig(g_pctx.display, fbconfig); Window root = DefaultRootWindow(g_pctx.display); XSetWindowAttributes win_attribs; win_attribs.colormap = XCreateColormap(g_pctx.display, root, visual->visual, AllocNone); win_attribs.background_pixmap = None; win_attribs.border_pixmap = None; win_attribs.border_pixel = 0; win_attribs.event_mask = StructureNotifyMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | KeyPressMask | KeyReleaseMask; int win_attribs_mask = CWBackPixmap| CWColormap| CWBorderPixel| CWEventMask; assert(visual->c_class == TrueColor); g_pctx.window = XCreateWindow(g_pctx.display, root, 0, 0, screen_dim.x, screen_dim.y, 0, visual->depth, InputOutput, visual->visual, win_attribs_mask, &win_attribs); if (!g_pctx.window) zabort("Failed to create a window.\n"); XFree(visual); XStoreName(g_pctx.display, g_pctx.window, "cge"); XMapWindow(g_pctx.display, g_pctx.window); if ((g_pctx.wm_delete_window = XInternAtom(g_pctx.display, "WM_DELETE_WINDOW", 1))) XSetWMProtocols(g_pctx.display, g_pctx.window, &g_pctx.wm_delete_window, 1); else zerror("Unable to register WM_DELETE_WINDOW atom"); } // Create OpenGL context. { int major_ver, minor_ver; if (!glXQueryVersion(g_pctx.display, &major_ver, &minor_ver)) zabort("Unable to query GLX version"); if ((major_ver == 1 && minor_ver < 3) || major_ver < 1) zabort("GLX version is too old"); // Install a new error handler so that the program doesn't just exit if we fail to get a 3.1 context. // Note this error handler is global. All display connections in all threads of a process use the same error handler. ctx_error_occured = false; int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctx_error_handler); const char *gl_exts = glXQueryExtensionsString(g_pctx.display, XDefaultScreen(g_pctx.display)); if (!is_ext_supported(gl_exts, "GLX_ARB_create_context")) zabort("OpenGL does not support glXCreateContextAttribsARB extension"); int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB"); if (!glXCreateContextAttribsARB) zabort("Could not load glXCreateContextAttribsARB"); g_pctx.gl_context = NULL; g_pctx.gl_context = glXCreateContextAttribsARB(g_pctx.display, fbconfig, 0, True, context_attribs); XSync(g_pctx.display, False); if (ctx_error_occured || !g_pctx.gl_context) zabort("Failed to create OpenGL context"); XSetErrorHandler(old_handler); glXMakeCurrent(g_pctx.display, g_pctx.window, g_pctx.gl_context); } // Load OpenGL functions. #define LOADPROC #include "glprocs.h" #undef LOADPROC main_loop(screen_dim); platform_exit(); return 0; }