Add OpenGL capture path for the hooked video mirror
The Present hook never fired in Phantom Brave because it's an OpenGL game (OPENGL32.dll loaded, IDXGISwapChain::Present calls=0), so the hooked video source showed no image. Add an OpenGL producer under the video subsystem: inline-hook gdi32!SwapBuffers + opengl32!wglSwapBuffers (with a re-entrancy guard, since SwapBuffers calls wglSwapBuffers), glReadPixels the backbuffer, flip it, and upload it into the same shared keyed-mutex texture the host already samples -- so the host is unchanged. DXGI games still hit the Present hook; both producers are installed and whichever the game uses fills the texture. Validated by opengl_hook_test (real GL context, clears to a known color, reads the exact pixels back through the shared texture) and against Phantom Brave (SwapBuffers ~75/s, present=0, shared texture 1920x1080, generation advancing). Vulkan (vkQueuePresentKHR) still needs WGC -- documented. All 7 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
30
hook/src/opengl_hook.hpp
Normal file
30
hook/src/opengl_hook.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// Injected OpenGL capture path: hooks SwapBuffers / wglSwapBuffers in OpenGL games
|
||||
// (which never call IDXGISwapChain::Present, so the DXGI present hook can't see
|
||||
// them -- e.g. Phantom Brave), reads the GL backbuffer with glReadPixels, and
|
||||
// uploads it into the same shared keyed-mutex texture (coop_video_<pid>) the host
|
||||
// samples. Part of the video subsystem, alongside present_hook.
|
||||
//
|
||||
// glReadPixels forces a GPU->CPU readback each frame, so this is heavier than the
|
||||
// D3D shared-texture copy; fine for the 2D / lower-framerate games that tend to be
|
||||
// OpenGL. Vulkan games present via vkQueuePresentKHR and aren't covered here (see
|
||||
// the README) -- use WGC for those.
|
||||
#pragma once
|
||||
|
||||
#include "ipc_client.hpp"
|
||||
|
||||
namespace coop::hook
|
||||
{
|
||||
|
||||
// Installs the OpenGL swap hooks. `ipc` must outlive the hooks. Returns true if at
|
||||
// least SwapBuffers was hooked. Safe to call repeatedly.
|
||||
bool install_opengl_hooks(IpcClient& ipc);
|
||||
|
||||
// Removes the OpenGL swap hooks and releases the shared texture (best effort).
|
||||
void remove_opengl_hooks();
|
||||
|
||||
// --- Diagnostics -----------------------------------------------------------
|
||||
|
||||
std::uint64_t opengl_swaps(); // cumulative SwapBuffers/wglSwapBuffers detours
|
||||
std::uint64_t opengl_frames_shared(); // frames uploaded into the shared texture
|
||||
|
||||
} // namespace coop::hook
|
||||
Reference in New Issue
Block a user