Ich habe ein Problem mit diesem Code. Keine Fehler oder Warnungen, aber Dreieck erscheint, wenn Fenster nur die Größe ändert.Triangle Zeichnung mit OpenGL: wie mit zwei Klassen zu verwalten
Ich muss das korrigieren. Header-Datei enthalten diese zwei Klassen: Window und WindowGL (klassenbasierte Vererbung). Was ist mit diesem Code falsch?
#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
Und CPP-Datei:
#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 dafür. Ich habe die Run() -Funktion aktualisiert. Aber immer noch das gleiche Problem. Kein Dreieck, ohne die Fenstergröße zu ändern. –
Ich habe den Code bearbeitet, er sollte dir die richtige Idee geben. – FedeWar
Ja, ich habe meinen obigen Code bearbeitet - und Run() mit der "besseren" Funktion PeekMessage() geändert, aber immer noch keinen Effekt. Header-Klassen werden auf diese Weise erstellt, ich kann nicht einmal Render() in Run() aufrufen. Stattdessen kann ich anrufen: Fenster. Render(), aber es ändert nichts. Der Code stammt aus einem Buch, das von einem Physiker geschrieben wurde, aber der Autor stellt keinen Quellcode zur Verfügung. Können Sie versuchen, dieses Zeug auf Ihrem Computer zu kompilieren? Danke für Ihre Hilfe. –