bool InitGLCapture() { bool bSuccess = false; HMODULE hGL = GetModuleHandle(TEXT("opengl32.dll")); if(hGL) { pglReadBuffer = (GLREADBUFFERPROC) GetProcAddress(hGL, "glReadBuffer"); pglReadPixels = (GLREADPIXELSPROC) GetProcAddress(hGL, "glReadPixels"); pglGetError = (GLGETERRORPROC) GetProcAddress(hGL, "glGetError"); pwglSwapLayerBuffers= (WGLSWAPLAYERBUFFERSPROC) GetProcAddress(hGL, "wglSwapLayerBuffers"); pwglDeleteContext = (WGLDELETECONTEXTPROC) GetProcAddress(hGL, "wglDeleteContext"); pwglGetProcAddress = (WGLGETPROCADDRESSPROC) GetProcAddress(hGL, "wglGetProcAddress"); pwglMakeCurrent = (WGLMAKECURRENTPROC) GetProcAddress(hGL, "wglMakeCurrent"); pwglCreateContext = (WGLCREATECONTEXTPROC) GetProcAddress(hGL, "wglCreateContext"); if( !pglReadBuffer || !pglReadPixels || !pglGetError || !pwglSwapLayerBuffers || !pwglDeleteContext || !pwglGetProcAddress || !pwglMakeCurrent || !pwglCreateContext) { return false; } HDC hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if(hDC) { PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd.cAccumBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd); HGLRC hGlrc = jimglCreateContext(hDC); if(hGlrc) { jimglMakeCurrent(hDC, hGlrc); pglBufferData = (GLBUFFERDATAARBPROC) jimglGetProcAddress("glBufferData"); pglDeleteBuffers = (GLDELETEBUFFERSARBPROC) jimglGetProcAddress("glDeleteBuffers"); pglGenBuffers = (GLGENBUFFERSARBPROC) jimglGetProcAddress("glGenBuffers"); pglMapBuffer = (GLMAPBUFFERPROC) jimglGetProcAddress("glMapBuffer"); pglUnmapBuffer = (GLUNMAPBUFFERPROC) jimglGetProcAddress("glUnmapBuffer"); pglBindBuffer = (GLBINDBUFFERPROC) jimglGetProcAddress("glBindBuffer"); UINT lastErr = GetLastError(); if(pglBufferData && pglDeleteBuffers && pglGenBuffers && pglMapBuffer && pglUnmapBuffer && pglBindBuffer) { glHookSwapBuffers.Hook((FARPROC)SwapBuffers, (FARPROC)SwapBuffersHook); glHookSwapLayerBuffers.Hook((FARPROC)jimglSwapLayerBuffers, (FARPROC)wglSwapLayerBuffersHook); glHookDeleteContext.Hook((FARPROC)jimglDeleteContext, (FARPROC)wglDeleteContextHook); bSuccess = true; } jimglMakeCurrent(NULL, NULL); jimglDeleteContext(hGlrc); if(bSuccess) { glHookSwapBuffers.Rehook(); glHookSwapLayerBuffers.Rehook(); glHookDeleteContext.Rehook(); } } DeleteDC(hDC); } } return bSuccess; }
static inline void *wgl_get_proc(const char *name) { return (void*)jimglGetProcAddress(name); }
bool InitGLCapture() { static HWND hwndOpenGLSetupWindow = NULL; bool bSuccess = false; if(!hwndOpenGLSetupWindow) { WNDCLASSEX windowClass; ZeroMemory(&windowClass, sizeof(windowClass)); windowClass.cbSize = sizeof(windowClass); windowClass.style = CS_OWNDC; windowClass.lpfnWndProc = DefWindowProc; windowClass.lpszClassName = TEXT("OBSOGLHookClass"); windowClass.hInstance = hinstMain; if(RegisterClassEx(&windowClass)) { hwndOpenGLSetupWindow = CreateWindowEx (0, TEXT("OBSOGLHookClass"), TEXT("OBS OpenGL Context Window"), WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 1, 1, NULL, NULL, hinstMain, NULL ); } } HMODULE hGL = GetModuleHandle(TEXT("opengl32.dll")); if(hGL && hwndOpenGLSetupWindow) { pglReadBuffer = (GLREADBUFFERPROC) GetProcAddress(hGL, "glReadBuffer"); pglReadPixels = (GLREADPIXELSPROC) GetProcAddress(hGL, "glReadPixels"); pglGetError = (GLGETERRORPROC) GetProcAddress(hGL, "glGetError"); pwglSwapLayerBuffers= (WGLSWAPLAYERBUFFERSPROC) GetProcAddress(hGL, "wglSwapLayerBuffers"); pwglSwapBuffers= (WGLSWAPBUFFERSPROC) GetProcAddress(hGL, "wglSwapBuffers"); pwglDeleteContext = (WGLDELETECONTEXTPROC) GetProcAddress(hGL, "wglDeleteContext"); pwglGetProcAddress = (WGLGETPROCADDRESSPROC) GetProcAddress(hGL, "wglGetProcAddress"); pwglMakeCurrent = (WGLMAKECURRENTPROC) GetProcAddress(hGL, "wglMakeCurrent"); pwglCreateContext = (WGLCREATECONTEXTPROC) GetProcAddress(hGL, "wglCreateContext"); if( !pglReadBuffer || !pglReadPixels || !pglGetError || !pwglSwapLayerBuffers || !pwglSwapBuffers || !pwglDeleteContext || !pwglGetProcAddress || !pwglMakeCurrent || !pwglCreateContext) { return false; } HDC hDC = GetDC(hwndOpenGLSetupWindow); if(hDC) { PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd.cAccumBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd); HGLRC hGlrc = jimglCreateContext(hDC); if(hGlrc) { jimglMakeCurrent(hDC, hGlrc); pglBufferData = (GLBUFFERDATAARBPROC) jimglGetProcAddress("glBufferData"); pglDeleteBuffers = (GLDELETEBUFFERSARBPROC) jimglGetProcAddress("glDeleteBuffers"); pglGenBuffers = (GLGENBUFFERSARBPROC) jimglGetProcAddress("glGenBuffers"); pglMapBuffer = (GLMAPBUFFERPROC) jimglGetProcAddress("glMapBuffer"); pglUnmapBuffer = (GLUNMAPBUFFERPROC) jimglGetProcAddress("glUnmapBuffer"); pglBindBuffer = (GLBINDBUFFERPROC) jimglGetProcAddress("glBindBuffer"); UINT lastErr = GetLastError(); if(pglBufferData && pglDeleteBuffers && pglGenBuffers && pglMapBuffer && pglUnmapBuffer && pglBindBuffer) { glHookSwapBuffers.Hook((FARPROC)SwapBuffers, (FARPROC)SwapBuffersHook); glHookSwapLayerBuffers.Hook((FARPROC)jimglSwapLayerBuffers, (FARPROC)wglSwapLayerBuffersHook); glHookwglSwapBuffers.Hook((FARPROC)jimglSwapBuffers, (FARPROC)wglSwapBuffersHook); glHookDeleteContext.Hook((FARPROC)jimglDeleteContext, (FARPROC)wglDeleteContextHook); bSuccess = true; } jimglMakeCurrent(NULL, NULL); jimglDeleteContext(hGlrc); ReleaseDC(hwndOpenGLSetupWindow, hDC); if(bSuccess) { glHookSwapBuffers.Rehook(); glHookSwapLayerBuffers.Rehook(); glHookwglSwapBuffers.Rehook(); glHookDeleteContext.Rehook(); DestroyWindow(hwndOpenGLSetupWindow); hwndOpenGLSetupWindow = NULL; UnregisterClass(TEXT("OBSOGLHookClass"), hinstMain); } } if(hwndOpenGLSetupWindow) ReleaseDC(hwndOpenGLSetupWindow, hDC); } } return bSuccess; }