Wednesday, June 10, 2009

Function-Plot: Sample OpenGL program

Before we sit down to writing code we have to set up our environment. You can download the glut library from here. Alternatively you can use the Dev C++ IDE's Package Manager to download it. For those who use Dev C++ you can go to Tools>Check for Updates/Packages and download glut from there.
After you successfully finish downloading you can start a new glut project by clicking File>New>Project and selecting the Multimedia tab and selecting glut as your project type.
You will instantly see a sample glut program. Just to get a taste of what you can accomplish, try running it. Select Execute>Compile and Run or press F9.

Now lets jump straight to out own glut project. Our objective is to plot a simple two dimensional sine curve on the screen. This will help to familiarize you to the opengl programming. Try running this program. I will elaborately explain the code in the following lines.


#include
#include<stdlib.h>
#include<math.h>


void Init(void)
{
glClearColor(0.0f,0.0f,0.0f,0.0f); // choose a color to clear the screen with
glColor3f(1.0f,1.0f,1.0f); // choose a fill color
glPointSize(1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0); // set up the co-ordinate system
}


void funcPlot(void)
{
glClear(GL_COLOR_BUFFER_BIT);
GLdouble x,y;
glBegin(GL_LINES); // Start drawing lines
glVertex2i(0,240); // Draw a vertex( a point,well almost) at (0,240) world co-ordinates
glVertex2i(640,240);
glEnd(); // end drawing

glBegin(GL_POINTS); // begin drawing points
for(x=0.0;x<8.0;x+=0.005)>
y = (480/2)+ (10 * sin(x));
glEnd(); // end drawing
}

int main(int args,char** argv)
{
glutInit(&args,argv);
glutInitWindowPosition(0,0);
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutCreateWindow("Function Plot Example");
glutDisplayFunc(funcPlot);
glutMainLoop();
return(0);
}

To take you through this I prefer to start with the main() function. The function glutInit() is called to start a new new thread and create a new window instance to run your program. The function calls that follow, set the various properties of your rendering context and your window instance. The beauty of glut is that you need'nt worry about creating your window handles and managing your contexts, glut does it all for you. The internal implementation of glut is such that these tasks are performed for you depending on your native window system. Hence the platform independancy. The glutInitDisplayMode() call defines your rendering context. The parameters passed to it ie. GLUT_SINGLE | GLUT_RGB, denote that you need a single display buffer and your color mode is RGB or Red, Green and Blue. It will be clear further what they excatly mean but for now think of the display buffer as a contigious memory block where you're rendered scene will be temporarily stored before it is pushed into the display. The color mode needs further explaination. As you know white light comprises of all colors. But a colored light is characterized by the absence of certain components, coherently it can also be said that colored light is rather a combination of various color components in specific proportions. Thus RGB is color mode is a method in which every color is denoted as a combination of Red, Green and Blue. The next three lines are self explainatory. glutInitWindowSize() specifies the size or resolution of your window in (pixel width) x (pixel height). glutInitWindowPosition() is used to postion your window relative to the screen co-ordinate system. The screen co-ordinate system is defined in two dimensions. The top left corner of your screen is considered the origin (0,0) and x and y co-ordinates increase as we move towards the right and downward respectively. Finally glutCreateWindow() creates your window with the title specified as the parameter. The next section is where you register your call back functions. Call back functions in simple terms are functions that are called when a specific event occurs. For instance, a screen resize operation gives rise to a resize event(I will introduce this later). To handle this event we implement a function that is to be called every time a resize event occurs. Then to let glut know that this is the function to be called for such an event, we register it. In the next line we see that the the display call back is registered. The init() function that is called next is where you setup the canvas for you to draw on. The glClearColor() specifies the color that you want to clear your screen with, everytime you redraw the scene. The first three values are the Red, Green and Blue components of your color and the fourth value is alpha(leave this for now). The glColor3f() function chooses your drawing color. The next few lines are better understood later so for now think of this operation as setting up your world co-ordinate system. The display call back that we registered in main is implemented as shown. I believe most of you will have no difficulty understanding it and for now the comments in the code should suffice.

Saturday, June 6, 2009

OpenGL Introduction sans the nonsense

This post is intended to make you feel at ease with using the OpenGL API. Here, I will cover the functionality of the low level procedures along with a brief overview of any graphics library in general.

It is naturally intimidating to see the highly complex computer displays, or the cutting edge 3D graphics and visuals of a movie scene. But it might surprise you to know that whatever be the case, the end result of that ultra realistic 3D world is a sequence of flattened images on a 2D screen. What actually happens is that a set of functions are implemented to calculate the depths, the lighting, the surface normals etc. (all of which I will explain clearly later) in the virtual world and finally map the 3D images onto a 2D plane. Thankfully, the implementation of these functions (which vary from library to library) are abstracted from the programmer.
Any known graphics library adheres to the following simple (at times) steps:
  1. Establish a co-ordinate system for the screen onto which the image is projected.
  2. Establish a co-ordinate system for the virtual world.
  3. Implement a function that allows the programmer to draw a point ( the smallest point one can draw is a pixel). It is this basic primitive that allows a programmer to draw in complex shapes and objects.
  4. Allow a way to specify normals to any surface or point (this helps in lighting and also when we want to simulate physics) .
  5. Provide methods to operate on matrices (Matrices are used to translate, rotate or scale
  6. Provide other common methods that might make the programmer's life easy.
Now lets jump straight to OpenGL.
Most books introduce you to a simple OpenGL program to start off with. But I feel there is a need to break this tradition. So, ill first do the explaining part and then show you the program.

OpenGL like all other graphic libraries encapsulates the aforesaid points in some way or the other. This will be clear if i explain in common language the structure of a typical OpenGL program. Keep in mind that i am using GLUT.

  • Include necessary files
  • Write a main function like any C/C++ program. And in main call a few glut functions which will set up and handle your window in which you are going to draw. To be more specific you will be setting up the display modes, the window sizes, window positions, menus in your windows(if there are any) etc.
  • Also in the main function after the initialization done in the previous step, you register the call back functions for necessary events. Further explaination is required here. Now in any window based program the code that is to be executed next is decided based on events. For instance when you click a mouse button, a mouse button event is generated, and to act on this event and perform the necessary action the programmer implements a call back function for mouse events. But how does GLUT know that the function that is implemented is a mouse call back? Hence the call back function is registered with GLUT as being a mouse event based call back function.
  • Now these call back functions that were just registered have to be implemented to actually be of any use. So that is done next. Also note that since registering a call back means you have to implement them before your main function.
And thats it! Thats how simple an OpenGL program is.
The next post presents a simple OpenGL program where a sine function is plotted on screen.

OpenGL - Introduction

OpenGL is widely considered as hard to tame. It is often intimidating to amateur and overenthusiastic programmers who's approach is to take a plunge into it at first sight. Though it may be encouraging to see, it often leaves them terribly confused.

Before GLUT, ( GL utility toolkit) which conviniently keeps us away from the complexities of window system related code, OpenGL programming was a daunting task. Despite this benifit, which GLUT gives us, it helps to be guided by a detailed tutorial or walk-through.

The soul aim of this tutorial is to eliminate the hardships faced by wannabe "GLUTtons". This tutorial is tailored in the way in which I taught myself this skill. I will try my best to ensure that I leave no doubts in the reader's mind.