Department of Computing Science Umeå University

OpenGL introduction


This short OpenGL introduction will show you how to set up a window, do some basic drawing and manage input. The code presented should be considered a sample, not as "correct code".

  1. Setting up the window
  2. Do some drawing
  3. Keyboard handling
  4. Mouse handling
  5. NDC Coordinates
  6. Popup menus with GLUT
  7. GTK and OpenGL

There is quite some stuff to be done before you can draw anything at all. All code in this intro will be written in C, even though C++ can be useful for some of the projects. To fully understand the OpenGL commands, read about the different commands at OpenGL and GLUT resources.

I really recommend NeHe OpenGL Tutorials, even though they are written in C++ for Windows. There is also translations at the end of eachtutorial.

Setting up the window

Here, we will set up a window for 2D drawing and while doing so, try to explain some of the functions used. The starting code can be found here.

First we need to initialize GLUT, which we will use to create the window and handle some other things.

glutInit(&argc, argv);
Then, to create a window and set up some preferences;
glHint(GL_POINT_SMOOTH_HINT, GL_FALSE);
glPointSize(1.0);
/* Always open a displaymode first */ 
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  
glutInitWindowSize(Width,Height);
glutInitWindowPosition(0,0);  
glutCreateWindow("OpenGL intro sample application");
glutDisplayFunc(drawDisplay);
glutReshapeFunc(resizeFunc);

The first to commands sets the pointsize and turn of smoothing of points. This will be useful in project 1 to be able to see all pixels. The third command initializes the display mode, which is here configured with double_buffering and RGB-colored pixels. Then we set up the window size and position, and create the window. To be able to draw anything (when using double-buffering) we need a routine to draw to the display, and this must be registered to OpenGL with glutDisplayFunc.

resizeFunc will be called when the window was resized (ie by the user). It should setup the drawing area and load default information.

void resizeFunc(int Width, int Height) {
    glViewport(0,0,Width,Height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0,Width,Height,0);
    glMatrixMode(GL_MODELVIEW);
}

First we set up the viewport which defines the area of "cyberspace" you can see through the window. glMatrixMode defines which matrix should be manipulated (check the reference and the book to fully understand this).

gluOrtho2D defines a 2D orthographic projection matrix, that is a 2D viewing region. This method should be replaced when working in 3D.

Draw something

The drawDisplay function described above should, as I said take care of all drawing. First though, we should clear the buffer (screen image).
void drawDisplay(void) {
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);

The first sets the clear color. Note that the last parameter sets the Alpha-value, which is not used. glClear actually clears the buffer.
Now we can draw something to the buffer. We start by setting the color of the object, and then draw a rectangle.

glColor3ub(1.0,1.0,1.0);
glBegin(GL_POLYGON);
    glVertex2i(50,50);
    glVertex2i(50,300);
    glVertex2i(300,300);
    glVertex2i(300,50);
glEnd();

When all the painting is done, we must display the buffer to the screen. Remember that we used double-buffering, that is we use two buffers, one to draw to and one to display on the screen. When a new picture has been drawn to the so called "backbuffer", we simply swap the buffers to display the new picture.

    glutSwapBuffers();
}

Finally, when this is set up, we must start the main processing loop of GLUT, which actually produce events for drawing and resizing. This is done by calling;

glutMainLoop();

You should now be able to compile the program and test it. You should see a white square, unless something went wrong.

  • Experiment with glViewport and gluOrtho2D. Try to figure out why I use different order of the arguments and try out what will happen if the same order was used.
  • It is a good idea to be able to express colors by names. Check glColor reference and try to use the vector based methods to set the color. Then define a color type and some color variables of that type. Use these to set the color.
  • Try to change the background color. Figure out what the Alpha value does?

Keyboard handling

When this is done, it is time to be able to do something. All input routines is implemented in the same way as the resize and drawing functions; that is you should supply GLUT with a method for keyboard input. The function looks like this;

void Keyboard(unsigned char key, int x, int y {
}

The x and y parameters specify the position of the mouse at the time the key was pressed.
To register the function, use;

glutKeyboardFunc(Keyboard);
  • Try to add a function to change the color of the square you painted using the keyboard.
  • Try to figure out how to draw some text on the screen.

Mouse handling

The mouse input is captured in a few functions; one for buttons, one for moving and one for dragging. (There might be more functions, but these three builds the base).

void MouseEvent(int button, int state, int mouseX, int mouseY);
void MoveMouse(int mouseX, int mouseY);
void DragMouse(int mouseX, int mouseY);

All methods give the mouse position, but the first also returns the button number and its state. Register these events with;

    glutMouseFunc(MouseEvent);
    glutMotionFunc(DragMouse);
    glutPassiveMotionFunc(MoveMouse);

When this is done, you should be able to print out events on standard out.

  • Create an event function that prints the mouse position to standard out. Then, return to the gluOrto2D function and try out different parameter orders and values. (Unless you solved the question earlier, you should be able to do it now).
  • Create an event function that let you change color of the square using different mouse buttons.
  • Create a move or drag function that draws an object at the mouse location.That is when the mouse moves, the object should do that too.

NDC Coordinates

When the user resizes your window, the picture will probably stay in a corner unless you calculate new positions of the objects. To do this a bit more easy, you should use NDC Coordinates. These range from 0 to 1 in each direction, and can be used to specify a position of the object.

Write two methods to translate between screen coordinates (pixels, positions returned by mouse routines) and NDC coordinates. These should be;

void screen2ndc(int x,int y, float *ndc_x, float *ndc_y)
void ndc2screen(float ndc_x, float ndc_y,int *x,int *y)

Note that you will need these further on, even if you may need to rewrite them to fit your projects.

Popup menus with GLUT

Since GUI is subject for the Human-Computer Interaction course, we have relaxed the requirements of the GUI in your projects. However, you will need some way to manage settings in your application. GLUT popup menus are very easy to use and simple to set up. There are however some issues on Sun that may arise.

First, study the reference documentation to find out what methods to use. Then try to create a simple example. I suggest you look at these functions;

glutCreateMenu
glutAddMenuEntry
glutAddSubMenu
glutAttachMenu
glutMenuStatusFunc
  • Try to set up a simple menu using these routines. Then attach it to a mouse button and test it.
  • Add an itemhandler that prints the item number to standard out.
  • Do something interesting.

I mentioned an issue that may arise on Sun machines. When displaying a popup menu, it may turn black. This is due to the clear function of the drawing routine. To prevent this from happening, use MenuStatusFunc to detect when the menu is visible and prevent updating the screen then. A sample MenuStatusFunc might look like this;

void glutMenuIsActive(int status,int x, int y) {<>    
    if (status==GLUT_MENU_IN_USE) {
        glutPostRedisplay();
        glutPostRedisplay();
        dontClear=1;
    }
    else dontClear=0;
}

GTK and OpenGL

To all of you who don't like a program without a GUI (like me), I looked around to find some information about using GTK to create a user interface. Here is a few links that might be useful.

To learn GTK, try these

If you find any useful pages on the web, please email us and we will put them here.




Responsible for the page: Anders Pettersson
Last modified 2004-11-01
Copyright © 2004. All rights reserved.