0
我對此代碼有問題。沒有錯誤或警告,但當窗口僅調整大小時會顯示三角形。使用OpenGL繪製三角形:如何使用兩個類來管理
我需要糾正這一點。頭文件包含這兩個類:Window和WindowGL(基於類的繼承)。這段代碼有什麼問題?
#ifndef OPENGL_H
#define OPENGL_H
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
class Window
{
protected:
HWND hwnd;
long clientWidh;
long clientHeight;
public:
Window() :hwnd(NULL){};
LRESULT WndProc(HWND , UINT , WPARAM , LPARAM);
bool Initialize(HINSTANCE appHandle, POINT windowPosition, POINT windowSize);
WPARAM Run();
};
class WindowGL : public Window
{
private:
HGLRC handleRC;
HDC handleDC;
bool InitWGL(HWND hwnd);
void DestroyWGL();
void SetScene(bool isometricProjection);
void Render();
public:
WindowGL() :Window(), handleRC(NULL), handleDC(NULL){};
LRESULT WndProc(HWND, UINT , WPARAM, LPARAM);
bool SetPixels(HDC) const;
}window;
#endif
和.cpp文件:
#include "myHeaderGL.h"
#include <cstdlib>
#include <gl/GL.h>
#include <gl/GLU.h>// not used in this example
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return window.WndProc(hWnd, message, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
POINT windowPosition = { 100, 100 };
POINT windowSize = { 800, 600 };
if (!window.Initialize(hInstance, windowPosition, windowSize))
{
MessageBox(NULL, "Initialisation fail.", "OpenGL Application", MB_OK | MB_ICONERROR);
return EXIT_FAILURE;
}
else return window.Run();
}
LRESULT Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
RECT rect;
GetClientRect(hWnd, &rect);
clientWidh = rect.right - rect.left;
clientHeight = rect.bottom - rect.top;
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}
LRESULT WindowGL::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
long result = Window::WndProc(hWnd, message, wParam, lParam);
switch (message)
{
case WM_CREATE:
if (!InitWGL(hWnd))
{
MessageBox(NULL, "Render context fail to load", "My OpenGL", MB_OK | MB_ICONERROR);
return EXIT_FAILURE;
}
SetScene(false);
break;
case WM_DESTROY:
DestroyWGL();
break;
case WM_SIZE:
SetScene(false);
break;
case WM_PAINT:
Render();
ValidateRect(hWnd, NULL);
break;
//default:
//return (DefWindowProc(hWnd, message, wParam, lParam));
}
return result;
}
bool Window::Initialize(HINSTANCE appHandle, POINT windowPosition, POINT windowSize)
{
char windowName[] = "My 1 OpenGL";
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = appHandle;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = windowName;
if (RegisterClassEx(&wc) == 0) return false;
hwnd = CreateWindow(
windowName,
windowName,
WS_OVERLAPPEDWINDOW,
windowPosition.x, windowPosition.y,
windowSize.x, windowSize.y,
NULL,
NULL,
appHandle,
NULL
);
if (!hwnd) return false;
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
return true;
}
WPARAM Window::Run()
{
MSG msg = {0};
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
window.Render();
}
return msg.wParam;
}
bool WindowGL::SetPixels(HDC handleDC) const
{
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd, sizeof(pfd));
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int pixFormat = ChoosePixelFormat(handleDC, &pfd);
if (pixFormat == 0) return false;
if (!SetPixelFormat(handleDC, pixFormat, &pfd)) return false;
return true;
}
bool WindowGL::InitWGL(HWND hwnd)
{
handleDC= ::GetDC(hwnd);
if (!SetPixels(handleDC)) return false;
handleRC = wglCreateContext(handleDC);
if (handleRC == NULL) return false;
if (!wglMakeCurrent(handleDC, handleRC)) return false;
return true;
}
void WindowGL::SetScene(bool isometricProjection)
{
glViewport(0, 0, clientWidh, clientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float wsp = clientHeight/(float)clientWidh;
if (!isometricProjection)
glFrustum(-1.0f, 1.0f, wsp*-1.0f, wsp*1.0f, 1.0f, 10.0f);
else
glOrtho(-1.0f, 1.0f, wsp*-1.0f, wsp*1.0f, 1.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void WindowGL::DestroyWGL()
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(handleRC);
::ReleaseDC(hwnd, handleDC);
}
void WindowGL::Render()
{
const float x0 = 1.0f;
const float y0 = 1.0f;
const float z0 = 1.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-x0, -y0, 0.0f);
glVertex3f(x0, -y0, 0.0f);
glVertex3f(0.0f, y0, 0.0f);
glEnd();
SwapBuffers(handleDC);
}
Sry基因此。我更新了Run()函數。但仍然是同樣的問題。沒有改變窗口大小的三角形。 –
我編輯了代碼,它應該給你正確的想法。 – FedeWar
是的,我之前編輯過我的代碼 - 並且用「更好」的函數PeekMessage()更改了Run(),但仍然沒有效果。標題類是這樣構建的,我甚至不能在Run()中調用Render()。相反,我可以調用:窗口。渲染(),但它不會改變任何東西。代碼來自物理學家編寫的書,但作者不提供源代碼。你可以嘗試在你的機器上編譯這些東西嗎?謝謝你的幫助。 –