GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() { #ifdef WITH_X11_XINPUT /* use our own event handlers to avoid exiting blender, * this would happen for eg: * if you open blender, unplug a tablet, then open a new window. */ XErrorHandler old_handler = XSetErrorHandler (GHOST_X11_ApplicationErrorHandler ); XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif /* needed so 'GLXEW_ARB_create_context' is valid */ mxIgnoreNoVersion(1); initContextGLXEW(); mxIgnoreNoVersion(0); if (GLXEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #ifdef WITH_GLEW_ES int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT; #endif if (!GLXEW_ARB_create_context_profile && profileBitCore) fprintf(stderr, "Warning! OpenGL core profile not available.\n"); if (!GLXEW_ARB_create_context_profile && profileBitCompat) fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); #ifdef WITH_GLEW_ES if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); #endif int profileMask = 0; if (GLXEW_ARB_create_context_profile && profileBitCore) profileMask |= profileBitCore; if (GLXEW_ARB_create_context_profile && profileBitCompat) profileMask |= profileBitCompat; #ifdef WITH_GLEW_ES if (GLXEW_EXT_create_context_es_profile && profileBitES) profileMask |= profileBitES; #endif if (profileMask != m_contextProfileMask) fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); /* max 10 attributes plus terminator */ int attribs[11]; int i = 0; if (profileMask) { attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[i++] = profileMask; } if (m_contextMajorVersion != 0) { attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; attribs[i++] = m_contextMajorVersion; } if (m_contextMinorVersion != 0) { attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = m_contextMinorVersion; } if (m_contextFlags != 0) { attribs[i++] = GLX_CONTEXT_FLAGS_ARB; attribs[i++] = m_contextFlags; } if (m_contextResetNotificationStrategy != 0) { if (GLXEW_ARB_create_context_robustness) { attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; attribs[i++] = m_contextResetNotificationStrategy; } else { fprintf(stderr, "Warning! Cannot set the reset notification strategy."); } } attribs[i++] = 0; /* Create a GL 3.x context */ GLXFBConfig *framebuffer_config = NULL; { int glx_attribs[64]; int fbcount = 0; GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, true); framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount); } if (framebuffer_config) { m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); } } else { /* Create legacy context */ m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True); } GHOST_TSuccess success; if (m_context != NULL) { if (!s_sharedContext) s_sharedContext = m_context; s_sharedCount++; glXMakeCurrent(m_display, m_window, m_context); initClearGL(); ::glXSwapBuffers(m_display, m_window); /* re initialize to get the extensions properly */ initContextGLXEW(); success = GHOST_kSuccess; } else { /* freeing well clean up the context initialized above */ success = GHOST_kFailure; } #ifdef WITH_X11_XINPUT /* Restore handler */ XSetErrorHandler (old_handler); XSetIOErrorHandler(old_handler_io); #endif return success; }
GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() { #ifdef GHOST_OPENGL_ALPHA const bool needAlpha = true; #else const bool needAlpha = false; #endif #ifdef GHOST_OPENGL_STENCIL const bool needStencil = true; #else const bool needStencil = false; #endif #ifdef GHOST_OPENGL_SRGB const bool sRGB = true; #else const bool sRGB = false; #endif HGLRC prevHGLRC; HDC prevHDC; int iPixelFormat; int lastPFD; PIXELFORMATDESCRIPTOR chosenPFD; SetLastError(NO_ERROR); prevHGLRC = ::wglGetCurrentContext(); WIN32_CHK(GetLastError() == NO_ERROR); prevHDC = ::wglGetCurrentDC(); WIN32_CHK(GetLastError() == NO_ERROR); iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); if (iPixelFormat == 0) goto error; lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); if (!WIN32_CHK(lastPFD != 0)) goto error; if (needAlpha && chosenPFD.cAlphaBits == 0) fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); if (needStencil && chosenPFD.cStencilBits == 0) fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) goto error; activateWGLEW(); if (WGLEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; #ifdef WITH_GLEW_ES int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; #endif if (!WGLEW_ARB_create_context_profile && profileBitCore) fprintf(stderr, "Warning! OpenGL core profile not available.\n"); if (!WGLEW_ARB_create_context_profile && profileBitCompat) fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); #ifdef WITH_GLEW_ES if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); #endif int profileMask = 0; if (WGLEW_ARB_create_context_profile && profileBitCore) profileMask |= profileBitCore; if (WGLEW_ARB_create_context_profile && profileBitCompat) profileMask |= profileBitCompat; #ifdef WITH_GLEW_ES if (WGLEW_EXT_create_context_es_profile && profileBitES) profileMask |= profileBitES; #endif if (profileMask != m_contextProfileMask) fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); std::vector<int> iAttributes; if (profileMask) { iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); iAttributes.push_back(profileMask); } if (m_contextMajorVersion != 0) { iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); iAttributes.push_back(m_contextMajorVersion); } if (m_contextMinorVersion != 0) { iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); iAttributes.push_back(m_contextMinorVersion); } if (m_contextFlags != 0) { iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); iAttributes.push_back(m_contextFlags); } if (m_contextResetNotificationStrategy != 0) { if (WGLEW_ARB_create_context_robustness) { iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); iAttributes.push_back(m_contextResetNotificationStrategy); } else { fprintf(stderr, "Warning! Cannot set the reset notification strategy."); } } iAttributes.push_back(0); if (!s_singleContextMode || s_sharedHGLRC == NULL) m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0])); else m_hGLRC = s_sharedHGLRC; } else { if (m_contextProfileMask != 0) fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL profiles."); if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) fprintf(stderr, "Warning! Legacy WGL is unable to select between OpenGL versions."); if (m_contextFlags != 0) fprintf(stderr, "Warning! Legacy WGL is unable to set context flags."); if (!s_singleContextMode || s_sharedHGLRC == NULL) m_hGLRC = ::wglCreateContext(m_hDC); else m_hGLRC = s_sharedHGLRC; } if (!WIN32_CHK(m_hGLRC != NULL)) goto error; if (s_sharedHGLRC == NULL) s_sharedHGLRC = m_hGLRC; s_sharedCount++; if (!s_singleContextMode && s_sharedHGLRC != m_hGLRC && !WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) goto error; if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) goto error; initContextGLEW(); initClearGL(); ::SwapBuffers(m_hDC); #ifndef NDEBUG reportContextString("Vendor", m_dummyVendor, reinterpret_cast<const char*>(glGetString(GL_VENDOR))); reportContextString("Renderer", m_dummyRenderer, reinterpret_cast<const char*>(glGetString(GL_RENDERER))); reportContextString("Version", m_dummyVersion, reinterpret_cast<const char*>(glGetString(GL_VERSION))); #endif return GHOST_kSuccess; error: ::wglMakeCurrent(prevHDC, prevHGLRC); return GHOST_kFailure; }