M2(OpenGL): GL mock backend (no loader) + mock-backed capture coverage

Add render_gl.cpp (selectable as `gl`): renders the animated pattern with
scissored clears (glClear + glScissor -- GL 1.1, exported straight from
opengl32) and presents with SwapBuffers. No glad/submodule needed: a legacy
wglCreateContext + <GL/gl.h> suffices, so the planned loader dependency was
dropped. GL is bottom-left origin and the capture flips top-down, so the
frame-counter block is drawn at the GL top to land top-left in the captured
image. Window class gains CS_OWNDC for a stable GL DC; best-effort vsync via a
runtime wglSwapIntervalEXT lookup.

The GL SwapBuffers/wglSwapBuffers hook now bumps the shared present counter
(it's the GL present), so present_calls works for GL games too. mock_game_test
decodes GL frames through the existing glReadPixels capture path; 15/15 ctest.
Roadmap: OpenGL milestone done and removed (Vulkan renumbered to M2);
architecture/lessons/test docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 12:03:43 +02:00
parent 67c1940d52
commit e996188aec
8 changed files with 154 additions and 17 deletions

View File

@@ -240,6 +240,10 @@ BOOL WINAPI hk_SwapBuffers(HDC hdc)
if (outer)
{
t_in_swap = true;
if (g_ipc != nullptr)
{
g_ipc->note_present(); // SwapBuffers is the GL present (counts toward video.present_calls)
}
capture_gl(hdc);
}
const BOOL r = g_hk_swapbuffers.stdcall<BOOL>(hdc); // __stdcall: call() is __cdecl on x86 -> crash
@@ -258,6 +262,10 @@ BOOL WINAPI hk_wglSwapBuffers(HDC hdc)
if (outer)
{
t_in_swap = true;
if (g_ipc != nullptr)
{
g_ipc->note_present(); // wglSwapBuffers is the GL present
}
capture_gl(hdc);
}
const BOOL r = g_hk_wglswap.stdcall<BOOL>(hdc); // __stdcall: call() is __cdecl on x86 -> crash