Running Linux, 5th Edition - Matthias Kalle Dalheimer [426]
Introduction to OpenGL Programming
Before we finish this chapter with a look at integrated development environments and in particular KDevelop, let's do some fun stuff—three-dimensional graphics programming using the OpenGL libraries!
Of course, it would be far too ambitious to give proper coverage of OpenGL programming in this book, so we just concentrate on a simple example and show how to get started and how OpenGL integrates with two popular toolkits.
GLUT
The GL Utility Toolkit was written by Mark Kilgard of SGI fame. It is not free software, but it comes with full source code and doesn't cost anything. The strength of GLUT is that it is tailored specifically for being very simple to get started with programming OpenGL. Mesa comes with a copy of GLUT included, and a free software reimplementation of GLUT is available from http://freeglut.sourceforge.net/. Basically, GLUT helps with initial housekeeping, such as setting up a window and so on, so you quickly can get to the fun part, namely, writing OpenGL code.
To use GLUT, you first need to access its definitions:
#include Next, call a couple of initialization functions in main(): glutInit(&argc, argv) to initialize GLUT and allow it to parse command-line parameters, and then: glutInitDisplayMode( unsigned int mode ) where mode is a bitwise OR of some constants from glut.h. We will use GLUT_RGBA|GLUT_SINGLE to get a true-color single-buffered window. The window size is set using: glutInitWindowSize(500,500) and finally the window is created using: glutCreateWindow("Some title") To be able to redraw the window when the window system requires it, we must register a callback function. We register the function disp() using: glutDisplayFunc(disp) The function disp() is where all the OpenGL calls happen. In it, we start by setting up the transformation for our object. OpenGL uses a number of transformation matrixes, one of which can be made "current" with the glMatrixMode(GLenum mode) function. The initial matrix is GL_MODELVIEW, which is used to transform objects before they are projected from 3D space to the screen. In our example, an identity matrix is loaded and scaled and rotated a bit. Next the screen is cleared and a four-pixel-wide white pen is configured. Then the actual geometry calls happen. Drawing in OpenGL takes place between glBegin() and glEnd(), with the parameter given to glBegin() controlling how the geometry is interpreted. We want to draw a simple box, so first we draw four line segments to form the long edges of the box, followed by two rectangles (with GL_LINE_LOOP) for the end caps of the box. When we are done we call glFlush() to flush the OpenGL pipeline and make sure the lines are drawn on the screen. To make the example slightly more interesting, we add a timer callback timeout() with the function glutTimerFunc() to change the model's rotation and redisplay it every 50 milliseconds. Here is the complete example: #include static int glutwin; static float rot = 0.; static void disp(void) { float scale=0.5; /* transform view */ glLoadIdentity(); glScalef( scale, scale, scale ); glRotatef( rot, 1.0, 0.0, 0.0 ); glRotatef( rot, 0.0, 1.0, 0.0 ); glRotatef( rot, 0.0, 0.0, 1.0 ); /* do a clearscreen */ glClear(GL_COLOR_BUFFER_BIT); /* draw something */ glLineWidth( 3.0 ); glColor3f( 1., 1., 1. ); glBegin( GL_LINES ); /* long edges of box */ glVertex3f( 1.0, 0.6, -0.4 ); glVertex3f( 1.0, 0.6, 0.4 ); glVertex3f( 1.0, -0.6, -0.4 ); glVertex3f( 1.0, -0.6, 0.4 ); glVertex3f( -1.0, -0.6, -0.4 ); glVertex3f( -1.0, -0.6, 0.4 ); glVertex3f( -1.0, 0.6, -0.4 ); glVertex3f( -1.0, 0.6, 0.4 ); glEnd(); glBegin( GL_LINE_LOOP ); /* end cap */ glVertex3f(