Introduction to c++/opengl game programming for beginners
No.1
Hi All!
I’m starting a tutorial series about using C++ with OpenGL and this is the first one.
NOTE:this tutorial may seem big, but the next ones will be much smaller because you wont need to write the code in this tutorial from scratch
In this tutorial you will learn the basics of the OpenGL library and the various elements/functions that you will be dealing with through OpenGL. You will need to know the basics of C++ and some WINAPI before you read this.
What’s OpenGL???
OpenGL stands for “Open Graphics Library” and it’s a library that offers low-level rendering utilities and an interface to the graphics card. What really makes OpenGL special is that it is cross-platform and it’s really easy and fun to learn.
- there’s many methods to setup an OpenGL window and all of them will work just fine. I choose this one because it uses less header files and you wont need to add more code when you try to modify or make a new project using the same code.
These are the header files we will be using through this tutorial series:
Code:
#include <stdio.h>
#include <gl.h>
#include <glaux.h>
These header files are included with VC++ and devcpp.
The first header file is the one used to build a window that holds the opengl elements; the “gl.h” is the primary header for the opengl library the “glux.h” is an opengl utility tool that adds more functionality.
Note: if your header files are in another folder make sure that you add it in the additional library directories, from clicking on the project properties->linker->general->additional library directories
For example If you have the .h files in the c: directory , it should be like this:

Before we jump into coding we must be familiar with 2 variables: (1) The Device Context which is responsible for drawing anything on the window and to link opengl to the device context we will need a (2) rendering context. The first step of any opengl application is to setup the context device and rendering context (the first two variables).
Code:
HGLRC rc=NULL;
HDC dc=NULL;
HWND wnd=NULL;
HINSTANCE hInstance;
bool ready=TRUE;
The third and fourth variable will hold our window object and its instance. The bool variable will tell us if the window is active and ready for drawing or not.
Now let’s set up our window:
If you’ve done winapi programming before you should be familiar with this code. In this code we create a basic window after that we start the OpenGL function (I’ll explain it after this). Notice that it took 4 parameters: the first is the title of the window and the others are the width, height and the number of bits that will be used for colors (I’ll explain later). The “msg” variable holds values about the status of the window. When the message of that variable is “WM_QUIT” we break out of the while loop to dispose the opengl window. When the window is ready and active we run the famous “DrawGLScene(); “ function
Code:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
BOOL done=FALSE;
startglwindow("Tutorial no.1 - OpenGl",640,480,16);
while(!done)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if (ready)
{
DrawGLScene();
SwapBuffers(dc);
}
}
}
KillGLWindow();
return (msg.wParam);
}
---so this code set up our winapi window and started two functions the “startglwindow” which will run once and the “DrawGLScene();” which will keep running till the application quits.
Now lets see how to start the opengl window:
It takes 4 parameters the title that will be dislayed at the top of the window, the width and height of the window, and the bits that will be used for colors theres 8bits,16bits,24bits, and 32bits
Here we declared some functions that we will need in the function. The first one will store the pixel format. The wndclass variable (wc) will hold the attriutes and properties of the window that we will create, the two DWORD(double word) variables the dwExStyle is assigned later with the style of the window weather its “WS_EX_APPWINDOW” which means that the window is minimized to the taskbar or “WS_EX_WINDOWEDGE” that means that the window isnt minimized and has “edges” and borders(lets not get into details) then we ave 4 variables that will specify the borders of the window and we assigned them with the values of the passed parameters
-after that we setted up the wc (window class) with the needed properties (you can change the cursor look, icon of the window and styles). Then we register our class “RegisterClass(&wc);“
Code:
BOOL startglwindow(char* title, int width, int height, int bits)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
RegisterClass(&wc);
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
Now we will assign the wnd variable that we already decleared in the beginning. If you are doing some customization to the window , DON’T, remove the “WS_CLIPSIBLINGS” and “WS_CLIPCHILDREN” because they are needed by the opengl.
Code:
//the next part is partially taken from another tutorial
wnd=CreateWindowEx(dwExStyle,"OpenGL",title,dwStyle | WS_CLIPSIBLINGS |WS_CLIPCHILDREN,0, 0,WindowRect.right- WindowRect.left,WindowRect.bottom-WindowRect.top,NULL,NULL,hInstance, NULL);
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
The revious part of code describes a Pixel Format. We choose a format that supports OpenGL and double buffering,RGBA (red, green, blue, alpha channel),Set Color Depth and set up a 16bit Z-Buffer other arguments are not important or not useful here.
Then we get the device context and assign the pixel format with the appropriate formate according to the current device context to accommodate the hardware, after choosing the right device context and the aroriate pixel formate we create a rendering context “rc=wglCreateContext(dc);”. Then we show the window for the user when the window is ready and the background of the opengl window is the winapi window then we call wo funcions “resize(width, height);” and “InitGL();“ which ill explain later.
Code:
dc=GetDC(wnd);
PixelFormat=ChoosePixelFormat(dc,&pfd);
SetPixelFormat(dc,PixelFormat,&pfd);
rc=wglCreateContext(dc);
wglMakeCurrent(dc,rc);
ShowWindow(wnd,SW_SHOW);
SetForegroundWindow(wnd);
SetFocus(wnd);
resize(width, height);
InitGL();
return TRUE;
}
Now we are done with the hard part
, till now we created a blank window then we will initialize the opengl elements and draw stuff on the screen
So lets see how to initialize opengl:
In the first line we choose our shading technique there only two to choose from (GL_FLAT & GL_SMOOTH). I chose the flat shading (it wont matter since we arnt doing any 3d in this tutorial).
After that we choose the background color, as you see it takes 4 parameters. The first one is red, the second is green, the third is blue , and the last one is alpha. If your color is (1.0f,0.0f,0.0f,0.0f) you will make a red background of course mixing the colors will produce new colors.
The third line: this function takes two parameters the first one is an element that we want to change its properties an the second parameter is the change , so here we need to make the prespective view(GL_PERSPECTIVE_CORRECTION_HINT)takes the mode (GL_NICEST). You have 3 modes to choose from GL_FASTEST, GL_NICEST, GL_DONT_CARE. (no explanation needed)
Code:
int InitGL(GLvoid)
{
glShadeModel(GL_SMOOTH);
glClearColor(0.5f, 1.0f, 1.0f, 0.0f); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
-now our opengl is running and we can draw shapes on it, but wait…our window is resizable so if the used changed its widt or height our glwindow wont draw itself, so we will need to add this function
In this code we pass the new width and height, and the code will change the viewport, in the next line we set the matrixmode which is used to manage the view there are two modes to choose from (projection and modelview) projection is usually used when you want to set the portview and modelview is used when you want to rotate or scale an object
So here we changed the matrixmode to adjust the perspective view in theis line “gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);” then we changed the matrixmode back to model view
Code:
GLvoid resize(GLsizei width, GLsizei height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
-now everytime the window size is changed the resize function sets the perspective to the new size of the window.
Before we go to the drawing part lets first view a typical “KillGLWindow” that will run when the application is closed:
I don’t think theres explaination needed here but anyways, we make the current gl null and delete the rendering context and set it to null and do the same with the device context then we unregister the wnd class
Code:
GLvoid KillGLWindow(GLvoid)
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(rc);
rc=NULL;
ReleaseDC(wnd,dc);
dc=NULL;
DestroyWindow(wnd);
wnd=NULL;
UnregisterClass("OpenGL",hInstance);
hInstance=NULL;
}
--now it’s the fun time
All the previous code will rarely change each time yo make a new 2d opengl application.
Lets see how to draw stuff on the screen:
In this drawscene we made a colored triangle, lets see how it works:
In the first line we clear the screen from the previous scene and clear the buffer to update the new scene, in the second line we reset the opengl scene.
the “glTranslatef(0.0f,0.0f,-10.0f);” statement here specifies the position of shape you will draw after it it takes three arguments which represent the x,y,z axis. I used the z to make it look far to make the shape look smaller.
Negative x means that the shape will be on the left side , vice versa
And positive y means the shape will be on the upper side of the screen
Positive z will zoom the shape or make it look closer
Now the “glBegin”
It’s the function that let us choose what shape to draw. The basic shapes that you can draw are:
GL_POINTS:that draw dots on the screen, you don’t need to specify glvertex3f for it.
GL_LINES:draws a line between 2 glvertex3f
GL_TRIANGLES : triangles
GL_QUADS :to draw a square
GL_LINE_STRIP: polylines
GL_LINE_LOOP :closed loop
Code:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-10.0f);
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(1.0f,0.0f,0.0f); //red
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(1.0f,0.0f,1.0f); //red
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
return TRUE;
}
The final look of the window will look like this:

I hope that you like my first tutorial , and feel free to ask me anything about it
in the next tutorial we will learn how to use keyboard and mouse with opengl 
*thanks alot jordan for correcting my tutorial
EDIT:source code added
Bookmarks
Algorithms and Data Structures
Java tutorials
Algorithms Forum