Book Image

Learn OpenGL

By : Frahaan Hussain
Book Image

Learn OpenGL

By: Frahaan Hussain

Overview of this book

Learn OpenGL is your one-stop reference guide to get started with OpenGL and C++ for game development. From setting up the development environment to getting started with basics of drawing and shaders, along with concepts such as lighting, model loading, and cube mapping, this book will get you up to speed with the fundamentals. You begin by setting up your development environment to use OpenGL on Windows and macOS. With GLFW and GLEW set up using absolute and relative linking done, you are ready to setup SDL and SFML for both the operating systems. Now that your development environment is set up, you'll learn to draw using simple shaders as well as make the shader more adaptable and reusable. Then we move on to more advanced topics like texturing your objects with images and transforming your objects using translate, rotate and scale. With these concepts covered, we'll move on to topics like lighting to enable you to incorporate amazing dynamic lights in your game world. By the end of the book, you'll learn about model loading, right from setting up ASSIMP to learning about the model class and loading a model in your game environment. We will conclude by understanding cube mapping to bring advance worlds to your game.
Table of Contents (13 chapters)
Title Page
Copyright and Credits
Packt Upsell
Contributors
Preface
Index

Creating the OpenGL rendering window using SDL


Perform the following steps to understand how to create a rendering window using SDL:

  1. 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> 
  1. Then, we'll include other necessary header files, such as the following:
#include <SDL.h> 
 
#include <GL/glew.h> 
 
#include <SDL_opengl.h>  
  1. 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.

  1. 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 []aschar. 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.

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

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

  1. 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; 
  1. 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; 
}  
  1. 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; 
  1. 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.