Beginning Device-independent Graphics Programming with OpenGL (using GL, GLU & GLUT)


We have already set up GLUT and OpenGL [↗]. Now we can start writing codes from the ground up.

Create an Empty C++ Win32 Console application and add a C++ source file.

Add necessary library headers as follow:

#include <stdlib.h>
#include <GL/glut.h>

Note» alteration of order will cause generation of error message.

Now let us write the main function that will perform the required initializations and start the event-processing loop. All the functions in GLUT have the prefix glut and those, which perform some kind of initialization, have the prefix glutInit (GL has gl and GLU has glu prefixes as well).

Note» Please do not start coding until I say it is time.

At first, we initialize glut using the function,

void glutInit//init GLUT lib & negotiate a session with the window system.
int *argc,  //pointer to unmodified argc var of main
char **argv //pointer to unmodified argv var of main
);

Then establish the window’s position:

int x,    //number of pixels from the left of the screen
int y     //number of pixels from the top of the screen
);            //for both deafult: -1 (positioned by system)

Now, choose the window size:

int width, //widht of window
int height //height of window
);

Unavoidable! Define the display mode:

void glutInitDisplayMode(unsigned int mode);

There are options for selecting modes. See documentation for more. We will use following for most of the cases,

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

Have completed above steps, the window can be created like this,

int glutCreateWindow(char *title);

» Here, title is a string that will be shown as the title of the displayed window.

`

Everything is set up; the kitchen is ready! Now start cooking. Yep, but you at least have to draw something before you really do the “hello world” of glut. So, we need the define a drawing function and call it from main, with the following,

void glutDisplayFunc//sets the display callback for the current window.
void (*func)(void) //name of function to be called when window is redrawn
);

» It is illegal to pass a Null as function and the return type of the display function should be void.

`

One last thing, tell glut to enter the event processing loop by calling,

void glutMainLoop(void);

Now, it is time we write some code, an example follows

#include <GL/glut.h>

void renderScene(void) {

glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glFlush();
}

void main(int argc, char **argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);

glutInitWindowPosition(100,100);

glutInitWindowSize(320,320);

glutCreateWindow(“nafSadh- GLUT Tutorial”);

glutDisplayFunc(renderScene);

glutMainLoop();

}

O.k., you have written your first (may be) program in glut, it is time you do some artisanship. If you run the code above, two windows will come, one the console window, another is OpneGL window. When the OpenGL window is resized, the triangle is distorted. To solve this, we need to add a functionality that handles the resizing. The glut function for this is,

void glutReshapeFunc(void (*func)(int width, int height));

This should be called just before the main loop, an example follow,

#include <GL/glut.h>

void renderScene(void) {

… … …

}

void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short (you cant make a window of zero width).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,
0.0,0.0,-1.0,
0.0f,1.0f,0.0f);
}

void main(int argc, char **argv) {

… … …

glutDisplayFunc(renderScene);

glutReshapeFunc(changeSize);

glutMainLoop();

}

Of course, what I included here is inadequately sufficient, but hopefully enough for a QUICK START. Regardless of anyone else’s effort, I must first mention, Lighthouse 3D’s tutorial was most helpful for me. Beside these, following are some other links I must share:

29 thoughts on “Beginning Device-independent Graphics Programming with OpenGL (using GL, GLU & GLUT)

  1. thanks for the nice tutorial ,.
    although i have one question…The title of your post is beginning device independent graphics programming , but you are using a win32 consol application to create your project…so how will this be able to run in any other OS .??

    Like

    1. My another post http://wp.me/puVgg-j tells how to configure GL environment in Win32 while this post never mention something about Win32.
      In this post, I described a generic program that is supposed to be compiled in any other OS (provided OpenGL & GLUT is already set up there).
      My title is “Device-independent” because the code is Device-independent. In fact it is not possible to achieve true device independence today, hope someday it will be.

      to run in any other OS, I’ll ask you to consult with someone familiar with GL on that OS or Google it… I’m sorry that I do not have much idea about GL on Mac, Linux or other platforms.

      Like

  2. #include // use as needed for your system
    #include
    #include
    //<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>
    void myInit(void)
    {
    glClearColor(1.0,1.0,1.0,0.0); // set white background color
    glColor3f(0.0f, 0.0f, 0.0f); // set the drawing color
    glPointSize(4.0); // a ‘dot’ is 4 by 4 pixels
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 640.0, 0.0, 480.0);
    }
    //<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
    void myDisplay(void)
    {
    glClear(GL_COLOR_BUFFER_BIT); // clear the screen
    glBegin(GL_POINTS);
    glVertex2i(100, 50); // draw three points
    glVertex2i(100, 130);
    glVertex2i(150, 130);
    glEnd();
    glFlush(); // send all output to display
    }
    //<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>
    void main(int argc, char** argv)
    {
    glutInit(&argc, argv); // initialize the toolkit
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
    glutInitWindowSize(640,480); // set window size
    glutInitWindowPosition(100, 150); // set window position on screen
    glutCreateWindow(“my first attempt”); // open the screen window
    glutDisplayFunc(myDisplay); // register redraw function
    myInit();
    glutMainLoop(); // go into a perpetual loop
    }

    When i build the code it gives me the following error:
    1>—— Build started: Project: Project1, Configuration: Debug Win32 ——
    1>Build started 31-03-2011 22:33:37.
    1>InitializeBuildStatus:
    1> Touching “Debug\Project1.unsuccessfulbuild”.
    1>ClCompile:
    1> All outputs are up-to-date.
    1>ManifestResourceCompile:
    1> All outputs are up-to-date.
    1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
    1>c:\users\toshiba\documents\visual studio 2010\Projects\Project1\Debug\Project1.exe : fatal error LNK1120: 1 unresolved externals
    1>
    1>Build FAILED.
    1>
    1>Time Elapsed 00:00:00.42
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    how do i solve this???

    Like

    1. try to add some headers, as I see in the code you pasted here, there are no include file. Also make sure, glut.h and other OpenGL headers and files are in place. Make sure that, the project you are using is console application and you started with an Empty Project and not one with some pre-configured text.

      Like

      1. yep i have included header:
        windows.h, gl/Gl.h, gl/glut.h.

        how do i know where the header files should be ? the glut.h is in correct plz….which others should i check?. It is an Empty project…..
        kkk it was not a console appliacation….i made it console now it worked 🙂
        so tell me whats the diff between win32 console and win32 project?

        Like

      2. I see you are using MSVS10. Please check the path as in http://wp.me/puVgg-5u , and please check :

        In order for this to work for VS2010, I had to modify:
        Type “opengl32.lib glu32.lib” in Additional Dependencies and click OK.

        to

        Type “opengl32.lib; glu32.lib;” in Additional Dependencies and click OK.

        Like

  3. The included header files are :
    #include
    #include
    #include

    I installed and pasted the files of GLUT downloaded from Nate Robins site…as mentioned by u. Im working on windows 7.

    Like

  4. #include
    #include
    #include

    void myInit1(void)
    {
    glClearColor(1.0,1.0,1.0,1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 640.0, 0.0, 480.0);
    }

    void myDisplay1(void)
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    }

    void myMouse(int button, int state, int x, int y)
    {
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {

    GLint x1=x;
    GLint y1=y;
    glBegin(GL_POINTS);
    glColor3f(0.4, 0.4, 0.4); // set the drawing color

    glVertex2i(x1,y1);
    glEnd();

    }
    else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {
    exit(-1);
    }
    }

    void main(int argc, char** argv)
    {
    glutInit(&argc, argv); // initialize the toolkit
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
    glutInitWindowSize(640,480); // set window size
    glutInitWindowPosition(100, 150); // set window position on screen
    glutCreateWindow(“mouse events”); // open the screen window
    glutDisplayFunc(myDisplay1); // register redraw function
    myInit1();
    glutMouseFunc(myMouse);
    glutMainLoop(); // go into a perpetual loop
    }

    no point is being drawn on left click ….can u figure out why???

    Like

    1. some very important functions are:

      glutKeyboardFunc(myKeyboardFunc);

      glutReshapeFunc(resizeWindow);
      glutDisplayFunc(drawScene);
      glutIdleFunc(animate);
      glutMainLoop();

      following is a main function I used once for one of my assignments,

      int fractalsmain (int argc, char **argv)
      {
      glutInit(&argc, argv);
      //This initializes the GLUT library, passing command line parameters
      //(this has an effect mostly on Linux/Unix)
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      //Initial parameters for the display. In this case, we are specifying
      //a RGB display (GLUT_RGB) along with double-buffering (GLUT_DOUBLE),
      //so the screen won't flicker when we redraw it.
      //GLUT_DEPTH Specifies a 32-bit depth buffer

      glutInitWindowPosition(-1,-1);
      glutInitWindowSize(winW,winH);
      //Initial window size - width, height
      glutCreateWindow("Nafsadh's Fractal Tree");
      //Creates and sets the window title
      initRenderingf();

      glutKeyboardFunc(myKeyboardFuncf);
      //Sets the keyboard callback function for the current window.

      glutReshapeFunc(resizeWindowf);
      glutDisplayFunc(drawScenef);
      //This function tells GLUT which function to call
      //whenever the windows contents must be drawn.
      //This can occur when the window is resized or uncovered or
      //when GLUT is specifically asked to refresh with a call to
      //the glutPostRedisplay function.
      glutIdleFunc(animatef);
      //This is particularly useful for continuous
      //animation or other background processing.

      glutMainLoop();
      //This function begins the main GLUT event-handling loop.
      //The event loop is the place where all keyboard, mouse,
      //timer, redraw, and other window messages are handled.
      //This function does not return until program termination.

      return (0);
      }

      read the comments carefully.

      Like

  5. ive written this code to rotate a pyramid and cube. The speed of rotation changes when the window size is changed. How can we stop that from happening?

    //#include
    #include
    #include
    #include

    GLfloat rtri=7;
    GLfloat rquad=7;

    void init(void)
    {

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glShadeModel (GL_SMOOTH);

    }

    void display(void)
    {

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity ();

    glTranslatef(-1.5f,0.0f,-10.0f);
    glRotatef(rtri,1.0f,0.0f,0.0f);

    glBegin(GL_TRIANGLES);
    glColor3f(1,0,0);
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0,1,0);
    glVertex3f(-1.0,-1.0, 1.0);
    glColor3f(0,0,1);
    glVertex3f(1.0, -1.0,1.0);

    glColor3f(1,0,0);
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0,1,0);
    glVertex3f(1.0, -1.0, -1.0);
    glColor3f(0,0,1);
    glVertex3f(1.0, -1.0, 1.0);

    glColor3f(1, 0,0);
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0,1,0);
    glVertex3f(1.0, -1.0, -1.0);
    glColor3f(0,0,1);
    glVertex3f(-1.0, -1.0, -1.0);

    glColor3f(1,0,0);
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0,1,0);
    glVertex3f(-1.0, -1.0, 1.0);
    glColor3f(0,0,1);
    glVertex3f(-1.0, -1.0, -1.0);

    glEnd();

    glLoadIdentity();
    glTranslatef(1.0, 0.0, -4.0);
    glRotatef(rquad,0.0f,1.0f,1.0f);

    glColor3f(1.0, 0.0,0.0);
    glBegin(GL_POLYGON);
    glVertex3f(-1.0, 1.0,1.0);
    glVertex3f(1.0, 1.0, 1.0);
    glVertex3f(1.0, -1.0,1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glEnd();

    glColor3f(0.0, 1.0,0.0);
    glBegin(GL_POLYGON);
    glVertex3f(1.0, 1.0,1.0);
    glVertex3f(1.0, -1.0,1.0);
    glVertex3f(1.0, -1.0,-1.0);
    glVertex3f(1.0, 1.0, -1.0);
    glEnd();

    glColor3f(0.0, 0.0, 1.0);
    glBegin(GL_POLYGON);
    glVertex3f(1.0, 1.0,-1.0);
    glVertex3f(1.0, -1.0, -1.0);
    glVertex3f(-1.0, -1.0,-1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glEnd();

    glColor3f(1.0, 1.0, 0.0);
    glBegin(GL_POLYGON);
    glVertex3f(-1.0, -1.0,-1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glVertex3f(-1.0, 1.0,1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glEnd();

    glColor3f(0.0, 1.0, 1.0);
    glBegin(GL_POLYGON);
    glVertex3f(-1.0, 1.0,-1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f(1.0, 1.0,1.0);
    glVertex3f(1.0, 1.0,- 1.0);
    glEnd();

    glColor3f(1.0, 0.0, 1.0);
    glBegin(GL_POLYGON);
    glVertex3f(-1.0, -1.0,-1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0,1.0);
    glVertex3f(1.0, -1.0,- 1.0);
    glEnd();

    glutSwapBuffers();
    glutPostRedisplay();

    rtri+=0.2;
    rquad+=0.05;
    }

    void reshape (int w, int h)
    {

    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(50.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
    glMatrixMode (GL_MODELVIEW);

    }

    void animate()
    {

    glutPostRedisplay();

    }

    int main(int argc, char** argv)
    {

    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (argv[0]);
    init ();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    glutIdleFunc(animate);

    glutMainLoop();
    return 0;

    }

    Like

    1. I’m not sure how. Please refer to the OpenGL website and F.S. Hill’s book. They might be of help.
      Please, make a blog post describing how you manage to do that, and post a link of that in here 🙂

      best of luck

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.