diff options
author | Ray Molenkamp <github@lazydodo.com> | 2018-06-19 03:10:45 +0300 |
---|---|---|
committer | Ray Molenkamp <github@lazydodo.com> | 2018-06-19 03:10:45 +0300 |
commit | 8c77c3653996516ba152eade2c27980ae20a1198 (patch) | |
tree | cd222da4cafd39575eb6e402dcb2dd6c6db18819 /intern | |
parent | 30c383fd35b5184037ba58ed2f7184af39a7b946 (diff) |
Ghost: Fix offline OGL render on windows.
rBe0c088f8fb5a introduced offline rendering support on windows, sadly it was trying to use the desktop window for getting a context, which given SetPixelFormat can only be called once for any given HDC was an unfortunate choice.
This patch uses a temporary hidden window for getting the opengl context.
Reviewers: mano-wii
Differential Revision: https://developer.blender.org/D3481
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_ContextWGL.cpp | 89 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextWGL.h | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 14 |
3 files changed, 17 insertions, 90 deletions
diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp index 0331958c34a..0047a88fa1d 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.cpp +++ b/intern/ghost/intern/GHOST_ContextWGL.cpp @@ -62,7 +62,6 @@ GHOST_ContextWGL::GHOST_ContextWGL( int contextFlags, int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), - m_dummyPbuffer(NULL), m_hWnd(hWnd), m_hDC(hDC), m_contextProfileMask(contextProfileMask), @@ -80,6 +79,7 @@ GHOST_ContextWGL::GHOST_ContextWGL( m_dummyVersion(NULL) #endif { + assert(m_hDC != NULL); } @@ -99,12 +99,6 @@ GHOST_ContextWGL::~GHOST_ContextWGL() WIN32_CHK(::wglDeleteContext(m_hGLRC)); } - if (m_dummyPbuffer) { - if (m_hDC != NULL) - WIN32_CHK(::wglReleasePbufferDCARB(m_dummyPbuffer, m_hDC)); - - WIN32_CHK(::wglDestroyPbufferARB(m_dummyPbuffer)); - } } #ifndef NDEBUG @@ -328,38 +322,10 @@ static HWND clone_window(HWND hWnd, LPVOID lpParam) return hwndCloned; } -/* It can happen that glew has not been init yet but we need some wgl functions. - * This create a dummy context on the screen window and init glew to have correct - * functions pointers. */ -static GHOST_TSuccess forceInitWGLEW(int iPixelFormat, PIXELFORMATDESCRIPTOR &chosenPFD) -{ - HDC dummyHDC = GetDC(NULL); - - if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD))) - return GHOST_kFailure; - - HGLRC dummyHGLRC = ::wglCreateContext(dummyHDC); - - if (!WIN32_CHK(dummyHGLRC != NULL)) - return GHOST_kFailure; - - if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) - return GHOST_kFailure; - - if (GLEW_CHK(glewInit()) != GLEW_OK) - return GHOST_kFailure; - - WIN32_CHK(::wglDeleteContext(dummyHGLRC)); - - WIN32_CHK(ReleaseDC(NULL, dummyHDC)); - - return GHOST_kSuccess; -} void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD) { HWND dummyHWND = NULL; - HPBUFFERARB dummyhBuffer = NULL; HDC dummyHDC = NULL; HGLRC dummyHGLRC = NULL; @@ -394,19 +360,6 @@ void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD) dummyHDC = GetDC(dummyHWND); } - else { - int iAttribList[] = {0}; - - if (wglCreatePbufferARB == NULL) { - /* This should only happen in background mode when rendering with opengl engine. */ - if (forceInitWGLEW(iPixelFormat, chosenPFD) != GHOST_kSuccess) { - goto finalize; - } - } - - dummyhBuffer = wglCreatePbufferARB(m_hDC, iPixelFormat, 1, 1, iAttribList); - dummyHDC = wglGetPbufferDCARB(dummyhBuffer); - } if (!WIN32_CHK(dummyHDC != NULL)) goto finalize; @@ -449,12 +402,6 @@ finalize: WIN32_CHK(::DestroyWindow(dummyHWND)); } - else if (dummyhBuffer != NULL) { - if (dummyHDC != NULL) - WIN32_CHK(::wglReleasePbufferDCARB(dummyhBuffer, dummyHDC)); - - WIN32_CHK(::wglDestroyPbufferARB(dummyhBuffer)); - } } @@ -816,9 +763,7 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() HDC prevHDC = ::wglGetCurrentDC(); WIN32_CHK(GetLastError() == NO_ERROR); - const bool create_hDC = m_hDC == NULL; - - if (!WGLEW_ARB_create_context || create_hDC || ::GetPixelFormat(m_hDC) == 0) { + if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { const bool needAlpha = m_alphaBackground; #ifdef GHOST_OPENGL_STENCIL @@ -835,14 +780,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() int iPixelFormat; int lastPFD; - if (create_hDC) { - /* get a handle to a device context with graphics accelerator enabled */ - m_hDC = wglGetCurrentDC(); - if (m_hDC == NULL) { - m_hDC = GetDC(NULL); - } - } - PIXELFORMATDESCRIPTOR chosenPFD; iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); @@ -851,13 +788,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() goto error; } - if (create_hDC) { - /* create an off-screen pixel buffer (Pbuffer) */ - int iAttribList[] = {0}; - m_dummyPbuffer = wglCreatePbufferARB(m_hDC, iPixelFormat, 1, 1, iAttribList); - m_hDC = wglGetPbufferDCARB(m_dummyPbuffer); - } - lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); if (!WIN32_CHK(lastPFD != 0)) { @@ -963,22 +893,13 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() goto error; } - /* Only init the non-offscreen context directly */ - if (!create_hDC) { - initContext(); + initContext(); - initClearGL(); - ::SwapBuffers(m_hDC); - } + initClearGL(); + ::SwapBuffers(m_hDC); return GHOST_kSuccess; error: - if (m_dummyPbuffer) { - if (m_hDC != NULL) - WIN32_CHK(::wglReleasePbufferDCARB(m_dummyPbuffer, m_hDC)); - - WIN32_CHK(::wglDestroyPbufferARB(m_dummyPbuffer)); - } ::wglMakeCurrent(prevHDC, prevHGLRC); return GHOST_kFailure; diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h index b77a50ae23e..7711f90a9e9 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -144,10 +144,6 @@ private: void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD); - /* offscreen buffer with size of 1x1 pixel, - * kept here to release the device constext when closing the program. */ - HPBUFFERARB m_dummyPbuffer; - HWND m_hWnd; HDC m_hDC; bool m_init; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 625a34aa142..b97bf1d089c 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -316,11 +316,21 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext() GHOST_Context *context; + HWND wnd = CreateWindowA("STATIC", + "BlenderGLEW", + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, 0, 64, 64, + NULL, NULL, + GetModuleHandle(NULL), NULL + ); + + HDC mHDC = GetDC(wnd); + #if defined(WITH_GL_PROFILE_CORE) for (int minor = 5; minor >= 0; --minor) { context = new GHOST_ContextWGL( false, true, 0, - NULL, NULL, + wnd, mHDC, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 4, minor, (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), @@ -336,7 +346,7 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext() context = new GHOST_ContextWGL( false, true, 0, - NULL, NULL, + wnd, mHDC, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 3, 3, (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), |