#include #include #include #include #include #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" #include "XCEngine/Containers/String.h" #pragma comment(lib, "opengl32.lib") using namespace XCEngine::Debug; using namespace XCEngine::Containers; static const int gWidth = 1280; static const int gHeight = 720; static HWND gHWND = nullptr; static HDC gHDC = nullptr; static HGLRC gHGLRC = nullptr; void Log(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); Logger::Get().Debug(LogCategory::Rendering, String(buffer)); } LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CLOSE: PostQuitMessage(0); break; } return DefWindowProc(hwnd, msg, wParam, lParam); } bool InitOpenGL() { gHDC = GetDC(gHWND); if (!gHDC) { Log("[ERROR] Failed to get DC"); return false; } PIXELFORMATDESCRIPTOR pfd = {}; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 24; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = ChoosePixelFormat(gHDC, &pfd); if (!pixelFormat) { Log("[ERROR] Failed to choose pixel format"); return false; } if (!SetPixelFormat(gHDC, pixelFormat, &pfd)) { Log("[ERROR] Failed to set pixel format"); return false; } gHGLRC = wglCreateContext(gHDC); if (!gHGLRC) { Log("[ERROR] Failed to create GL context"); return false; } if (!wglMakeCurrent(gHDC, gHGLRC)) { Log("[ERROR] Failed to make GL context current"); return false; } if (!gladLoadGL()) { Log("[ERROR] Failed to load OpenGL functions"); return false; } Log("[INFO] OpenGL initialized: %s", glGetString(GL_RENDERER)); Log("[INFO] OpenGL Version: %s", glGetString(GL_VERSION)); glViewport(0, 0, gWidth, gHeight); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); return true; } void ShutdownOpenGL() { if (gHGLRC) { wglDeleteContext(gHGLRC); gHGLRC = nullptr; } if (gHDC) { ReleaseDC(gHWND, gHDC); gHDC = nullptr; } } void SaveScreenshotPPM(const char* filename) { unsigned char* pixels = (unsigned char*)malloc(gWidth * gHeight * 3); if (!pixels) { Log("[ERROR] Failed to allocate pixel buffer"); return; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, gWidth, gHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels); FILE* f = fopen(filename, "wb"); if (!f) { Log("[ERROR] Failed to open file for screenshot: %s", filename); free(pixels); return; } fprintf(f, "P6\n%d %d\n255\n", gWidth, gHeight); unsigned char* row = (unsigned char*)malloc(gWidth * 3); for (int y = gHeight - 1; y >= 0; y--) { memcpy(row, pixels + y * gWidth * 3, gWidth * 3); fwrite(row, 1, gWidth * 3, f); } free(row); free(pixels); fclose(f); Log("[INFO] Screenshot saved to %s", filename); } void RenderFrame() { glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SwapBuffers(gHDC); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { Logger::Get().Initialize(); Logger::Get().AddSink(std::make_unique()); Logger::Get().SetMinimumLevel(LogLevel::Debug); Log("[INFO] OpenGL Integration Test Starting"); WNDCLASSEX wc = {}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = L"OpenGLTest"; if (!RegisterClassEx(&wc)) { MessageBox(NULL, L"Failed to register window class", L"Error", MB_OK); return -1; } RECT rect = { 0, 0, gWidth, gHeight }; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); gHWND = CreateWindowEx(0, L"OpenGLTest", L"OpenGL Integration Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL); if (!gHWND) { MessageBox(NULL, L"Failed to create window", L"Error", MB_OK); return -1; } if (!InitOpenGL()) { MessageBox(NULL, L"Failed to initialize OpenGL", L"Error", MB_OK); return -1; } ShowWindow(gHWND, nShowCmd); UpdateWindow(gHWND); MSG msg = {}; int frameCount = 0; const int targetFrameCount = 30; while (true) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { break; } TranslateMessage(&msg); DispatchMessage(&msg); } else { RenderFrame(); frameCount++; if (frameCount >= targetFrameCount) { Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount); SaveScreenshotPPM("minimal.ppm"); break; } } } ShutdownOpenGL(); Logger::Get().Shutdown(); Log("[INFO] OpenGL Integration Test Finished"); return 0; }