OpenGL functioniert nicht in Child Fenster
-
Hallo,
Ich habe ein Problem mit OpenGL.
Im folgenden Programm habe ich ein Child Fenster, das ein grünes Quadrat auf rotem Hintergrund zeichnet.
Allerdings sieht man das grünes Quadrat erst wenn man die Größe des Child Fensters ändert.#include <Windows.h> #include <WindowsX.h> #include <gl\GL.h> #include <gl\GLU.h> #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") LRESULT CALLBACK ParentWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hDC; static int width; static int height; static float r; switch(message) { case WM_CREATE: hDC = GetDC(hWnd); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_PAINT: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glColor3f(0, 1, 0); r += 1; glRotatef(r, 0, 0, 1); glTranslated(0, 0, -5); glBegin(GL_QUADS); glVertex2d(-1, -1); glVertex2d(1, -1); glVertex2d(1, 1); glVertex2d(-1, 1); glEnd(); SwapBuffers(hDC); break; case WM_SIZE: width = GET_X_LPARAM(lParam); height = GET_Y_LPARAM(lParam); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45, (GLdouble)width / (GLdouble)height, 0.01f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WNDCLASS wcp; ZeroMemory(&wcp, sizeof(wcp)); wcp.hInstance = hInstance; wcp.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); wcp.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); wcp.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcp.lpfnWndProc = ParentWndProc; wcp.lpszClassName = TEXT("ParentWnd"); wcp.style = CS_VREDRAW | CS_HREDRAW; RegisterClass(&wcp); HWND hParentWnd = CreateWindow(TEXT("ParentWnd"), TEXT("ParentWnd"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, 0, 1280, 720, NULL, NULL, hInstance, NULL); WNDCLASS wcc; ZeroMemory(&wcc, sizeof(wcc)); wcc.hInstance = hInstance; wcc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); wcc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); wcc.lpfnWndProc = ChildWndProc; wcc.lpszClassName = TEXT("ChildWnd"); wcc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC; RegisterClass(&wcc); HWND hChildWnd = CreateWindow(TEXT("ChildWnd"), TEXT("ChildWnd"), WS_OVERLAPPEDWINDOW | WS_CHILD, 0, 0, 500, 500, hParentWnd, NULL, hInstance, NULL); PIXELFORMATDESCRIPTOR pfd = {0}; pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; HDC hDC = GetDC(hChildWnd); int pixelFormat = ChoosePixelFormat(hDC, &pfd); SetPixelFormat(hDC, pixelFormat, &pfd); HGLRC hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); glClearColor(1, 0, 0, 0); ShowWindow(hParentWnd, SW_SHOWNORMAL); ShowWindow(hChildWnd, SW_SHOWNORMAL); MSG msg; bool quit = false; while(!quit) { PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE); if(msg.message == WM_QUIT) { quit = true; } else { TranslateMessage(&msg); DispatchMessage(&msg); } RedrawWindow(hChildWnd, NULL, NULL, RDW_INVALIDATE); } wglDeleteContext(hRC); DestroyWindow(hChildWnd); DestroyWindow(hParentWnd); UnregisterClass(wcc.lpszClassName, hInstance); UnregisterClass(wcp.lpszClassName, hInstance); return msg.wParam; }
Wenn man nun
HWND hChildWnd = CreateWindow(TEXT("ChildWnd"), TEXT("ChildWnd"), WS_OVERLAPPEDWINDOW | WS_CHILD, 0, 0, 500, 500, hParentWnd, NULL, hInstance, NULL);
mit
HWND hChildWnd = CreateWindow(TEXT("ChildWnd"), TEXT("ChildWnd"), WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
ersetzt - das Child Fenster also nun keines mehr ist - sieht man das Quadrat sofort.
Wieso sieht man das Quadrat im Child Fenster nicht sofort?
-
sontyp schrieb:
Wieso sieht man das Quadrat im Child Fenster nicht sofort?
Ich würde mal vermuten weil du glViewport() erst beim WM_SIZE aufrufst...
Btw: WS_OVERLAPPEDWINDOW zusammen mit WS_CHILD macht imo nicht gerade viel Sinn...
-
Also ich hab jetzt
RECT rect; GetClientRect(hChildWnd, &rect); glViewport(0, 0, rect.right, rect.bottom);
nach
wglMakeCurrent(hDC, hRC);
eingefügt aber es funktioniert immer noch nicht.
-
Ich habs jetzt nochmal auf einem anderen System kompiliert.
Selbe Ergebnis.
-
OK, das Problem war, dass beim Erstellen des Child Fensters WM_SIZE gesendet wurde wo auch gluPerspective etc. aufgerufen wurden.
Nun war OpenGL zu dem Zeitpunkt aber noch initialisiert.
Ich hab OpenGL nun direkt in WM_CREATE initialisiert, und jetzt gehts.