Почему мое приложение Win32 почти ломает мой компьютер, когда я пытаюсь преобразовать OpenGL в статический элемент управления? - PullRequest
1 голос
/ 01 декабря 2011

У меня есть приложение Win32 со статическим элементом управления, которое я хочу визуализировать с использованием OpenGL.Проблема в том, что когда я запускаю приложение, мой компьютер зависает, и мне уже не раз приходилось его сильно перезагружать.Это занимает меньше секунды, и это действительно брутально.Большая часть моего кода здесь взята из Интернета или из моей книги OpenGL.Я попытался сделать это несколькими другими способами, некоторые с теми же результатами, а некоторые с другими, но не более желательными результатами, в том числе сделать отрисовку владельца статического элемента управления, создать подклассы статического элемента управления и просто отобразить элемент управления в родительском элементе (основнойокна) сообщение WM_PAINT.Я даже не рендеринг геометрии, я просто хочу видеть чистый цвет.Большинство, если не все ресурсы, которые я обнаружил в Интернете, либо не покрывают рендеринг для элемента управления, ни используют MFC вместо собственных вызовов Win32 API.

Я определил, что это происходит только потому, что я вызываю glClear ().Если я этого не называю, я не испытываю замедления, но я также не вижу ничего в своем статическом элементе управления.

Еще немного информации:

  • ВизуальныйStudio 2010 Ultimate
  • Windows SDK v7.0a
  • GLEW 1.7
  • nVidia Quadro 1600M с последними драйверами
  • Windows 7 x64 Ultimate

Вот мой код:

#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define GLEW_STATIC
#include <windows.h>
#include <gl\glew.h>
#include <gl\wglew.h>
#include <Uxtheme.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
//#define WIN32_LEAN_AND_MEAN

#define IDC_THE_BUTTON 9001

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

struct GlobalSection
{
    HINSTANCE   app;
    HWND        wnd;
    HWND        button;
    HWND        panel;
    HWND        text;
    HGLRC       glrc;
    HDC         fdc;
} g;

bool initWindow(int cmdShow);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
void Init(HWND wnd);
void Render();

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow)
{
    g.app = hInst;

    INITCOMMONCONTROLSEX iccex;
    iccex.dwSize = sizeof(iccex);
    iccex.dwICC = ICC_BAR_CLASSES|ICC_COOL_CLASSES|ICC_LISTVIEW_CLASSES|ICC_PROGRESS_CLASS|ICC_STANDARD_CLASSES|ICC_TAB_CLASSES;
    InitCommonControlsEx(&iccex);

    initWindow(nCmdShow);

    MSG m;
    ZeroMemory(&m, sizeof(m));
    while(m.message != WM_QUIT)
    {
        Render();

        if(PeekMessage(&m, NULL, 0, 0, PM_REMOVE) && !IsDialogMessage(g.wnd, &m))
        {
            TranslateMessage(&m);
            DispatchMessage(&m);
        }
    }
}

bool initWindow(int cmdShow)
{
    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(wc));
    wc.cbSize = sizeof(wc);
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.lpszClassName = _T("Window Party");
    wc.hInstance = g.app;
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
    wc.hIcon = LoadIcon(g.app, MAKEINTRESOURCE(IDI_ICON2));
    wc.hIconSm = wc.hIcon;
    RegisterClassEx(&wc);

    g.wnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Window Party"), _T("Window Party"), WS_SYSMENU|WS_CLIPCHILDREN|WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 1280, 800, NULL, NULL, g.app, NULL);

    ShowWindow( g.wnd, cmdShow );                           // technically should be nCmdShow

    return true;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch(message)
    {
    case WM_CREATE:
        Init(hwnd);
        return DefWindowProc(hwnd, message, wparam, lparam);
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_COMMAND:
        {
            int wmId    = LOWORD(wparam);
            int wmEvent = HIWORD(wparam);
            switch(wmId)
            {
            case IDM_FILE_CLOSE:
                PostQuitMessage(0);
                break;
            case IDOK:
            case IDC_THE_BUTTON:
                {
                    MessageBox(hwnd, _T("You have pressed the button!"), _T("Congraturation"), MB_OK);
                }
                break;
            default:
                return DefWindowProc(hwnd, message, wparam, lparam);
            }
        }
        break;
    case WM_KEYDOWN:
        {
            TCHAR buff[64] = {0};
            wsprintf(buff, _T("Key Pressed: 0x%X"), (unsigned)wparam);
            MessageBox(hwnd, buff, _T("YOYOYO"), MB_OK);
            break;
        }
    default:
        return DefWindowProc(hwnd, message, wparam, lparam);
    }

    return 0;
}

void Init(HWND wnd)
{
    //Creating controls
    RECT cr;
    GetClientRect(wnd, &cr);
    g.panel = CreateWindow(_T("STATIC"), NULL, WS_CHILDWINDOW|WS_VISIBLE|CS_OWNDC|CS_VREDRAW|CS_HREDRAW, 0, 0, cr.right, cr.bottom-26, wnd, NULL, g.app, NULL);
    g.button = CreateWindow(_T("BUTTON"), _T("The Button"), WS_CHILDWINDOW|BS_DEFPUSHBUTTON|WS_VISIBLE, cr.right-160, cr.bottom-26, 160, 26, wnd, (HMENU)IDC_THE_BUTTON, g.app, NULL);
    g.text = CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), NULL, WS_CHILDWINDOW|ES_LEFT|WS_VISIBLE, 0, cr.bottom-26, cr.right-160, 26, wnd, NULL, g.app, NULL);

    //Setting fonts
    HFONT hf = NULL;
    hf = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    SendMessage(g.button, WM_SETFONT, (WPARAM)hf, TRUE);
    SendMessage(g.text, WM_SETFONT, (WPARAM)hf, TRUE);

    //Creating wgl context
    g.fdc = GetDC(g.panel);
    PIXELFORMATDESCRIPTOR pfd = {0};
    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.cDepthBits = 16;
    pfd.cStencilBits = 8;

    SetPixelFormat(g.fdc, 1, &pfd);
    g.glrc = wglCreateContext(g.fdc);
    wglMakeCurrent(g.fdc, g.glrc);

    RECT pcr;
    GetClientRect(g.panel, &pcr);
    glViewport(0, 0, pcr.right, pcr.bottom);

    glewInit();

    glClearColor(0.0, 0.0, 0.0, 1.0);

    UpdateWindow(wnd);
}

void Render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    SwapBuffers(g.fdc);
}

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

Вы не должны звонить Render() за каждое сообщение в окне!Звоните только Render() для WM_PAINT сообщений.

0 голосов
/ 01 декабря 2011

Это звучит как утечка памяти где-то.Компьютер прекратит визг, если использование PF станет слишком высоким.

Откройте диспетчер задач и посмотрите на использование PF до, а затем снова во время работы программы.Если он увеличивается на 0,5 ГБ или больше и продолжает подниматься, значит, у вас утечка памяти.

Если он ведет себя так, как описано выше, наиболее вероятным виновником является то, что вы создаете новый объект(или текстуры) несколько раз, что заставляет Windows выделять больше места для PF, или вы можете отключить VSYNC.

Мне, вероятно, не нужно рассказывать вам, что происходит с утечкой памяти, но при выключенном VSYNC программа будет пытаться работать так быстро, как позволяет процессор.Это будет максимально использовать ваш процессор и будет делать это быстро.

Надеюсь, это поможет.

...