官术网_书友最值得收藏!

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:

  1. 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"

  2. 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);

  3. 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.

主站蜘蛛池模板: 安仁县| 固始县| 卢氏县| 库尔勒市| 响水县| 百色市| 六盘水市| 武邑县| 延吉市| 章丘市| 明溪县| 洛阳市| 依安县| 辽阳县| 朝阳市| 嘉义市| 保山市| 平远县| 乌拉特后旗| 甘南县| 嵩明县| 类乌齐县| 云安县| 淮南市| 黎城县| 宜兰市| 东宁县| 南阳市| 山丹县| 桦甸市| 十堰市| 涞水县| 沂南县| 乐都县| 肃北| 嫩江县| 灵台县| 澳门| 济源市| 河北省| 红安县|