diff --git a/scgl/cGDriver.h b/scgl/cGDriver.h index 0345c71..fcc33f2 100644 --- a/scgl/cGDriver.h +++ b/scgl/cGDriver.h @@ -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(); diff --git a/scgl/cGDriver_Init.cpp b/scgl/cGDriver_Init.cpp index 41df910..4a834b1 100644 --- a/scgl/cGDriver_Init.cpp +++ b/scgl/cGDriver_Init.cpp @@ -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; diff --git a/scgl/cGDriver_Viewport.cpp b/scgl/cGDriver_Viewport.cpp index e264d66..edd414a 100644 --- a/scgl/cGDriver_Viewport.cpp +++ b/scgl/cGDriver_Viewport.cpp @@ -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(glContext)); if (supportedExtensions.swapControl) { diff --git a/scgl/ext/cGDriver_BufferRegions.cpp b/scgl/ext/cGDriver_BufferRegions.cpp index a059c03..af0220e 100644 --- a/scgl/ext/cGDriver_BufferRegions.cpp +++ b/scgl/ext/cGDriver_BufferRegions.cpp @@ -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; }