Example #1
0
static BOOL WINAPI hook_wgl_delete_context(HGLRC hrc)
{
	BOOL ret;

	if (capture_active()) {
		HDC last_hdc = jimglGetCurrentDC();
		HGLRC last_hrc = jimglGetCurrentContext();

		jimglMakeCurrent(data.hdc, hrc);
		gl_free();
		jimglMakeCurrent(last_hdc, last_hrc);
	}

	unhook(&wgl_delete_context);
	BOOL (WINAPI *call)(HGLRC) = wgl_delete_context.call_addr;
	ret = call(hrc);
	rehook(&wgl_delete_context);

	return ret;
}
Example #2
0
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;
}
Example #3
0
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;
}