OpenGL深入探索——OpenGL/GLSL数据传递小记(3.x) 【包含UBO详解】
752
2022-05-29
文章目录
一、导入头文件
二、桌面程序入口函数
三、注册窗口
四、创建窗口
五、显示窗口
六、完整代码示例
七、相关资源
基于 【OpenGL】一、Visual Studio 2019 创建 Windows 桌面程序 ( Visual Studio Installer 安装 C++ 桌面开发库 | 创建桌面程序 ) 博客中创建的 Windows 桌面程序继续向下讲解 , Visual Studio 自动生成了空白的桌面程序 , OpenGL 系列开发基于该桌面程序进行 ;
本篇博客简单介绍下该桌面初始化的操作 , 注册桌面窗口 , 创建桌面窗口 , 显示桌面窗口 ;
一、导入头文件
Windows 窗口程序需要导入 windows.h 头文件 ;
// Windows 头文件 #include
1
2
下面的代码时 Visual Studio 创建桌面程序时 , 自动生成的头文件 , 其中包含了 windows.h 头文件 ;
// header.h: 标准系统包含文件的包含文件, // 或特定于项目的包含文件 // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 // Windows 头文件 #include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
二、桌面程序入口函数
Windows 桌面程序的入口
是
wWinMain
函数 ,
该函数相当于命令行程序中的 void main() 函数 ;
完整的 wWinMain 函数格式 :
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
1
2
3
4
三、注册窗口
使用
WNDCLASSEXW
结构体注册窗口 ;
WNDCLASSEXW 结构体代码如下 :
typedef struct tagWNDCLASSEXW { UINT cbSize; /* Win 3.x */ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; /* Win 4.0 */ HICON hIconSm; } WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
下面是该结构体各个字段的含义 :
style : 窗口风格 ;
lpfnWndProc : 设置消息响应函数 , 如响应鼠标 , 键盘事件 ;
cbWndExtra : 窗口是否需要额外空间 ;
hInstance : 窗口实体 , 通过桌面程序入口函数传入 ;
hIcon : 生成的程序在文件夹中的样式 , 可执行程序的图标
hCursor : 设置鼠标光标样式 ;
hbrBackground : 设置背景 ;
lpszMenuName : 设置菜单 ;
lpszClassName : 设置窗口标识 ;
窗口注册代码示例 : 下面的代码时 Visual Studio 自动身
// // 函数: MyRegisterClass() // // 目标: 注册窗口类。 // ATOM MyRegisterClass(HINSTANCE hInstance) { // 注册窗口的结构体 WNDCLASSEXW wcex; // 设置结构体的大小 wcex.cbSize = sizeof(WNDCLASSEX); // 窗口风格 , CS 是 Class Style 缩写 , VREDRAW 垂直重绘 , HREDRAW 水平重绘 wcex.style = CS_HREDRAW | CS_VREDRAW; // 消息响应函数 , 鼠标点击窗口 , 或打字字后的回调函数 wcex.lpfnWndProc = WndProc; // 不需要额外的空间 wcex.cbClsExtra = 0; // 不需要额外的空间 wcex.cbWndExtra = 0; // 设置程序的实例, 通过桌面程序入口函数传入 wcex.hInstance = hInstance; // 生成的程序在文件夹中的样式 , 可执行程序的图标 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL)); // 设置鼠标光标样式 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // 设置背景 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 菜单 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL); // 窗口的唯一标识符 wcex.lpszClassName = szWindowClass; // 设置窗口运行后显示在右上角的图标 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // 设置完上述参数后 , 最后调用该方法注册窗口 return RegisterClassExW(&wcex); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
四、创建窗口
调用 CreateWindowW 方法 , 创建 Windows 窗口 ,
创建完成之后 , 验证下创建方法返回值 hWnd , 如果创建失败 , 直接退出 ;
// 创建窗口的核心逻辑 HWND hWnd = CreateWindowW( szWindowClass, // 窗口主类 szTitle, // 窗口标题名称 WS_OVERLAPPEDWINDOW, // 窗口风格 100 , // x 坐标 100 , // y 坐标 800, // 宽度 600, // 高度 nullptr, // 父窗口 nullptr, // 菜单 hInstance, // 程序实体 nullptr); // 如果创建失败 , 直接退出 if (!hWnd) { return FALSE; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
五、显示窗口
创建完成后 , 显示窗口 ;
// 显示窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
1
2
3
六、完整代码示例
Windows 窗口完整代码 , 这是 Visual Studio 自动生成的代码 ;
// OpenGL.cpp : 定义应用程序的入口点。 // 窗口程序入口 // 代码提交测试 #include "framework.h" #include "OpenGL.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此处放置代码。 // 初始化全局字符串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_OPENGL, szWindowClass, MAX_LOADSTRING); // 注册窗口 MyRegisterClass(hInstance); // 执行应用程序初始化: // 创建窗口 if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // 下面的逻辑是一个死循环 , 避免让窗口退出 HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGL)); MSG msg; // 主消息循环: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函数: MyRegisterClass() // // 目标: 注册窗口类。 // ATOM MyRegisterClass(HINSTANCE hInstance) { // 注册窗口的结构体 WNDCLASSEXW wcex; // 设置结构体的大小 wcex.cbSize = sizeof(WNDCLASSEX); // 窗口风格 , CS 是 Class Style 缩写 , VREDRAW 垂直重绘 , HREDRAW 水平重绘 wcex.style = CS_HREDRAW | CS_VREDRAW; // 消息响应函数 , 鼠标点击窗口 , 或打字字后的回调函数 wcex.lpfnWndProc = WndProc; // 不需要额外的空间 wcex.cbClsExtra = 0; // 不需要额外的空间 wcex.cbWndExtra = 0; // 设置程序的实例, 通过桌面程序入口函数传入 wcex.hInstance = hInstance; // 生成的程序在文件夹中的样式 , 可执行程序的图标 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL)); // 设置鼠标光标样式 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // 设置背景 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 菜单 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL); // 窗口的唯一标识符 wcex.lpszClassName = szWindowClass; // 设置窗口运行后显示在右上角的图标 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // 设置完上述参数后 , 最后调用该方法注册窗口 return RegisterClassExW(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目标: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 将实例句柄存储在全局变量中 // 创建窗口的核心逻辑 HWND hWnd = CreateWindowW( szWindowClass, // 窗口主类 szTitle, // 窗口标题名称 WS_OVERLAPPEDWINDOW, // 窗口风格 100 , // x 坐标 100 , // y 坐标 800, // 宽度 600, // 高度 nullptr, // 父窗口 nullptr, // 菜单 hInstance, // 程序实体 nullptr); // 如果创建失败 , 直接退出 if (!hWnd) { return FALSE; } // 显示窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目标: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此处添加使用 hdc 的任何绘图代码... EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
七、相关资源
GitHub 地址 : https://github.com/han1202012/OpenGL
博客源码快照 : https://download.csdn.net/download/han1202012/14503846
OpenGL Windows
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。