OpenGL窗口错误

时间:2013-02-03 16:57:20

标签: c windows window opengl-4

我正在尝试用C创建一个简单的OpenGL窗口,但是我遇到了窗口本身的问题。创建一个窗口,然后它突然消失。我通过将“msg”归零来修复此问题但是窗口仍然尝试退出并且不传递所有其他消息。所以我无法通过按下退出退出(WM_KEYDOWN未通过)。渲染图形的工作方式应该如此。有谁知道是什么原因造成的,以及如何解决这个问题?

entrypoint.c

#include "main.h"
#include "graphics.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    int breedte, hoogte;
    DEVMODE dmScreenSettings;
    HWND hWnd;
    WNDCLASSEX wcex;
    MSG msg;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wcex.lpfnWndProc = Actie;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
    wcex.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"WinClass";
    wcex.hIconSm = NULL;
    breedte = GetSystemMetrics(SM_CXSCREEN);
    hoogte = GetSystemMetrics(SM_CYSCREEN);
    RegisterClassEx(&wcex);

    // Tijdelijk "nep" venster maken
    hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP,
        0, 0, 640, 480, NULL, NULL, hInstance, NULL);
    if(hWnd == NULL) {
        MessageBox(NULL, L"Error: er kon geen venster worden gemaakt.", L"ERROR", MB_OK);
        return -1;
    }

    if (InitializeExtensions(hWnd) != 0) {
        MessageBox(NULL, L"Error: OpenGL extensies konden niet worden geladen.", L"ERROR", MB_OK);
        return -1;
    }

    // Tijdelijk venster verwijderen
    DestroyWindow(hWnd);

    if (FULLSCREEN == 1) {
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize       = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth  = (unsigned long)breedte;
        dmScreenSettings.dmPelsHeight = (unsigned long)hoogte;
        dmScreenSettings.dmBitsPerPel = 32;         
        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
        hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP, 
            0, 0, breedte, hoogte, NULL, NULL, hInstance, NULL);
    }
    else {
        hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP,  
            (breedte / 4), (hoogte / 4), (breedte / 2), (hoogte / 2), NULL, NULL, hInstance, NULL);
        breedte /= 2;
        hoogte /= 2;
    }

    if(hWnd == NULL) {
        MessageBox(NULL, L"Error: er kon geen venster worden gemaakt.", L"ERROR", MB_OK);
        return -1;
    }

    if (InitializeOpenGL(hWnd, breedte, hoogte, SCREEN_DEPTH, SCREEN_NEAR, VSYNC) != 0) {
        MessageBox(NULL, L"Error: OpenGL kon niet worden geïnitialiseerd", L"ERROR", MB_OK);
        return -1;
    }

    // Scherm laten zien
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);

    main_loop(&msg, hWnd);
    return msg.wParam;
}

的main.c

#include "main.h"
#include "graphics.h"

void keyevent();

BYTE key_down[256];

LRESULT CALLBACK CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        ShutdownOpenGL(hWnd);
        PostQuitMessage(0);
        return 0;
    case WM_KEYDOWN:
        key_down[(unsigned int)wParam] = 1;
        keyevent();
        return 0;
    case WM_KEYUP:
        key_down[(unsigned int)wParam] = 0;
        return 0;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
        break;
    }
}

void main_loop(MSG* msg, HWND hWnd)
{
    memset(key_down, 0, 256);
    memset(&msg, 0, sizeof(MSG));

    while (1) {
        if(PeekMessage(msg, NULL, 0, 0, PM_REMOVE)) {
            if(msg->message == WM_QUIT) 
                break;

            TranslateMessage(msg);  
            DispatchMessage(msg);
        }

        if (Render() != 0) {
            break;
        }
    }
}

void keyevent()
{
    if (key_down[VK_ESCAPE] == 1) {
        PostQuitMessage(0);
    }
}

main.h

#ifndef MAIN_HEADER

#define MAIN_HEADER
#define FULLSCREEN      1
#define VSCYNC          1
#define SCREEN_DEPTH    1000.0f
#define SCREEN_NEAR     0.1f

#include <Windows.h>

LRESULT CALLBACK CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void main_loop(MSG* msg, HWND hWnd);

#endif

1 个答案:

答案 0 :(得分:2)

  1. 你是ZeroMemory'ing太多而且正在破坏你的筹码。
  2. 当您销毁临时窗口时,它将调用PostQuitMessage,因为这是您在其WM_DESTROY处理程序中告诉它的内容。然后,您的消息循环会选择该退出消息,这会导致它立即退出。