- Hands-On C++ Game Animation Programming
- Gabor Szauer
- 771字
- 2021-06-30 14:45:47
Creating a window
In this section, you will create a window. This means you will be using Win32 API calls directly to open a window and control its life cycle from code. You will also set up a debug console that can run alongside the window, which is useful for viewing logs.
Important note
An in-depth discussion of the Win32 API is beyond the scope of this book. For additional information on any of the Win32 APIs, refer to the Microsoft Developers Network (MSDN) at https://docs.microsoft.com/en-us/windows/win32/api/.
To make logging a bit easier, two windows will be open at the same time in debug mode. One will be the standard Win32 window, and the other will be a console window for viewing logs. This can be achieved by setting the linker conditionally. In debug mode, the application should link to the console subsystem. In release mode, it should link to the window subsystem.
Setting the linker subsystem can be done through the project's properties or in code using a #pragma comment. Once the subsystem is set to the console, the WinMain function can be called from main, which will launch a window that is attached to the console.
Additional linker actions, such as linking to external libraries, can be done from code, too. You will be using a #pragma command to link with OpenGL.
Start the window implementation by creating a new file, WinMain.cpp. This file will contain all of the window logic. Then, do the following:
- Add the following code to the beginning of the file. It creates #define constants that reduce the amount of code that is brought in by including <windows.h>:
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include "glad.h"
#include <windows.h>
#include <iostream>
#include "Application.h"
- The window entry function and the window event processing function both need to be forward declared. These are the two Win32 functions that we will need to open a new window:
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- Use a #pragma comment to link to OpenGL32.lib in code, rather than going through the project's properties window. Add the following code to WinMain.cpp:
#if _DEBUG
#pragma comment( linker, "/subsystem:console" )
int main(int argc, const char** argv) {
return WinMain(GetModuleHandle(NULL), NULL,
GetCommandLineA(), SW_SHOWDEFAULT);
}
#else
#pragma comment( linker, "/subsystem:windows" )
#endif
#pragma comment(lib, "opengl32.lib")
Now, a few OpenGL functions need to be declared. Creating a modern OpenGL context is done through wglCreateContextAttribsARB, but there is no reference to this function. This is one of the functions that needs to be loaded through wglGetProcAddress, as it's an extension function.
The function signature of wglCreateContextAttribsARB can be found in wglext.h. The wglext.h header is hosted by Khronos and can be found online in the OpenGL registry at https://www.khronos.org/registry/OpenGL/index_gl.php.
There is no need to include the entire wglext.h header file; you will only need the function relevant to creating a modern context. The following code is directly copied from the file. It contains the declarations for the relevant #define constants and the function pointer types:
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
typedef HGLRC(WINAPI* PFNWGLCREATECONTEXTATTRIBSARBPROC)
(HDC, HGLRC, const int*);
The previous code defines a function pointer type for wglCreatecontextAttribsARB. In addition to this, there are #define constants that are needed to make an OpenGL 3.3 Core context. The samples for this book will have vsynch enabled, which can be done through wglSwapIntervalEXT.
As you will guess, this function needs to be loaded using OpenGL's extension mechanism, too. It also needs two additional support functions: wglGetExtensionStringEXT and wglGetSwapIntervalEXT. All three of these functions are found in wgl.h, which is hosted by Khronos in the OpenGL registry linked previously.
Instead of including wgl.h, add the following code to WinMain.cpp. The code defines function pointer signatures for wglGetExtensionStringEXT, wglSwapIntervalEXT, and wglGetSwapIntervalEXT, copied out of wgl.h:
typedef const char*
(WINAPI* PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int);
typedef int (WINAPI* PFNWGLGETSWAPINTERVALEXTPROC) (void);
The preceding code is required to work with OpenGL. It's common to copy the code instead of including these headers directly. In the next section, you will begin working on the actual window.
- 演進(jìn)式架構(gòu)(原書(shū)第2版)
- Advanced Machine Learning with Python
- Flutter開(kāi)發(fā)實(shí)戰(zhàn)詳解
- Drupal 8 Blueprints
- Apache Karaf Cookbook
- Mastering Python High Performance
- PostgreSQL Replication(Second Edition)
- C語(yǔ)言實(shí)驗(yàn)指導(dǎo)及習(xí)題解析
- MATLAB for Machine Learning
- Visual Basic程序設(shè)計(jì)實(shí)驗(yàn)指導(dǎo)(第二版)
- Visual Basic程序設(shè)計(jì)
- 用戶體驗(yàn)可視化指南
- PHP項(xiàng)目開(kāi)發(fā)全程實(shí)錄(第4版)
- 虛擬現(xiàn)實(shí):引領(lǐng)未來(lái)的人機(jī)交互革命
- Raspberry Pi開(kāi)發(fā)實(shí)戰(zhàn)