Skip to content

Commit

Permalink
Add a debug mode window to show game framebuffer
Browse files Browse the repository at this point in the history
I was trying to debug issues with rendering for dirty rectangles, so I added a
window to show the contents of the framebuffer that backs the dirty rect system.
The color output is wrong because OpenGL's pixels are BGR and I'm just rendering
it to the HWND as RGB, but that doesn't really matter.
  • Loading branch information
nsgomez committed Oct 19, 2024
1 parent 8c32ae4 commit 8f5a632
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
6 changes: 6 additions & 0 deletions scgl/cGDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ namespace nSCGL
void* deviceContext;
void* glContext;

#ifndef NDEBUG
void* secondaryWindow;
void* secondaryDeviceContext;
void* pixels;
#endif

private:
void SetLastError(DriverError err);
void DestroyOpenGLContext();
Expand Down
18 changes: 18 additions & 0 deletions scgl/cGDriver_Init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@
namespace nSCGL
{
bool cGDriver::Init(void) {
#ifndef NDEBUG
WNDCLASS wcDebug{};
wcDebug.style = CS_OWNDC;
wcDebug.lpfnWndProc = DefWindowProcA;
wcDebug.hInstance = GetModuleHandle(nullptr);
wcDebug.lpszClassName = "GDriverClass--OpenGLDebug";

UnregisterClass(wcDebug.lpszClassName, nullptr);

if (!RegisterClass(&wcDebug)) {
DWORD err = GetLastError();
if (err != ERROR_CLASS_ALREADY_EXISTS) {
MessageBoxA(NULL, "Failed to set up an OpenGL debug window class", "SCGL failed to start", MB_ICONERROR);
return false;
}
}
#endif

// Create an invisible default window to set up an initial OpenGL context
WNDCLASS wc{};
wc.style = CS_OWNDC;
Expand Down
47 changes: 47 additions & 0 deletions scgl/cGDriver_Viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,53 @@ namespace nSCGL
return;
}

#ifndef NDEBUG
{
HWND secondaryHwnd = CreateWindowExA(
dwExtStyle,
"GDriverClass--OpenGLDebug",
"GDriverWindow--OpenGLDebug",
(dwStyle) & ~(WS_EX_APPWINDOW | WS_POPUP),
wndRect.left,
wndRect.top,
wndRect.right - wndRect.left,
wndRect.bottom - wndRect.top,
nullptr,
nullptr,
GetModuleHandle(nullptr),
nullptr);

if (secondaryHwnd == nullptr) {
DWORD error = GetLastError();
MessageBoxA(NULL, "Failed to create window.", "SCGL video mode error", MB_ICONWARNING);
return;
}

HDC secondaryDC = GetDC(secondaryHwnd);
secondaryWindow = secondaryHwnd;
secondaryDeviceContext = secondaryDC;

pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cAlphaBits = (newMode.depth == 32) ? 8 : 1;
pfd.cColorBits = (newMode.depth == 32) ? 24 : 15;
pfd.cDepthBits = (newMode.depth == 32) ? 24 : 16;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;

pixelFormat = ChoosePixelFormat(secondaryDC, &pfd);

if (!SetPixelFormat(secondaryDC, pixelFormat, &pfd)) {
MessageBoxA(NULL, "Failed to set video mode on debug window.", "SCGL video mode error", MB_ICONWARNING);
}

ShowWindow(secondaryHwnd, SW_SHOWNORMAL);
pixels = new char[3 * newMode.width * newMode.height];
}
#endif

wglMakeCurrent(hdc, static_cast<HGLRC>(glContext));

if (supportedExtensions.swapControl) {
Expand Down
55 changes: 55 additions & 0 deletions scgl/ext/cGDriver_BufferRegions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,61 @@ namespace nSCGL
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, framebufferMasks[bufferRegionIndex], GL_NEAREST);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

#ifndef NDEBUG
if (framebufferMasks[bufferRegionIndex] == GL_COLOR_BUFFER_BIT)
{
glFinish();

memset(pixels, 127, width * height * 3);
glReadPixels(srcX0, srcY0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

InvalidateRect((HWND)secondaryWindow, nullptr, TRUE);

PAINTSTRUCT ps;
DWORD dwError;
HDC hdc = BeginPaint((HWND)secondaryWindow, &ps);

dwError = GetLastError();

BITMAPINFO bm;
bm.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bm.bmiHeader.biWidth = width;
bm.bmiHeader.biHeight = height;
bm.bmiHeader.biPlanes = 1;
bm.bmiHeader.biBitCount = 24;
bm.bmiHeader.biCompression = BI_RGB;
bm.bmiHeader.biSizeImage = 0;
bm.bmiHeader.biXPelsPerMeter = 2835;
bm.bmiHeader.biYPelsPerMeter = 2835;
bm.bmiHeader.biClrUsed = 0;
bm.bmiHeader.biClrImportant = 0;
bm.bmiColors->rgbBlue = 255;
bm.bmiColors->rgbGreen = 255;
bm.bmiColors->rgbRed = 255;
bm.bmiColors->rgbReserved = 0;

dwError = ::SetDIBitsToDevice(
hdc,
dstX0,
windowHeight - dstY1,
width,
height,
0,
0,
0,
height,
pixels,
&bm,
DIB_RGB_COLORS);

dwError = GetLastError();

EndPaint((HWND)secondaryWindow, &ps);

dwError = GetLastError();
}
#endif

return true;
}

Expand Down

0 comments on commit 8f5a632

Please sign in to comment.