搭建OpenGL窗口

創(chuàng)建時間:2019.07.06
修改時間:ONE 2019.07.07


官方標(biāo)準(zhǔn)教程中使用GLFW來創(chuàng)建OpenGL的窗體,處理輸入相關(guān)消息。本文瞎寫如何在win32下搭建OpenGL窗口。

完整代碼

#include <Windows.h>

LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM IParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, IParam);
}

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    WNDCLASSEX wndclass;
    wndclass.cbClsExtra = 0;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.cbWndExtra = 0;
    wndclass.hbrBackground = NULL;
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hIcon = NULL;
    wndclass.hIconSm = NULL;
    wndclass.hInstance = hInstance;
    wndclass.lpfnWndProc = GLWindowProc;
    wndclass.lpszClassName = L"GLWindow";
    wndclass.lpszMenuName = NULL;
    wndclass.style = CS_VREDRAW | CS_HREDRAW;
    ATOM atom = RegisterClassEx(&wndclass);
    if (!atom)
    {
        MessageBox(NULL, L"Notice", L"Error", MB_OK);
        return 0;
    }
    HWND hwnd = CreateWindowEx(NULL, L"GLWindow", L"OpenGL Window", WS_OVERLAPPEDWINDOW,
        100, 100, 800, 600,
        NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);
    MSG msg;
    while (true)
    {
        if (PeekMessage(&msg, NULL, NULL, PM_REMOVE)
        {
            if (msg.message == WM_QUIT)
            {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return 0;
}

運(yùn)行結(jié)果

運(yùn)行結(jié)果

主要分為三步:注冊窗口--->創(chuàng)建窗口--->顯示窗口

1.注冊窗口

1.1代碼詳解

//窗口應(yīng)用程序需包含的頭文件
#include <Windows.h>

//窗口應(yīng)用程序中,入口函數(shù) WinMain();
//返回值類型  函數(shù)修飾符(調(diào)用方式)  WinMain函數(shù)名
INT WINAPI WinMain(HINSTANCE hInstance/*當(dāng)前應(yīng)用程序?qū)嵗?/, HINSTANCE hPrevInstance/*上一次應(yīng)用程序啟動的實(shí)例*/, LPSTR lpCmdLine/*用cmd打開,命令行參數(shù)*/, int nShowCmd/*如何顯示窗口*/)
{
  return 0;
}

運(yùn)行結(jié)果

1.1運(yùn)行結(jié)果

1.2準(zhǔn)備工作

  //定義WNDCLASSEX結(jié)構(gòu)體,一個怎樣的窗口 
  WNDCLASSEX wndclass;
  //窗口類型的額外控件
  wndclass.cbClsExtra = 0;
  //實(shí)際占用的多大內(nèi)存
  wndclass.cbSize = sizeof(WNDCLASSEX);
  //額外內(nèi)存
  wndclass.cbWndExtra = 0;
  //窗口部分,沒有包含旁邊的邊框
  wndclass.hbrBackground = NULL;
  //光標(biāo)
  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  //應(yīng)用程序放在磁盤上的圖標(biāo)
  wndclass.hIcon = NULL;
  //程序運(yùn)行后,顯示在左上角的圖標(biāo)
  wndclass.hIconSm = NULL;
  //
  wndclass.hInstance = hInstance;
  //處理用戶操作函數(shù)
  wndclass.lpfnWndProc = NULL;
  //窗口名稱
  wndclass.lpszClassName = L"GLWindow";
  //菜單的名字
  wndclass.lpszMenuName = NULL;
  //窗口更新時,采用哪種重繪方式 水平|垂直
  wndclass.style = CS_VREDRAW | CS_HREDRAW;

1.3注冊窗口

  //注冊窗口
  ATOM atom = RegisterClassEx(&wndclass);
  if (!atom)
  {
    MessageBox(NULL, L"Notice", L"Error", MB_OK);
    return 0;
  }

運(yùn)行結(jié)果

1.3運(yùn)行結(jié)果

2.創(chuàng)建窗口

2.1準(zhǔn)備工作

在創(chuàng)建窗口之前需要新增用戶操作函數(shù),更改第一步注冊窗口中的準(zhǔn)備工作相關(guān)代碼。

  //處理用戶操作函數(shù)
  //wndclass.lpfnWndProc = NULL;
  wndclass.lpfnWndProc = GLWindowProc;

定義消息處理函數(shù),監(jiān)聽并處理用戶對窗口的操作

LRESULT CALLBACK GLWindowProc(HWND hwnd/*窗口句柄*/, UINT msg/*消息ID*/, WPARAM wParam/*附帶參數(shù)*/, LPARAM IParam/*附帶參數(shù)*/)
{
    switch (msg)
    {
    //關(guān)閉按鈕,退出消息
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    }
    //默認(rèn)消息處理函數(shù)去處理
    return DefWindowProc(hwnd, msg, wParam, IParam);
}

2.2創(chuàng)建窗口

  HWND hwnd = CreateWindowEx(NULL/*窗口額外的風(fēng)格*/, L"GLWindow"/*注冊時窗口的名稱*/, L"OpenGL Window"/*顯示在窗口標(biāo)題欄上的字符串*/, WS_OVERLAPPEDWINDOW/*窗口風(fēng)格*/,
        100, 100, 800, 600/*包含窗口邊框部分的寬和高*/,
        NULL/*父窗口句柄*/, NULL/*菜單句柄*/, hInstance/*應(yīng)用程序?qū)嵗?/, NULL/*額外的參數(shù)*/);

運(yùn)行結(jié)果

2.2運(yùn)行效果

3.顯示窗口

3.1顯示窗口

  ShowWindow(hwnd, SW_SHOW);
  UpdateWindow(hwnd);

運(yùn)行結(jié)果
窗口一閃而過

3.2程序不退出

  //使應(yīng)用程序不退出————死循壞
  MSG msg;
  while (true)
  {
    //從系統(tǒng)的消息隊(duì)列里獲取消息
    if (PeekMessage(&msg/*存取消息的變量*/, NULL/*獲取哪個消息的變量,所有*/, NULL/*消息IDmin */, NULL/*消息IDmax,不對消息過濾*/, PM_REMOVE/*如何處理消息,從消息隊(duì)列中移除掉*/))
    {
      if (msg.message == WM_QUIT)
      {
        break;
      }
      //轉(zhuǎn)換成應(yīng)用程序可以識別的消息
      TranslateMessage(&msg);
      //將消息派發(fā)出去
      DispatchMessage(&msg);
    }
  }

運(yùn)行結(jié)果

運(yùn)行結(jié)果


參考博客
https://blog.csdn.net/qq_22822335/article/details/50911858

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 創(chuàng)建窗口 在我們畫出出色的效果之前,首先要做的就是創(chuàng)建一個OpenGL上下文(Context)和一個用于顯示的窗口...
    IceMJ閱讀 1,550評論 0 0
  • 譯序 早前學(xué)OpenGL的時候還是1.x版本,用的都是glVertex,glNormal等固定管線API。后來工作...
    威士忌閱讀 6,806評論 4 51
  • 上一節(jié)中我們獲取并編譯了GLFW和GLEW這兩個開源庫,現(xiàn)在我們就可以使用它們來創(chuàng)建一個OpenGL繪圖窗口了。 ...
    IceMJ閱讀 2,022評論 0 1
  • 最近在學(xué)習(xí)OpenGL,搭建環(huán)境的時候發(fā)現(xiàn)網(wǎng)絡(luò)上面的教程都太籠統(tǒng)了,而且跟著上面搭建最后各種報錯,這里我會一步一步...
    機(jī)智的神棍醬閱讀 10,377評論 3 5
  • 1感恩美麗的紅心西柚。拿著你像擁有了全世界的幸福。?? 2感恩我的一天勞動。今天滿滿的收入。感覺很覺很富足??? ...
    寶貝由麗閱讀 255評論 0 0

友情鏈接更多精彩內(nèi)容