Chapter 1: Creating a Game Window
In this chapter, you will set up a simple Win32 window and bind an OpenGL context to it. You will be using OpenGL 3.3 Core throughout this book. The actual OpenGL code is going to be very minimal.
Most OpenGL-specific code will be abstracted into helper objects and functions, which will allow you to focus on animation rather than any specific graphics APIs. You will write the abstraction layer in Chapter 6, Building an Abstract Renderer, but for now, it's important to create a window ready to be drawn to.
By the end of this chapter, you should be able to do the following:
- Open a Win32 window
- Create and bind an OpenGL 3.3 Core context
- Use glad to load OpenGL 3.3 Core functions
- Enable vsynch for the created window
- Understand the downloadable samples for this book
Technical requirements
To follow along with the code in this book, you will need a computer running Windows 10 with a recent version of Visual Studio installed. All of the downloadable code samples are built using Visual Studio 2019. You can download Visual Studio from https://visualstudio.microsoft.com/.
You can find all of the sample code for the book on GitHub at https://github.com/PacktPublishing/Game-Animation-Programming.
Creating an empty project
Throughout this book, you will be creating code from scratch as much as possible. Because of this, there will be very few external dependencies. To get started, follow these steps to create a new blank C++ project in Visual Studio:
- Open Visual Studio and create a new project by going to File|New|Project:
Figure 1.1: Creating a new Visual Studio project
- You will see your project templates on the left-hand side of the window that pops up. Navigate to Installed|Visual C++|Other. Then, select Empty Project:
Figure 1.2: Creating an empty C++ project
- Enter a project name and select a project location. Finally, click Create.
Figure 1.3: Specifying a new project name
If you have followed the preceding steps, you should have a new blank project. Throughout the rest of this chapter, you will add an application framework and an OpenGL-enabled window.
Creating the application class
It would be difficult to maintain a cluttered window entry function. Instead, you need to create an abstract Application class. This class will contain some basic functions, such as Initialize, Update, Render, and Shutdown. All of the code samples provided for this book will be built on top of the Application base class.
Create a new file, Application.h. The declaration of the Application class is provided in the following code sample. Add this declaration to the newly created Application.h file:
#ifndef _H_APPLICATION_
#define _H_APPLICATION_
class Application {
private:
Application(const Application&);
Application& operator=(const Application&);
public:
inline Application() { }
inline virtual ~Application() { }
inline virtual void Initialize() { }
inline virtual void Update(float inDeltaTime) { }
inline virtual void Render(float inAspectRatio) { }
inline virtual void Shutdown() { }
};
#endif
The Initialize, Update, Render, and Shutdown functions are the life cycle of an application. All these functions will be called directly from the Win32 window code. Update and Render take arguments. To update a frame, the delta time between the current and last frame needs to be known. To render a frame, the aspect ratio of the window must be known.
The life cycle functions are virtual. Each chapter in the downloadable materials for this book has an example that is a subclass of the Application class that demonstrates a concept from that chapter.
Next, you will be adding an OpenGL loader to the project.
Adding an OpenGL loader
There is some external code that this chapter depends on, called glad. When you create a new OpenGL context on Windows, it's created with a legacy OpenGL context. The extension mechanism of OpenGL will let you use this legacy context to create a new modern context.
Once the modern context is created, you will need to get function pointers to all OpenGL functions. The functions need to be loaded with wglGetProcAdress, which returns a function pointer.
Loading every OpenGL function in this fashion would be very time-consuming. This is where having an OpenGL loader comes in; glad will do all this work for you. An OpenGL loader is a library or some code that calls wglGetProcAdress on the functions that the OpenGL API defines.
There are several OpenGL loaders available on Windows.; this book will use glad. glad is a small library that consists of only a few files. It has a simple API; you call one function and get access to all the OpenGL functions. glad has a web-based interface; you can find it at https://glad.dav1d.de/.
Important note
When using an X Windows system, such as many popular Linux distributions, the function to load OpenGL functions is glXGetProcAddress. As with Windows, there are OpenGL loaders available for Linux as well. Not all OSes need an OpenGL loader; for example, macOS, iOS, and Android don't need a loader. Both iOS and Android run on OpenGL ES.
Getting glad
You can get glad from https://glad.dav1d.de/, a web-based generator:
- Go to the site, select Version 3.3 from the gl dropdown, and select Core from the Profile dropdown:...