xdl_int XdevLOpenGLWGL::create(XdevLWindow* window) { if(window == NULL) { XDEVL_MODULE_ERROR("Parameter invalid.\n"); return ERR_ERROR; } m_window = window; m_wnd = static_cast<HWND>(m_window->getInternal(XdevLInternalName("WIN32_HWND"))); if ( m_wnd == NULL) { XDEVL_MODULE_ERROR("Get WIN32_HWND failed.\n"); return ERR_ERROR; } if (initOpenGL() == ERR_ERROR) { XDEVL_MODULE_ERROR("Failed to initialize OpenGL.\n"); return ERR_ERROR; } // Set vertical syncronisation. setVSync(getVSync()); // TODO: This shouldn't be done maybe because it changes the initial state of the OpenGL context. glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(m_DC); return ERR_OK; }
xdl_int XdevLBluetoothMacOSXImpl::readInfoFromXMLFile() { if(getMediator()->getXmlFilename() == NULL) return ERR_ERROR; TiXmlDocument xmlDocument; if(!xmlDocument.LoadFile(getMediator()->getXmlFilename())) { XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl); return ERR_ERROR; } TiXmlHandle docHandle(&xmlDocument); TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLBluetooth").ToElement(); if (!root) { XDEVL_MODULE_WARNING("<XdevLBluetooth> section not found. Using default values for the device.\n"); return ERR_OK; } while(root != NULL) { if(root->Attribute("id")) { XdevLID id(root->Attribute("id")); if(getID() == id) { if (root->Attribute("device")) { m_deviceName = root->Attribute("device"); } } root = root->NextSiblingElement(); } else XDEVL_MODULE_ERROR("No 'id' attribute specified. Using default values for the device\n"); } return ERR_OK; }
xdl_int XdevLCudaImpl::readModuleInformation(TiXmlDocument* document) { TiXmlHandle docHandle(document); TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLOpenGL").ToElement(); if (!root) { XDEVL_MODULE_INFO("<XdevLCuda> section not found, skipping proccess.\n"); return ERR_OK; } if(root->Attribute("id")){ XdevLModuleId id(root->Attribute("id")); if(*getId() != id){ return ERR_OK; } }else{ XDEVL_MODULE_ERROR("No 'id' attribute specified."); return ERR_ERROR; } // if (root->Attribute("framebuffer_depth")){ // m_ColorDepth = xstd::from_string<xdl_int>(root->Attribute("framebuffer_depth")); // XDEVL_MODULE_INFO("Framebuffer depth request: " << m_ColorDepth << std::endl); // } return ERR_OK; }
xdl_int XdevLWindowWayland::createAnonymousFile(off_t size) { static const char tmp[] = "/weston-shared-XXXXXX"; const char *path; char *name; int fd; path = getenv("XDG_RUNTIME_DIR"); if(!path) { XDEVL_MODULE_ERROR("XDG_RUNTIME_DIR environment variable not found.\n"); return -1; } name = (char*)malloc(strlen(path) + sizeof(tmp)); if(!name) { return -1; } strcpy(name, path); strcat(name, tmp); fd = createTmpFileCloExec(name); free(name); if(fd < 0) return -1; if(ftruncate(fd, size) < 0) { close(fd); return -1; } return fd; }
xdl_int XdevLOpenGLWGL::makeCurrent(XdevLWindow* window) { // Try To Activate The Rendering Context if (wglMakeCurrent(m_DC, m_RC) != TRUE) { XDEVL_MODULE_ERROR("wglMakeCurrent failed.\n"); return ERR_ERROR; } return ERR_OK; }
xdl_int XdevLOpenGLWGL::shutdown() { if (m_RC) { if (!wglMakeCurrent(NULL, NULL)) { XDEVL_MODULE_ERROR("wglMakeCurrent() failed.\n"); return ERR_ERROR; } if (!wglDeleteContext( m_RC)) { XDEVL_MODULE_ERROR("wglDeleteContext() failed.\n"); return ERR_ERROR; } } m_RC = NULL; if ( m_DC && !ReleaseDC( m_wnd, m_DC)) { XDEVL_MODULE_ERROR("ReleaseDC() failed.\n"); return ERR_ERROR; } m_DC = NULL; return ERR_OK; }
int XdevLOpenGLContextGLX::create(XdevLWindow* window, XdevLOpenGLContext* shareContext) { XDEVL_ASSERT(m_display == nullptr, "XdevLOpenGLContextGLX already created."); if(nullptr != shareContext) { m_shareContext = static_cast<XdevLOpenGLContextGLX*>(shareContext); } window->getDescriptor().registerDependency(this); m_display = static_cast<Display*>(window->getInternal(XdevLInternalName("X11_DISPLAY"))); if(nullptr == m_display) { XDEVL_MODULE_ERROR("Could not get native X11 display information.\n"); return RET_FAILED; } m_window = (Window)(window->getInternal(XdevLInternalName("X11_WINDOW"))); if(None == m_window) { XDEVL_MODULE_ERROR("Could not get native X11 window information.\n"); return RET_FAILED; } if(glXQueryVersion(m_display, &m_glxMajorVersion, &m_glxMinorVersion) == False) { XDEVL_MODULE_ERROR("glXQueryVersion failed.\n"); return RET_FAILED; } if(initOpenGL(m_display, m_window) == RET_FAILED) { XDEVL_MODULE_ERROR("Failed to initialize OpenGL.\n"); return RET_FAILED; } if(glXIsDirect(m_display, m_glxContext)) { XDEVL_MODULE_INFO("Direct Rendering supported.\n"); } else { XDEVL_MODULE_WARNING("Direct Rendering not supported.\n"); } setVSync(getVSync()); return RET_SUCCESS; }
xdl_int XdevLWindowWayland::createBuffer() { // Couldn't create anonymous file. m_fd = createAnonymousFile(getWidth() * getHeight() * 4); if(-1 == m_fd) { XDEVL_MODULE_ERROR("mmap failed\n"); return ERR_ERROR; } // Couldn't map memory. m_shm_data = (xdl_uint8*)mmap(NULL, getWidth() * getHeight() * 4, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0); if(m_shm_data == MAP_FAILED) { XDEVL_MODULE_ERROR("mmap failed\n"); close(m_fd); return ERR_ERROR; } m_pool = wl_shm_create_pool(m_sharedMemory, m_fd, getWidth() * getHeight() * 4); m_buffer = wl_shm_pool_create_buffer(m_pool, 0, getWidth(), getHeight(), getWidth() * 4, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(m_pool); return ERR_OK; }
xdl_int XdevLCudaImpl::init() { TiXmlDocument xmlDocument; if (!xmlDocument.LoadFile(getMediator()->getXmlFilename())) { XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl); return ERR_ERROR; } if (readModuleInformation(&xmlDocument) != ERR_OK) return ERR_ERROR; cudaGetDevice(&m_devID); cudaGetDeviceProperties(&m_prop, m_devID); return ERR_OK; }
xdl_int XdevLFTDI::readInfoFromXMLFile() { if(getMediator()->getXmlFilename() == nullptr) return RET_FAILED; TiXmlDocument xmlDocument; if(!xmlDocument.LoadFile(getMediator()->getXmlFilename())) { XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl); return RET_FAILED; } TiXmlHandle docHandle(&xmlDocument); TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLSerial").ToElement(); if(!root) { XDEVL_MODULE_WARNING("<XdevLSerial> section not found. Using default values for the device.\n"); return RET_SUCCESS; } while(root != nullptr) { if(root->Attribute("id")) { XdevLID id(root->Attribute("id")); if(getID() == id) { if(root->Attribute("device")) { m_deviceName = XdevLString(root->Attribute("device")); } if(root->Attribute("usb_in_size")) { std::istringstream ss(root->Attribute("usb_in_size")); ss >> m_usbInSize; } if(root->Attribute("usb_out_size")) { std::istringstream ss(root->Attribute("usb_out_size")); ss >> m_usbOutSize; } if(root->Attribute("latency_timer")) { std::istringstream ss(root->Attribute("latency_timer")); ss >> m_latencyTimer; }
xdl_int XdevLOpenGLWGL::initOpenGL() { m_DC = GetDC(m_wnd); if(m_DC == NULL) { XDEVL_MODULE_ERROR("GetDC() failed."); return ERR_ERROR; } PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = m_attributes.color_buffer_size; pfd.cDepthBits = m_attributes.depth_size; pfd.cStencilBits = m_attributes.stencil_size; pfd.cRedBits = m_attributes.red_size; pfd.cGreenBits = m_attributes.green_size; pfd.cBlueBits = m_attributes.blue_size; pfd.cAlphaBits = m_attributes.alpha_size; pfd.iLayerType = PFD_MAIN_PLANE; int iPixelFormat = ChoosePixelFormat(m_DC, &pfd); if (FALSE == iPixelFormat) { XDEVL_MODULE_ERROR("ChoosePixelFormat failed.\n"); return ERR_ERROR; } if (SetPixelFormat(m_DC, iPixelFormat, &pfd) != TRUE) { XDEVL_MODULE_ERROR("SetPixelFormat failed.\n"); return ERR_ERROR; } // Create the old style context (OpenGL 2.1 and before) HGLRC hRC = wglCreateContext(m_DC); wglMakeCurrent(m_DC, hRC); wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); wglMakeCurrent(nullptr, nullptr); wglDeleteContext(hRC); if (wglCreateContextAttribsARB) { const int iPixelFormatAttribList[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB, WGL_COLOR_BITS_ARB, 32, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, WGL_ACCUM_BITS_ARB, 0, WGL_RED_BITS_ARB, m_attributes.red_size, WGL_GREEN_BITS_ARB, m_attributes.green_size, WGL_BLUE_BITS_ARB, m_attributes.blue_size, WGL_ALPHA_BITS_ARB, m_attributes.alpha_size, 0 // End of attributes list }; int iPixelFormat, iNumFormats; if (wglChoosePixelFormatARB(m_DC, iPixelFormatAttribList, NULL, 1, &iPixelFormat, (UINT*)&iNumFormats) != TRUE) { XDEVL_MODULE_ERROR("wglChoosePixelFormatARB failed.\n"); return ERR_ERROR; } // PFD seems to be only redundant parameter now if (SetPixelFormat(m_DC, iPixelFormat, &pfd) != TRUE) { XDEVL_MODULE_ERROR("SetPixelFormat failed.\n"); return ERR_ERROR; } // // Set the core profile attributes. // std::vector<xdl_int> contextAttributes; contextAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); contextAttributes.push_back(m_attributes.context_major_version); contextAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); contextAttributes.push_back(m_attributes.context_minor_version); contextAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) { contextAttributes.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB); } else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY) { contextAttributes.push_back(WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); } else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_ES1) { XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n"); return ERR_ERROR; } else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_ES2) { XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n"); return ERR_ERROR; } else { XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n"); return ERR_ERROR; } // // Set the WGL_CONTEXT_FLAGS_ARB // if (m_attributes.context_flags != XDEVL_OPENGL_CONTEXT_FLAGS_NONE || (m_debugMode == xdl_true)) { contextAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); if (m_debugMode == xdl_true) { contextAttributes.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); } if (m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT) { contextAttributes.push_back(WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); } } contextAttributes.push_back(0); m_RC = wglCreateContextAttribsARB(m_DC, 0, contextAttributes.data()); if (nullptr == m_RC) { XDEVL_MODULE_ERROR("wglCreateContextAttribsARB failed.\n"); return ERR_ERROR; } // If everything went OK if (wglMakeCurrent(m_DC, m_RC) != TRUE) { XDEVL_MODULE_ERROR("wglMakeCurrent failed.\n"); return ERR_ERROR; } } else { // Are We Able To Get A Rendering Context? m_RC = wglCreateContext(m_DC); if (nullptr == m_RC) { XDEVL_MODULE_ERROR("Could not create GL context.\n"); return ERR_ERROR; } } return ERR_OK; }
xdl_int XdevLWindowWayland::initializeEGL() { static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const char *extensions; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE }; EGLint major, minor, n, count, i, size; m_egl.m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)display); if(m_egl.m_eglDisplay == EGL_NO_DISPLAY) { XDEVL_MODULE_ERROR("Can't create egl display\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Created egl display\n"); } EGLBoolean ret = eglInitialize(m_egl.m_eglDisplay, &major, &minor); if(ret != EGL_TRUE) { XDEVL_MODULE_ERROR("Can't initialize egl display\n"); return ERR_ERROR; } ret = eglBindAPI(EGL_OPENGL_ES_API); if(ret != EGL_TRUE) { XDEVL_MODULE_ERROR("Can't bind egl API to EGL_OPENGL_ES_API\n"); return ERR_ERROR; } if(!eglGetConfigs(m_egl.m_eglDisplay, nullptr, 0, &count) || count < 1) { return ERR_ERROR; } EGLConfig* configs = new EGLConfig[count]; ret = eglChooseConfig(m_egl.m_eglDisplay, config_attribs, configs, count, &n); if(ret != EGL_TRUE) { return ERR_ERROR; } // TODO This is at the moment for only test purpose. As you can see only the first // config is used. for(i = 0; i < n; i++) { eglGetConfigAttrib(m_egl.m_eglDisplay, configs[i], EGL_BUFFER_SIZE, &size); printf("Buffer size for config %d is %d\n", i, size); // For now just use the first one. m_egl.m_eglConfig = configs[0]; } delete [] configs; // If we do not found any configs stop here. if(m_egl.m_eglConfig == nullptr) { return ERR_ERROR; } m_egl.m_eglContext = eglCreateContext(m_egl.m_eglDisplay, m_egl.m_eglConfig, EGL_NO_CONTEXT, context_attribs); if(m_egl.m_eglContext == nullptr) { return ERR_ERROR; } }
xdl_int XdevLWindowWayland::init() { XdevLWindowImpl::init(); wl_display_roundtrip(display); if(m_compositor == nullptr) { XDEVL_MODULE_ERROR("Wayland compositor object not received.\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Received Wayland compositor object proxy\n"); } if(m_shell == nullptr) { XDEVL_MODULE_ERROR("Wayland shell object not received.\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Received Wayland shell object proxy\n"); } if(m_sharedMemory == nullptr) { XDEVL_MODULE_ERROR("Wayland shared memory object not received.\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Received Wayland shared memory object proxy\n"); } // // Now we create the surface we can see on the screen. // m_surface = wl_compositor_create_surface(m_compositor); if(m_surface == nullptr) { XDEVL_MODULE_ERROR("Can't create Wayland surface\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Created surface\n"); } wl_surface_set_user_data(m_surface, this); m_shellSurface = wl_shell_get_shell_surface(m_shell, m_surface); if(m_shellSurface == nullptr) { XDEVL_MODULE_ERROR("Can't create Wayland shell surface\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Created shell surface\n"); } wl_shell_surface_add_listener(m_shellSurface, &shell_surface_listener, this); // Bring the surface to the front. wl_shell_surface_set_toplevel(m_shellSurface); // m_frameCallback = wl_surface_frame(m_surface); // wl_callback_add_listener(m_frameCallback, &frame_listener, this); createOpaqueRegion(m_attribute.position.x, m_attribute.position.y, m_attribute.size.width, m_attribute.size.height); xdl_int ret = initializeEGL(); if(ret == ERR_ERROR) { XDEVL_MODULE_ERROR("Initializing EGL failed.\n"); return ERR_ERROR; } m_egl.m_eglWindow = wl_egl_window_create(m_surface, getWidth(), getHeight()); if(m_egl.m_eglWindow == EGL_NO_SURFACE) { XDEVL_MODULE_ERROR("Can't create egl window\n"); return ERR_ERROR; } else { XDEVL_MODULE_SUCCESS("Created egl window\n"); } m_egl.m_eglSurface = eglCreateWindowSurface(m_egl.m_eglDisplay, m_egl.m_eglConfig, m_egl.m_eglWindow, nullptr); if(!eglMakeCurrent(m_egl.m_eglDisplay, m_egl.m_eglSurface, m_egl.m_eglSurface, m_egl.m_eglContext)) { XDEVL_MODULE_ERROR("eglMakeCurrent failed\n"); } glClearColor((1.0f/255.0)*m_backgroundColor[0], (1.0f/255.0)*m_backgroundColor[1], (1.0f/255.0)*m_backgroundColor[2], (1.0f/255.0)*m_backgroundColor[3]); glClear(GL_COLOR_BUFFER_BIT); glFlush(); if(!eglSwapBuffers(m_egl.m_eglDisplay, m_egl.m_eglSurface)) { XDEVL_MODULE_ERROR("eglSwapBuffers failed\n"); } wl_display_flush(display); return ERR_OK; }
xdl_int XdevLOpenGLContextGLX::initOpenGL(Display* display, Window window) { // // Get all supported extensions. // std::string tmp(glXQueryExtensionsString(display, DefaultScreen(display))); std::vector<std::string> exlist; xstd::tokenize(tmp, exlist, " "); for(auto extension : exlist) { extensionsList.push_back(XdevLString(extension)); } std::vector<int> attribute_list; // --------------------------------------------------------------------------- // Prepare the attribute values for the glXChooseVisual function // attribute_list.push_back(GLX_X_RENDERABLE); attribute_list.push_back(True); // We are going to use the normal RGBA color type, not the color index type. attribute_list.push_back(GLX_RENDER_TYPE); attribute_list.push_back(GLX_RGBA_BIT); // This window is going to use only Window type, that means we can't use PBuffers. // Valid values are GLX WINDOW BIT, GLX PIXMAP BIT, GLX PBUFFER BIT. All can be used at the same time. attribute_list.push_back(GLX_DRAWABLE_TYPE); attribute_list.push_back(GLX_WINDOW_BIT); if(m_attributes.red_size > 0) { attribute_list.push_back(GLX_RED_SIZE); attribute_list.push_back(m_attributes.red_size); } if(m_attributes.green_size > 0) { attribute_list.push_back(GLX_GREEN_SIZE); attribute_list.push_back(m_attributes.green_size); } if(m_attributes.blue_size > 0) { attribute_list.push_back(GLX_BLUE_SIZE); attribute_list.push_back(m_attributes.blue_size); } if(m_attributes.alpha_size > 0) { attribute_list.push_back(GLX_ALPHA_SIZE); attribute_list.push_back(m_attributes.alpha_size); } if((m_attributes.red_size > 0) || (m_attributes.green_size > 0) || (m_attributes.blue_size > 0) || (m_attributes.alpha_size > 0) ) { attribute_list.push_back(GLX_BUFFER_SIZE); attribute_list.push_back(m_attributes.color_buffer_size); } attribute_list.push_back(GLX_DEPTH_SIZE); attribute_list.push_back(m_attributes.depth_size); attribute_list.push_back(GLX_STENCIL_SIZE); attribute_list.push_back(m_attributes.stencil_size); // attribute_list.push_back(GLX_ACCUM_RED_SIZE); // attribute_list.push_back(m_attributes.accum_red_size); // // attribute_list.push_back(GLX_ACCUM_GREEN_SIZE); // attribute_list.push_back(m_attributes.accum_green_size); // // attribute_list.push_back(GLX_ACCUM_BLUE_SIZE); // attribute_list.push_back(m_attributes.accum_blue_size); // // attribute_list.push_back(GLX_ACCUM_ALPHA_SIZE); // attribute_list.push_back(m_attributes.accum_alpha_size); if(m_attributes.stereo > 0) { attribute_list.push_back(GLX_STEREO); attribute_list.push_back(True); } if(m_attributes.multisample_buffers > 0) { attribute_list.push_back(GLX_SAMPLE_BUFFERS); attribute_list.push_back(GL_TRUE); attribute_list.push_back(GLX_SAMPLES); attribute_list.push_back(m_attributes.multisample_samples); } if(m_attributes.double_buffer > 0) { attribute_list.push_back(GLX_DOUBLEBUFFER); attribute_list.push_back(GL_TRUE); } attribute_list.push_back(None); // // Get all supported visual configurations. // xdl_int numberOfConfigs; GLXFBConfig *fbcfg = glXChooseFBConfig(display, DefaultScreen(display), attribute_list.data(), &numberOfConfigs); if(!fbcfg) { XDEVL_MODULE_ERROR("glXChooseFBConfig failed\n"); return RET_FAILED; } // // Retrieve the X Visual associated with a GLXFBConfig // int best_fbc = -1; int worst_fbc = -1; int best_num_samples = -1; int worst_num_samples = 999; for(auto i = 0; i < numberOfConfigs; i++) { XVisualInfo* vi = glXGetVisualFromFBConfig(display, fbcfg[i]); if(nullptr != vi) { int sample_buffer, samples; glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLE_BUFFERS, &sample_buffer); glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLES, &samples); if(best_fbc < 0 || (sample_buffer && samples) > best_num_samples) { best_fbc = i; best_num_samples = samples; } if(worst_fbc < 0 || (!sample_buffer && samples) < worst_num_samples) { worst_fbc = i; worst_num_samples = samples; } } XFree(vi); } /// Now get the GLXFBConfig for the best match. GLXFBConfig bestFbc = fbcfg[best_fbc]; XFree(fbcfg); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "--- GLXFBConfig ---\n"); dumpConfigInfo(bestFbc); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "-------------------\n"); m_visualInfo = glXGetVisualFromFBConfig(display, bestFbc); // Change the windows color map. XSetWindowAttributes swa; swa.colormap = XCreateColormap(display, RootWindow(display, m_visualInfo->screen), m_visualInfo->visual, AllocNone); XChangeWindowAttributes(display, window, CWColormap, &swa); glXWaitGL(); // TODO: This is the easiest way to create a visual for X11. You should do that in a better way cengiz. // m_visualInfo = glXChooseVisual(display, DefaultScreen(display), attribute_list.data()); // if(nullptr == m_visualInfo) { // XDEVL_MODULE_ERROR("glXChooseVisual failed. Please try different framebuffer, depthbuffer, stencilbuffer values.\n"); // return RET_FAILED; // } // // Set OpenGL 3.0 > attributes. // std::vector<int> opengl_profile_attribute_list; opengl_profile_attribute_list.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB); opengl_profile_attribute_list.push_back(m_attributes.context_major_version); opengl_profile_attribute_list.push_back(GLX_CONTEXT_MINOR_VERSION_ARB); opengl_profile_attribute_list.push_back(m_attributes.context_minor_version); if((m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) || (m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT)) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_FLAGS_ARB); if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_DEBUG_BIT_ARB); } else if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); } } if((m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) || (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY)) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB); } else if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY) { opengl_profile_attribute_list.push_back(GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); } } opengl_profile_attribute_list.push_back(None); XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "OpenGL: " << m_attributes.context_major_version << "." << m_attributes.context_minor_version << std::endl); // // Try to use new ARB_create_context and ARB_create_context_profile // auto sharedContext = m_shareContext ? m_shareContext->getNativeContext() : nullptr; if(nullptr != glXCreateContextAttribs) { // // Create the context. // m_glxContext = glXCreateContextAttribs(display, bestFbc, sharedContext, True, opengl_profile_attribute_list.data()); if(nullptr == m_glxContext) { XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n"); return RET_FAILED; } // // Check for other erros. // glXWaitGL(); if(xdl_true == contextErrorOccured) { // m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE); } } else { // // OK, not supported, let's use old function. // m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE); if(nullptr == m_glxContext) { XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n"); return RET_FAILED; } } // setEnableFSAA(xdl_true); // // Make it current. // // GLXWindow glxWindow = glXCreateWindow(display, bestFbc, window, nullptr); // GLXDrawable drawable = glxWindow; // glXMakeContextCurrent(display, drawable, drawable, m_glxContext); if(glXMakeCurrent(display, window, m_glxContext) == False) { return RET_FAILED; } return RET_SUCCESS; }