需要明確的是,我已經廣泛測驗了這段代碼,發現問題出在 WGL 代碼之前撰寫的代碼的某個地方。正是在 WIN32 代碼中。現在我認為它可能部分是由呼叫 gluOrth2D 引起的,但即便如此,據我所知,這不應該是主要原因。我可能會自己弄亂一些東西來解決這個問題,但考慮到這個問題(發生在一個更大的專案中)已經占用了我很多時間,我認為值得發布這個封裝,以防其他人遇到同樣的問題。我希望得到解釋以及修復/更正。
#include <GL/glew.h>
#include <glfw3.h>
#define GLFW_EXPOSE_NATIVE_WGL
#define GLFW_EXPOSE_NATIVE_WIN32
#include <glfw3native.h>
constexpr int width = 1000, height = 1000;
bool running = true;
LRESULT CALLBACK WIN32_processMessage(HWND hwnd, UINT msg,
WPARAM wparam, LPARAM lparam)
{
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
int main()
{
HINSTANCE hinst = GetModuleHandleA(NULL);
HICON icon = LoadIcon(hinst, IDI_APPLICATION);
WNDCLASSA* wc = (WNDCLASSA*)memset(malloc(sizeof(WNDCLASSA)), 0, sizeof(WNDCLASSA));
if (wc == NULL)
{
return -1;
}
wc->style = CS_DBLCLKS;
wc->lpfnWndProc = WIN32_processMessage;
wc->cbClsExtra = 0;
wc->cbWndExtra = 0;
wc->hInstance = hinst;
wc->hIcon = icon;
wc->hCursor = LoadCursor(NULL, IDC_ARROW);
wc->hbrBackground = NULL;
wc->lpszClassName = "toast_window_class";
if (!RegisterClassA(wc))
{
return 1;
}
UINT32 windowX = 100;
UINT32 windowY = 100;
UINT32 windowWidth = width;
UINT32 windowHeight = height;
UINT32 windowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION;
UINT32 windowExStyle = WS_EX_APPWINDOW;
windowStyle |= WS_MAXIMIZEBOX;
windowStyle |= WS_MINIMIZEBOX;
windowStyle |= WS_THICKFRAME;
RECT borderRect = { 0,0,0,0 };
AdjustWindowRectEx(&borderRect, windowStyle, 0, windowExStyle);
windowX = borderRect.left;
windowY = borderRect.top;
windowWidth = borderRect.right - borderRect.left;
windowWidth = borderRect.bottom - borderRect.top;
HWND window = CreateWindowExA(windowExStyle, "toast_window_class", (LPCSTR)"test",
windowStyle, windowX, windowY, windowWidth, windowHeight, 0, 0, hinst, 0);
if (window == 0)
{
return 2;
}
bool shouldActivate = true;
const int showWindowCommandFlags = shouldActivate ? SW_SHOW : SW_SHOWNOACTIVATE;
ShowWindow(window, showWindowCommandFlags);
// WGL -----------------------------------------------------------
HDC device = GetDC(window);
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.cAlphaBits = 0;
pfd.cAccumBits = 0;
pfd.cDepthBits = 0;
pfd.cStencilBits = 0;
pfd.cAuxBuffers = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(device, ChoosePixelFormat(device, &pfd), &pfd);
HGLRC render = wglCreateContext(device);
wglMakeCurrent(device, render);
// GLEW ---------------------------------------------------------
const GLint res = glewInit();
if (GLEW_OK != res)
{
return 1;
}
// setup OpenGL --------------------------------------------------
gluOrtho2D(0, width, 0, height);
// main loop -----------------------------------------------------
while (running)
{
glClear(GL_COLOR_BUFFER_BIT);
// rendering
glBegin(GL_POINTS);
for (int x = 10; x < width - 10; x)
{
for (int y = 10; y < height - 10; y)
{
glVertex2f(x, y);
}
}
glEnd();
SwapBuffers(device);
}
return 0;
}
uj5u.com熱心網友回復:
不要GL_POINTS
用于逐像素繪制影像。
一方面,由于 OpenGL、其實作和現代 GPU 的作業方式,它可能是最低效的方式(在任何系統上、任何配置中)。相反 - 如果使用 OpenGL - 創建所需大小的 2D 陣列,根據需要填充像素值,然后將圖片加載到紋理中并繪制帶紋理的四邊形,或者更好的是使用裁剪的矩形覆寫三角形glScissor
。
回到您的點對點繪圖問題。您正在運行的問題本質上是舍入錯誤以及 OpenGL 在模型視圖空間、投影空間到 NDC 以及最終視口之間轉換的方式。順便說一句,您沒有呼叫glViewport
,因此不考慮視窗大小的任何調整。
呼叫glOrtho2D
將設定轉換矩陣(在您的情況下是模型視圖,因為您沒有費心切換到投影矩陣),以便范圍內的坐標[0; width]×[0; height]
將映射到 NDC 坐標[-1; 1]×[-1; 1]
。這些范圍是封閉的,即它們確實包括它們的極限值。然而,像素網格中的像素在整數范圍內尋址,范圍的末端是開放的(即?2∩[0; width(×[0; height(
)。這意味著,如果您將視口范圍用于未經調整的正交投影,則像素索引和 OpenGL 坐標之間將存在如此微小的差異。作為練習,我將把它留給您,以計算出要進行哪種調整的數學運算(提示,您必須將視口范圍的某個小數值減去某些 glOrtho 引數)。
現在對于某些視窗大小,您不會注意到這個問題,因為對于您放入 OpenGL 中的所有“像素”位置,四舍五入將恰好強制它們朝向您想要的像素位置。但是對于其他視窗大小,對于某些坐標值,四舍五入是另一種方式,并且您的列和/或行保持不變。這會導致您有時看到的線條。
uj5u.com熱心網友回復:
所以我設法修復它。他們的關鍵是在第 49 和 54 行。我已經注釋掉了導致此示例中問題的部分:
UINT32 windowStyle = WS_OVERLAPPED | WS_SYSMENU; //| WS_CAPTION;
UINT32 windowExStyle = WS_EX_APPWINDOW;
windowStyle |= WS_MAXIMIZEBOX;
windowStyle |= WS_MINIMIZEBOX;
//windowStyle |= WS_THICKFRAME;
我對 WIN32 視窗代碼不是很熟悉。這真的是我第一次嘗試。因此,如果有人可以添加一些評論,我將歡迎任何評論。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/428300.html
上一篇:提取檔案的所有圖示