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

@@ -1,6 +1,6 @@
// CoopMockGame -- a tiny test "game" used to exercise the capture + audio + hook paths.
//
// coop_mock_game.exe [dx9|dx9ex|dx10|dx11|dx12] [seconds] [rate] [channels] [bits] [pcm|float]
// coop_mock_game.exe [dx9|dx9ex|dx10|dx11|dx12|gl] [seconds] [rate] [channels] [bits] [pcm|float]
//
// It opens a normal visible window and renders an animated, frame-numbered pattern (see
// render_backend.hpp): a moving bar + per-frame background colour make motion obvious, and
@@ -78,6 +78,7 @@ int main(int argc, char** argv)
const HINSTANCE inst = GetModuleHandleW(nullptr);
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC; // a stable private DC, so the OpenGL backend can keep one GL context
wc.lpfnWndProc = wnd_proc;
wc.hInstance = inst;
wc.hCursor = LoadCursorW(nullptr, IDC_ARROW);