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:
@@ -20,6 +20,7 @@
|
||||
#include "focus_spoof.hpp"
|
||||
#include "hook_registry.hpp"
|
||||
#include "ipc_client.hpp"
|
||||
#include "opengl_hook.hpp"
|
||||
#include "present_hook.hpp"
|
||||
#include "xinput_hook.hpp"
|
||||
|
||||
@@ -122,22 +123,28 @@ DWORD WINAPI worker_thread(LPVOID)
|
||||
coop::hook::logf("worker_thread: audio hooks removed (host request)");
|
||||
}
|
||||
|
||||
// --- Video (Present-hook) ---
|
||||
// --- Video (Present hook + OpenGL swap hook) ---
|
||||
// Opt-in alternative to the host's WGC path; the host enables it on request.
|
||||
// Install both producers: DXGI games hit the Present hook, OpenGL games hit
|
||||
// the SwapBuffers hook, whichever the game uses fills the shared texture.
|
||||
const bool want_video = g_ipc.subsystem_install_requested(coop::HookSubsys_Video);
|
||||
if (want_video && !video_installed)
|
||||
{
|
||||
video_installed = coop::hook::install_present_hooks(g_ipc);
|
||||
const bool present_ok = coop::hook::install_present_hooks(g_ipc);
|
||||
const bool gl_ok = coop::hook::install_opengl_hooks(g_ipc);
|
||||
video_installed = present_ok || gl_ok;
|
||||
if (video_installed)
|
||||
{
|
||||
coop::hook::logf("worker_thread: present hook installed");
|
||||
coop::hook::logf("worker_thread: video hooks installed (present=%d opengl=%d)",
|
||||
present_ok ? 1 : 0, gl_ok ? 1 : 0);
|
||||
}
|
||||
}
|
||||
else if (!want_video && video_installed)
|
||||
{
|
||||
coop::hook::remove_present_hooks();
|
||||
coop::hook::remove_opengl_hooks();
|
||||
video_installed = false;
|
||||
coop::hook::logf("worker_thread: present hook removed (host request)");
|
||||
coop::hook::logf("worker_thread: video hooks removed (host request)");
|
||||
}
|
||||
|
||||
if (audio_installed && !audio_ring_open)
|
||||
@@ -206,6 +213,7 @@ BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved)
|
||||
coop::hook::remove_xinput_hooks();
|
||||
coop::hook::remove_audio_hooks();
|
||||
coop::hook::remove_present_hooks();
|
||||
coop::hook::remove_opengl_hooks();
|
||||
coop::hook::hook_registry_reset();
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user