Monday, June 17, 2013

GLEW and a basic Win32 Application

Introduction to Win32 and OpenGL 4.3 - Part1

1. Introduction.

This blog post is split in multiple parts and will summarize the findings from my early experiments and programming with OpenGL 4.3 in a Win32 environment. The reader will find some detailed explanations about setting up a win32 application with OpenGL as 3D rendering API. More specifically, OpenGL will be used to render a Gouraud shaded cube. This blog post is mainly intended as a tutorial/howto

Hereafter some details of the environment that was used:
  • OS: Windows 7 64-bit
  • GPU: 
    • Nvidia GT 630M
    • Nvidia GT 640
  • Visual Studio express 2010
This blog limits itself to a 32-bit application and its debug-build.

2. Preparing the visual studio project.

Before we start implementing and explaining the code, we'll set up the required dependencies for this application. Actually, the only dependency that requires some minimal effort is GLEW. The other dependency, OpenGL can just be set as an additional import library in the application's project settings.

GLEW, the OpenGL Extension Wrangler Library.

OpenGL relies on extensions to extend the functionality of its core. In order to alleviate some work to load all extensions yourself, GLEW is there to help you. I decided to discuss the static library, you could use the shared library as well, but I prefered to compile the GLEW code into the application in order to avoid an additional DLL.
In order to integrate GLEW in the application, I felt it was the most easy to download the source, unzip it, make a copy into C:\Program Files (x86)\glew-1.9.0\ and then just compile the glew_static project, found in C:\Program Files (x86)\glew-1.9.0\build\vc10\. This  results in a static 32-bit debug library glew32sd.lib in C:\Program Files (x86)\glew-1.9.0\lib\.

This last path will thus need to be referenced in your project's "Additional Library Directories" as can be seen in the figure below:

Referencing glew32sd.lib in "Additional Library Directories"
Since the application will be using a static library for GLEW, we need to define the preprocessor definition GLEW_STATIC in our application.

Defining the preprocessor definition GLEW_STATIC
In order to access the functionality offered by GLEW, which is basically your opengl rendering calls, you'll need to include GL\glew.h. Therefore, you'll need to add C:\Program Files (x86)\glew-1.9.0\include\ as Additional Include Directory.

Setting the "Additional Include Directory"
More information on the compilation, installation and usage of GLEW can be found on their website.

OpenGL

OpenGL is directly provided by windows in the default visual studio include paths, so you'll just need to set OpenGL32.lib as an additional dependency.

3. Basic Windows application.

A basic window application requires you to write some minimal code for the creation of the window. However, in order to make the window interactive, we also need to take the message driven architecture of Windows into account, i.e. we'll need to create a message loop to treat the messages that Windows queues for our application.

We start by creating the window, where the rendering will take place:
  • First, you'll have to instantiate a window class, WNDCLASS
    • Among other things, this class allows you to define the windows procedure, WNDPROC. This callback function will be called every time we will dispatch a message to our window "to be". Please refer to "Writing the Window Procedure" for some more indepth information.
  • Then, you'll need to register this class with a call to RegisterClass().
  • Finally, you can create your window, CreateWindow(), its important to note that this function will return a handle to your window. Then you'll want to show and update your window.
Once we have correctly initialized our window, we can move on to the creation of the message loop. The messageloop will actually be the place were your program will be spending most of its time. You can find hereafter an example of such a message loop:

 while(msg.message != WM_QUIT)  
 {  
      if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))  
      {  
           TranslateMessage(&msg);  
           DispatchMessage(&msg);  
      }  
      else  
      {  
           //Do Other stuff  
      }  
 }  

The important functions here are: PeekMessage() and DispatchMessage(). I refer to TranslateMessage() for completeness.
  • PeekMessage(): This function will look in the queue to verify if messages are available.
  • TranslateMessage()
  • DispatchMessage(): if the message on the queue is intended for the window we created, then the corresponding window procedure we created earlier will be called. 
Other code can come in the else-branch of the if-else clause. This way, if no messages are available on the queue, we can let the processor handle other work (e.h. render calls). Now that we have covered a basic windows application, we are ready to move on to the creation of an OpenGL rendering context.

4. Closure
This article is already getting a bit long, so I'll wrap it up here now that we have some insight in our basic windows application and the required dependencies. The second part of this article will probably be finished somewhere next week. We'll have a look at initializing OpenGL 4.3, GLEW, vertex and fragment shaders. Feel free to leave some comments. Have fun coding and experimenting!