OpenGL: Fix screenshot gray edge issue by correcting SetWindowPos usage

- OpenGLSwapChain::Initialize now uses AdjustWindowRect before SetWindowPos
- This ensures window client area matches expected size (1280x720)
- Previously SetWindowPos was given client area size instead of full window size
- Removed debug fprintf statements from OpenGLDevice
- Updated minimal integration test to use cleaner code
This commit is contained in:
2026-03-20 19:33:58 +08:00
parent d6ff7b6d1b
commit 28bf76cb00
3 changed files with 18 additions and 31 deletions

View File

@@ -1,7 +1,6 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOMINMAX #define NOMINMAX
#include <stdio.h>
#include <glad/glad.h> #include <glad/glad.h>
#include <windows.h> #include <windows.h>
@@ -104,17 +103,14 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
} }
if (!hwnd) { if (!hwnd) {
fprintf(stderr, "[OpenGLDevice] ERROR: hwnd is null\n");
return false; return false;
} }
m_hwnd = hwnd; m_hwnd = hwnd;
m_hdc = ::GetDC(m_hwnd); m_hdc = ::GetDC(m_hwnd);
if (!m_hdc) { if (!m_hdc) {
fprintf(stderr, "[OpenGLDevice] ERROR: GetDC failed\n");
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] GetDC succeeded\n");
PIXELFORMATDESCRIPTOR pfd = {}; PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
@@ -128,42 +124,33 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
int pixelFormat = ChoosePixelFormat(m_hdc, &pfd); int pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
if (!pixelFormat) { if (!pixelFormat) {
fprintf(stderr, "[OpenGLDevice] ERROR: ChoosePixelFormat failed\n");
ReleaseDC(m_hwnd, m_hdc); ReleaseDC(m_hwnd, m_hdc);
m_hdc = nullptr; m_hdc = nullptr;
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] ChoosePixelFormat succeeded\n");
if (!SetPixelFormat(m_hdc, pixelFormat, &pfd)) { if (!SetPixelFormat(m_hdc, pixelFormat, &pfd)) {
fprintf(stderr, "[OpenGLDevice] ERROR: SetPixelFormat failed\n");
ReleaseDC(m_hwnd, m_hdc); ReleaseDC(m_hwnd, m_hdc);
m_hdc = nullptr; m_hdc = nullptr;
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] SetPixelFormat succeeded\n");
m_hglrc = wglCreateContext(m_hdc); m_hglrc = wglCreateContext(m_hdc);
if (!m_hglrc) { if (!m_hglrc) {
fprintf(stderr, "[OpenGLDevice] ERROR: wglCreateContext failed\n");
ReleaseDC(m_hwnd, m_hdc); ReleaseDC(m_hwnd, m_hdc);
m_hdc = nullptr; m_hdc = nullptr;
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] wglCreateContext succeeded\n");
if (!wglMakeCurrent(m_hdc, m_hglrc)) { if (!wglMakeCurrent(m_hdc, m_hglrc)) {
fprintf(stderr, "[OpenGLDevice] ERROR: wglMakeCurrent failed\n");
wglDeleteContext(m_hglrc); wglDeleteContext(m_hglrc);
ReleaseDC(m_hwnd, m_hdc); ReleaseDC(m_hwnd, m_hdc);
m_hglrc = nullptr; m_hglrc = nullptr;
m_hdc = nullptr; m_hdc = nullptr;
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] wglMakeCurrent succeeded\n");
if (!gladLoadGL()) { if (!gladLoadGL()) {
fprintf(stderr, "[OpenGLDevice] ERROR: gladLoadGL failed\n");
wglMakeCurrent(nullptr, nullptr); wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(m_hglrc); wglDeleteContext(m_hglrc);
ReleaseDC(m_hwnd, m_hdc); ReleaseDC(m_hwnd, m_hdc);
@@ -171,7 +158,6 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
m_hdc = nullptr; m_hdc = nullptr;
return false; return false;
} }
fprintf(stderr, "[OpenGLDevice] gladLoadGL succeeded\n");
const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));

View File

@@ -68,7 +68,9 @@ bool OpenGLSwapChain::Initialize(HWND window, int width, int height, PresentMode
wglSwapIntervalEXT(m_vsync ? 1 : 0); wglSwapIntervalEXT(m_vsync ? 1 : 0);
} }
::SetWindowPos(m_hwnd, nullptr, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER); RECT rect = { 0, 0, width, height };
::AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
::SetWindowPos(m_hwnd, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);
m_framebufferWidth = width; m_framebufferWidth = width;
m_framebufferHeight = height; m_framebufferHeight = height;
@@ -135,7 +137,9 @@ void OpenGLSwapChain::Resize(uint32_t width, uint32_t height) {
m_width = width; m_width = width;
m_height = height; m_height = height;
if (m_hwnd) { if (m_hwnd) {
::SetWindowPos(m_hwnd, nullptr, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER); RECT rect = { 0, 0, width, height };
::AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
::SetWindowPos(m_hwnd, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);
} }
m_framebufferWidth = width; m_framebufferWidth = width;
m_framebufferHeight = height; m_framebufferHeight = height;

View File

@@ -1,5 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <glad/glad.h> #include <glad/glad.h>
#include <windows.h> #include <windows.h>
@@ -35,7 +37,12 @@ void SaveScreenshotPPM(const char* filename, int width, int height) {
return; return;
} }
glFinish();
glReadBuffer(GL_BACK);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
FILE* f = fopen(filename, "wb"); FILE* f = fopen(filename, "wb");
@@ -101,23 +108,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
NULL, NULL, hInstance, NULL NULL, NULL, hInstance, NULL
); );
RECT clientRect;
GetClientRect(hwnd, &clientRect);
fprintf(stderr, "[minimal] Window client area: %ldx%ld\n", clientRect.right, clientRect.bottom);
if (!hwnd) { if (!hwnd) {
Log("[ERROR] Failed to create window"); Log("[ERROR] Failed to create window");
return -1; return -1;
} }
OpenGLDevice device; OpenGLDevice device;
fprintf(stderr, "[minimal] About to call InitializeWithExistingWindow\n");
if (!device.InitializeWithExistingWindow(hwnd)) { if (!device.InitializeWithExistingWindow(hwnd)) {
fprintf(stderr, "[minimal] InitializeWithExistingWindow returned false\n");
Log("[ERROR] Failed to initialize OpenGL device"); Log("[ERROR] Failed to initialize OpenGL device");
return -1; return -1;
} }
fprintf(stderr, "[minimal] InitializeWithExistingWindow succeeded\n");
ShowWindow(hwnd, nShowCmd); ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd); UpdateWindow(hwnd);
@@ -132,7 +132,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
int frameCount = 0; int frameCount = 0;
const int targetFrameCount = 30; const int targetFrameCount = 30;
while (true) { while (frameCount < targetFrameCount) {
if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) { if (msg.message == WM_QUIT) {
break; break;
@@ -145,15 +145,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
swapChain.Present(0, 0); swapChain.Present(0, 0);
frameCount++; frameCount++;
if (frameCount >= targetFrameCount) {
Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount);
SaveScreenshotPPM("minimal.ppm", gWidth, gHeight);
break;
}
} }
} }
Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount);
SaveScreenshotPPM("minimal.ppm", gWidth, gHeight);
swapChain.Shutdown(); swapChain.Shutdown();
device.Shutdown(); device.Shutdown();
Logger::Get().Shutdown(); Logger::Get().Shutdown();