Changeset View
Changeset View
Standalone View
Standalone View
intern/ghost/intern/GHOST_ContextWGL.cpp
| Show First 20 Lines • Show All 739 Lines • ▼ Show 20 Lines | static void reportContextString(const char *name, const char *dummy, const char *context) | ||||
| if (strcmp(dummy, context) != 0) | if (strcmp(dummy, context) != 0) | ||||
| fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy); | fprintf(stderr, "Warning! Dummy %s: %s\n", name, dummy); | ||||
| } | } | ||||
| #endif | #endif | ||||
| GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() | GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() | ||||
| { | { | ||||
| SetLastError(NO_ERROR); | |||||
| HGLRC prevHGLRC = ::wglGetCurrentContext(); | |||||
| WIN32_CHK(GetLastError() == NO_ERROR); | |||||
| HDC prevHDC = ::wglGetCurrentDC(); | |||||
| WIN32_CHK(GetLastError() == NO_ERROR); | |||||
| if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { | |||||
| const bool needAlpha = m_alphaBackground; | const bool needAlpha = m_alphaBackground; | ||||
| #ifdef GHOST_OPENGL_STENCIL | #ifdef GHOST_OPENGL_STENCIL | ||||
| const bool needStencil = true; | const bool needStencil = true; | ||||
| #else | #else | ||||
| const bool needStencil = false; | const bool needStencil = false; | ||||
| #endif | #endif | ||||
| #ifdef GHOST_OPENGL_SRGB | #ifdef GHOST_OPENGL_SRGB | ||||
| const bool sRGB = true; | const bool sRGB = true; | ||||
| #else | #else | ||||
| const bool sRGB = false; | const bool sRGB = false; | ||||
| #endif | #endif | ||||
| HGLRC prevHGLRC; | |||||
| HDC prevHDC; | |||||
| int iPixelFormat; | int iPixelFormat; | ||||
| int lastPFD; | int lastPFD; | ||||
| PIXELFORMATDESCRIPTOR chosenPFD; | 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); | iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); | ||||
| if (iPixelFormat == 0) { | if (iPixelFormat == 0) { | ||||
| ::wglMakeCurrent(prevHDC, prevHGLRC); | ::wglMakeCurrent(prevHDC, prevHGLRC); | ||||
| return GHOST_kFailure; | return GHOST_kFailure; | ||||
| } | } | ||||
| lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); | lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); | ||||
| if (!WIN32_CHK(lastPFD != 0)) { | if (!WIN32_CHK(lastPFD != 0)) { | ||||
| ::wglMakeCurrent(prevHDC, prevHGLRC); | ::wglMakeCurrent(prevHDC, prevHGLRC); | ||||
| return GHOST_kFailure; | return GHOST_kFailure; | ||||
| } | } | ||||
| if (needAlpha && chosenPFD.cAlphaBits == 0) | if (needAlpha && chosenPFD.cAlphaBits == 0) | ||||
| fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); | fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); | ||||
| if (needStencil && chosenPFD.cStencilBits == 0) | if (needStencil && chosenPFD.cStencilBits == 0) | ||||
| fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); | fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); | ||||
| if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { | if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { | ||||
| ::wglMakeCurrent(prevHDC, prevHGLRC); | ::wglMakeCurrent(prevHDC, prevHGLRC); | ||||
| return GHOST_kFailure; | return GHOST_kFailure; | ||||
| } | } | ||||
| } | |||||
| if (WGLEW_ARB_create_context) { | if (WGLEW_ARB_create_context) { | ||||
| int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; | int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; | ||||
| int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | ||||
| #ifdef WITH_GLEW_ES | #ifdef WITH_GLEW_ES | ||||
| int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; | int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; | ||||
| #endif | #endif | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | #endif | ||||
| initClearGL(); | initClearGL(); | ||||
| ::SwapBuffers(m_hDC); | ::SwapBuffers(m_hDC); | ||||
| const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | ||||
| const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); | const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); | ||||
| const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); | const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| if (m_dummyVendor != NULL) { | |||||
| reportContextString("Vendor", m_dummyVendor, vendor); | reportContextString("Vendor", m_dummyVendor, vendor); | ||||
| reportContextString("Renderer", m_dummyRenderer, renderer); | reportContextString("Renderer", m_dummyRenderer, renderer); | ||||
| reportContextString("Version", m_dummyVersion, version); | reportContextString("Version", m_dummyVersion, version); | ||||
| } | |||||
| #endif | #endif | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles() | GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles() | ||||
| { | { | ||||
| GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure; | GHOST_TSuccess success = m_hGLRC != s_sharedHGLRC || s_sharedCount == 1 ? GHOST_kSuccess : GHOST_kFailure; | ||||
| m_hWnd = NULL; | m_hWnd = NULL; | ||||
| m_hDC = NULL; | m_hDC = NULL; | ||||
| return success; | return success; | ||||
| } | } | ||||
| /** | |||||
| * For any given HDC you may call SetPixelFormat once | |||||
| * | |||||
| * So we better try to get the correct OpenGL version in a new window altogether, in case it fails. | |||||
| * (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd369049(v=vs.85).aspx) | |||||
| */ | |||||
| static bool TryOpenGLVersion( | |||||
| HWND hwnd, | |||||
| bool wantStereoVisual, | |||||
| bool wantAlphaBackground, | |||||
| GHOST_TUns16 wantNumOfAASamples, | |||||
| int contextProfileMask, | |||||
| bool debugContext, | |||||
| int major, int minor) | |||||
| { | |||||
| HWND dummyHWND = clone_window(hwnd, NULL); | |||||
| if (dummyHWND == NULL) { | |||||
| return false; | |||||
| } | |||||
| HDC dummyHDC = GetDC(dummyHWND); | |||||
| if (dummyHDC == NULL) { | |||||
| return false; | |||||
| } | |||||
| GHOST_ContextWGL * context = new GHOST_ContextWGL( | |||||
| wantStereoVisual, | |||||
| wantAlphaBackground, | |||||
| wantNumOfAASamples, | |||||
| dummyHWND, | |||||
| dummyHDC, | |||||
| contextProfileMask, | |||||
| major, minor, | |||||
| (debugContext ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), | |||||
| GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); | |||||
| bool result = context->initializeDrawingContext(); | |||||
| delete context; | |||||
| ReleaseDC(dummyHWND, dummyHDC); | |||||
| DestroyWindow(dummyHWND); | |||||
| return result; | |||||
| } | |||||
| GHOST_TSuccess GHOST_ContextWGL::getMaximumSupportedOpenGLVersion( | |||||
| HWND hwnd, | |||||
| bool wantStereoVisual, | |||||
| bool wantAlphaBackground, | |||||
| GHOST_TUns16 wantNumOfAASamples, | |||||
| int contextProfileMask, | |||||
| bool debugContext, | |||||
| GHOST_TUns8 *r_major_version, | |||||
| GHOST_TUns8 *r_minor_version) | |||||
| { | |||||
| /* - AMD and Intel give us exactly this version | |||||
| * - NVIDIA gives at least this version <-- desired behavior | |||||
| * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best version on the user's system. */ | |||||
| for (int minor = 5; minor >= 0; --minor) { | |||||
| if (TryOpenGLVersion( | |||||
| hwnd, | |||||
| wantStereoVisual, | |||||
| wantAlphaBackground, | |||||
| wantNumOfAASamples, | |||||
| contextProfileMask, | |||||
| debugContext, | |||||
| 4, minor)) | |||||
| { | |||||
| *r_major_version = 4; | |||||
| *r_minor_version = minor; | |||||
| return GHOST_kSuccess; | |||||
| } | |||||
| } | |||||
| /* Fallback to OpenGL 3.3 */ | |||||
| if (TryOpenGLVersion( | |||||
| hwnd, | |||||
| wantStereoVisual, | |||||
| wantAlphaBackground, | |||||
| wantNumOfAASamples, | |||||
| contextProfileMask, | |||||
| debugContext, | |||||
| 3, 3)) | |||||
| { | |||||
| *r_major_version = 3; | |||||
| *r_minor_version = 3; | |||||
| return GHOST_kSuccess; | |||||
| } | |||||
| *r_major_version = 0; | |||||
| *r_minor_version = 0; | |||||
| return GHOST_kFailure; | |||||
| } | |||||