Perform the following steps to understand how to create a rendering window using SDL:
- Let's go to our main.cpp file in Visual Studio or Xcode and let's get started. The first thing to do is include iostream; this'll be used to log out any errors that we have:
#include <iostream>
- Then, we'll include other necessary header files, such as the following:
#include <SDL.h> #include <GL/glew.h> #include <SDL_opengl.h>
- Next, we'll create a constant variable using GLint:
const GLint WIDTH = 800, HEIGHT = 600;
The reason for using Glint is quite simple: a regular int on different compilers might have different sizes, whereas GLint is always consistent. The WIDTH and the HEIGHT variables will store the size of our window.
- Then, we'll set up our main entry point:
int main(int argc, char *argv[]) {
You might have noticed we have passed the argc integer and the *argv [] as char. These are the argument count and the argument value and SDL requires them to run the code, or else you will get errors while running it.
- Next, we'll initialize SDL with the help of SDL_Init() and to it we'll pass SDL_INIT_EVERYTHING to make sure we are initializing every part of the SDL library:
SDL_Init(SDL_INIT_EVERYTHING);
- Then, we'll set up some attributes, which are essentially properties that we'll set for our window:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
So, there are three main profiles that we can use for OpenGL with SDL:
- ES, which is embedded systems, for stuff like mobile devices
- There's the core profile, which is for modern OpenGL
- Then there's the compatibility profile, which allows you to use an older version of OpenGL and ensures maximum compatibility.
For our project, we'll use the core profile.
- Next, we'll set up some more attributes, as follows:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- Once all the attributes have been declared, we'll declare the SDL window, as follows:
SDL_Window *window = SDL_CreateWindow("OpenGL", 0, 0, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
The preceding code contains the name of our window, OpenGL. Then, we set the position of our window to (0, 0). To set the width and the height of our window, we'll use the WIDTH and HEIGHT values that we declared earlier. The beauty of using these values is if we refer to these anywhere, they'll get updated if we were to change them later.
- Next, for the context, we just need to provide the window variable that we created before:
SDL_GLContext context = SDL_GL_CreateContext(window); // Set this to true so GLEW knows to use a modern approach to
retrieving function pointers and extensions glewExperimental = GL_TRUE;
- Now, we are going to initialize GLEW and ensure that it's has been initialized by checking for the condition in an if statement. If it hasn't been initialized, we're going to notify the user or the developer about it in the console:
// Initialize GLEW to setup the OpenGL Function pointers if (GLEW_OK != glewInit()) { std::cout << "Failed to initialize GLEW" << std::endl; return EXIT_FAILURE; }
- Now, we'll set up the OpenGL viewport, as follows:
// Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT);
What we did in the preceding line of code is that we set the initial coordinates from 0, 0 to Width and Height. The values that you'll retrieve here will be the accurate representation of what our window is relative to the screen, as you might have a higher or a lower pixel density screen. Next, we're going to create a window event, as follows:
SDL_Event windowEvent;
- Now, we'll create our game loop:
while (true) { if (SDL_PollEvent(&windowEvent)) { if (windowEvent.type == SDL_QUIT) break; } // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // draw OpenGL SDL_GL_SwapWindow(window); } SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); return EXIT_SUCCESS; }
In the preceding code, we set while to true to keep the loop constantly running while our application is open. If something happens, like the user closes the application, we'll exit the while loop and do some cleanup. While the loop is running, we'll check for a window event and pass a reference to the window. We'll also check if the window is getting shut down and if it is, then we'll break out of the loop. Now, outside of both the if statements, we'll try to clear the screen with the help of the glClearColor statement. A ClearColor statement isn't necessary. We're adding it because we might just end up getting a black background, as we're not drawing any shapes or any textures at the moment. We'll add color to the window with the help of the following parameters: 0.2f, 0.3f, 0.3f, and 1.0f. These values range between 0 and 1; these are very similar to 0 to 255. And these are red, green, blue, and alpha values. Next, we'll clear the screen with the help of glClear. And, the last thing we're going to do is SDL_GL_SwapWindow. It swaps the window if double buffering is present; if not, then it won't. Then, we'll do some cleanup and exit out of the code with EXIT_SUCCESS.
Now, let's run this code and check the output. You will get the same OpenGL window as we got in the preceding sections.