Fix RenderDoc OpenGL capture - pass HGLRC instead of HDC
Critical fix: For OpenGL, RenderDoc requires HGLRC (OpenGL context) as the device pointer, not HDC. Previously OpenGL test incorrectly passed HDC which caused capture to silently fail (NumCaptures=0). Changes: - OpenGLDevice: Add wglCreateContextAttribsARB support for debug context - OpenGLDevice: Create OpenGL 4.6 core profile with debug flag - RenderDocCapture: Pass correct window to SetActiveWindow/StartFrameCapture - OpenGL test: Pass HGLRC via SetDevice(), use BeginCapture/EndCapture Fix root cause identified via RenderDoc docs analysis: 'For OpenGL it must be the HGLRC, GLXContext, or EGLContext'
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLScreenshot.h"
|
||||
#include "XCEngine/Debug/Logger.h"
|
||||
#include "XCEngine/Debug/ConsoleLogSink.h"
|
||||
#include "XCEngine/Debug/RenderDocCapture.h"
|
||||
#include "XCEngine/Containers/String.h"
|
||||
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
@@ -41,6 +42,10 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
|
||||
// Set RenderDoc environment variables for global capture
|
||||
_putenv_s("RENDERDOC_CAPTUREINTERACTIVE", "0");
|
||||
_putenv_s("RENDERDOC_CAPTUREFRAMESTART", "0");
|
||||
|
||||
// Initialize logger
|
||||
Logger::Get().Initialize();
|
||||
Logger::Get().AddSink(std::make_unique<ConsoleLogSink>());
|
||||
@@ -81,6 +86,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize RenderDoc capture (MUST be before OpenGL init)
|
||||
// For OpenGL: device=nullptr (will be set via SetDevice), window=hwnd
|
||||
if (!RenderDocCapture::Get().Initialize(nullptr, hwnd)) {
|
||||
Log("[WARNING] Failed to initialize RenderDoc, frame capture will not be available");
|
||||
} else {
|
||||
RenderDocCapture::Get().SetCaptureFilePath(".\\minimal_frame30");
|
||||
}
|
||||
|
||||
// Initialize OpenGL device with existing window
|
||||
OpenGLDevice device;
|
||||
if (!device.InitializeWithExistingWindow(hwnd)) {
|
||||
@@ -88,6 +101,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set device for RenderDoc (must be called after OpenGL init)
|
||||
// For OpenGL, device pointer must be HGLRC, not HDC!
|
||||
RenderDocCapture::Get().SetDevice(device.GetContext());
|
||||
|
||||
ShowWindow(hwnd, nShowCmd);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
@@ -115,6 +132,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
} else {
|
||||
if (frameCount == targetFrameCount - 1) {
|
||||
Log("[INFO] Starting RenderDoc capture at frame %d", frameCount + 1);
|
||||
wglMakeCurrent(device.GetDC(), device.GetContext());
|
||||
RenderDocCapture::Get().BeginCapture("OpenGL_Minimal_Test");
|
||||
Log("[INFO] IsCapturing after BeginCapture: %s", RenderDocCapture::Get().IsCapturing() ? "true" : "false");
|
||||
}
|
||||
|
||||
// Set viewport and clear color using encapsulated command list
|
||||
commandList.SetViewport(0, 0, gWidth, gHeight);
|
||||
commandList.Clear(1.0f, 0.0f, 0.0f, 1.0f, 1 | 2);
|
||||
@@ -122,14 +146,21 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
// Present the rendered frame
|
||||
swapChain.Present(0, 0);
|
||||
frameCount++;
|
||||
|
||||
if (frameCount >= targetFrameCount) {
|
||||
Log("[INFO] Ending RenderDoc capture at frame %d", frameCount);
|
||||
RenderDocCapture::Get().EndCapture();
|
||||
Log("[INFO] NumCaptures: %u", RenderDocCapture::Get().GetNumCaptures());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Take screenshot after target frame count is reached
|
||||
Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount);
|
||||
Log("[INFO] Taking screenshot!");
|
||||
OpenGLScreenshot::Capture(device, swapChain, "minimal.ppm");
|
||||
|
||||
// Shutdown in reverse order of initialization
|
||||
RenderDocCapture::Get().Shutdown();
|
||||
swapChain.Shutdown();
|
||||
device.Shutdown();
|
||||
Logger::Get().Shutdown();
|
||||
|
||||
Reference in New Issue
Block a user