GlxContext::GlxContext(GlxContext* shared) : m_window (0), m_context (NULL), m_ownsWindow(true) { // Open a connection with the X server m_display = OpenDisplay(); m_connection = XGetXCBConnection(m_display); xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); // Choose the visual according to the context settings XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); // Define the window attributes xcb_colormap_t colormap = xcb_generate_id(m_connection); xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); const uint32_t value_list[] = {colormap}; // Create a dummy window (disabled and hidden) m_window = xcb_generate_id(m_connection); xcb_create_window( m_connection, static_cast<uint8_t>(visualInfo.depth), m_window, screen->root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualInfo.visualid, XCB_CW_COLORMAP, value_list ); // Create the context createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); }
void GlxContext::createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel) { m_display = OpenDisplay(); m_connection = XGetXCBConnection(m_display); // Choose the visual according to the context settings XVisualInfo visualInfo = selectBestVisual(m_display, bitsPerPixel, m_settings); // Check if the shared context already exists and pbuffers are supported if (shared && (sfglx_ext_SGIX_pbuffer == sfglx_LOAD_SUCCEEDED)) { // There are no GLX versions prior to 1.0 int major = 0; int minor = 0; glXQueryVersion(m_display, &major, &minor); // Check if glXCreatePbuffer is available (requires GLX 1.3 or greater) bool hasCreatePbuffer = ((major > 1) || (minor >= 3)); if (hasCreatePbuffer) { // Get a GLXFBConfig that matches the visual GLXFBConfig* config = NULL; // We don't supply attributes to match against, since // the visual we are matching against was already // deemed suitable in selectBestVisual() int nbConfigs = 0; GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), NULL, &nbConfigs); for (int i = 0; configs && (i < nbConfigs); ++i) { XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]); if (!visual) continue; if (visual->visualid == visualInfo.visualid) { config = &configs[i]; break; } } if (config) { int attributes[] = { GLX_PBUFFER_WIDTH, static_cast<int>(width), GLX_PBUFFER_HEIGHT, static_cast<int>(height), 0, 0 }; m_pbuffer = glXCreatePbuffer(m_display, *config, attributes); updateSettingsFromVisualInfo(&visualInfo); XFree(configs); return; } if (configs) XFree(configs); } } // If pbuffers are not available we use a hidden window as the off-screen surface to draw to xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); // Define the window attributes xcb_colormap_t colormap = xcb_generate_id(m_connection); xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); const uint32_t value_list[] = {colormap}; // Create a dummy window (disabled and hidden) m_window = xcb_generate_id(m_connection); xcb_create_window( m_connection, static_cast<uint8_t>(visualInfo.depth), m_window, screen->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualInfo.visualid, XCB_CW_COLORMAP, value_list ); m_ownsWindow = true; updateSettingsFromWindow(); }