introduction to opengl
introduction to opengl
It is a window system independent, operating system independent graphics rendering API which is capable
of rendering high-quality color images composed of geometric and image primitives. OpenGL is a library
for doing computer graphics. By using it, you can create interactive applications which render high-quality
color images composed of 3D geometric objects and images. As OpenGL is window and operating system
independent. As such, the part of your application which does rendering is platform independent. However,
in order for OpenGL to be able to render, it needs a window to draw into. Generally, this is controlled by
the windowing system on whatever platform you’re working on. Summarizing the above discussion, we
can say OpenGL is a software API to graphics hardware. · Designed as a streamlined, hardware-
independent interface to be implemented on many different hardware platforms.
Procedural interface
No windowing commands.
No high-level commands.
OpenGL as a Renderer
OpenGL is a library for rendering computer graphics. Generally, there are two operations that you do with
OpenGL:
draw something
change the state of how OpenGL draws
OpenGL has two types of things that it can render: geometric primitives and image Primitives. Geometric
primitives are points, lines and polygons. Image primitives are Bitmaps and graphics images (i.e. the
pixels that you might extract from a JPEG image after you’ve read it into your program.) Additionally,
OpenGL links image and geometric The other common operation that you do with OpenGL is setting
state. “Setting state” is the process of initializing the internal data that OpenGL uses to render your
primitives. It can be as simple as setting up the size of points and color that you want a vertex to be, to
initializing multiple pixmap levels for texture mapping.
GLUT is designed for constructing small to medium sized OpenGL programs. While GLUT is well-suited
to learning OpenGL, and developing simple OpenGL applications, GLUT is not a full-featured toolkit so
large applications requiring sophisticated user interfaces are better off using native window system toolkits.
GLUT is simple, easy, and small. The GLUT library has C, C++ (same as C), FORTRAN, and Ada
programming bindings. The GLUT source code distribution is portable to nearly all OpenGL
implementations and platforms. The current version is 3.7. Additional releases of the library are not
anticipated. GLUT is not open source. Mark Kilgard maintains the copyright. There are a number of newer
and open source alternatives.
The toolkit supports:
Void glutInit()
glutInit() initializes the GLUT library, and it must be called before any other GLUT function. Argc and
argv should be the arguments of the application’s main() – glutInit() understands several Command-line
options, which are beyond the scope of this manual (see the GLUT manual for details).
Next, we call glutCreateWindow():
int glutCreateWindow( char *name)
glutCreateWindow() creates an OpenGL window for rendering and interaction, with name displayed in
its title bar. GLUT assigns this window an integer identifier, returned as the result of the function. The
window identifier is used when writing OpenGL programs which use multiple windows By default, the
window has a size of (300, 300) pixels, and its position is up to the window manager to choose. If the
functions glutInitWindowSize() or glutInitWindowPosition() have already been called, their arguments
will control the size and position of the window. Next comes a call to glutDisplayFunc(), and this is a bit
more interesting. It’s an example of one of the cornerstones of OpenGL programming, which we’ll need to
look at in detail – the use of Callback functions.
A callback function, more often just called a callback, is a C function, written by the application
programmer.
Void glutDisplayFunc( void(*func)(void))
glutDisplayFunc() registers the name of the callback function to be invoked when OpenGL needs to
redisplay (or display for the first time) the contents of the window. The application
must register a display function – it isn’t optional. The argument of glutDisplayFunc() is rather cryptic,
and worth a closer look:
void (*func)(void)
This says that func() must be a function which returns void, and has no arguments. In other words, a function
like display():
void display (void) :
/* Called when OpenGL needs to update the display */
glClear (GL_COLOR_BUFFER_BIT) /* Clear the window */
glFlush() /* Force update of screen */
Here, the “3f” part of the function name means that the function takes three arguments, each of which is a
GLfloat.(Note: GL uses its own data types). GLfloat is equivalent to the C++ type float. So, for example,
to define the vertex at (10, 8, and 5) you would call: glVertex3f (10.0, 8.0, 5.0);
Many OpenGL functions come in several flavors. For example, suppose you only ever want to do 2D
drawing, so you’re only concerned with specifying vertices in the XY plane, and all vertices will have a Z
coordinate of 0. To make life easier, OpenGL offers a variant form of the
glVertex3f() function, called glVertex2f():
Internally, this function still creates a 3D vertex, but it sets its Z coordinate to 0.0 for you, to save you the
bother. But in this manual, we will always use the 3D form of functions – the less functions we have to
remember, the better!
2. Defining Shapes: primitives
A vertex on its own isn’t very interesting. Now we look at how to group vertices together into
vertex lists, which define geometrical shapes. The grouping of vertices is done with the
glBegin() and glEnd() functions:
glBegin() defines the start of a vertex list mode determines the kind of shape the vertices describe, which
can be:
A set of unconnected points (GL POINTS);
Lines (GL LINES, GL LINE STRIP, GL LINE LOOP);
The boundary of a single convex polygon (GL POLYGON);
A collection of triangles (GL TRIANGLES, GL TRIANGLE STRIP, GL TRIANGLE FAN);
A collection of quadrilaterals (GL QUADS, GL QUAD STRIP).
Drawing Points
In the function glBegin(), the values of mode which interpret vertices as points to connect with lines are:
GL LINES: each pair of vertices is drawn as a separate line.
GL LINE STRIP: all the vertices are joined up with lines.
GL LINE LOOP: all the vertices are joined up with lines, and an extra line is drawn from the
last vertex to the first.
glBegin (GL_LINES); /* or GL_LINE_STRIP or GL_LINE_LOOP */
glVertex3f (0.0, 6.0, 4.0)
glVertex3f (0.0, 8.0, 0.0)
glVertex3f (8.0, 6.0, 0.0)
glVertex3f (8.0, 3.0, 0.0)
glVertex3f (6.0, 0.0, 5.0)
glVertex3f (2.0, 0.0, 5.0)
glEnd ();
Line attributes
glLineWidth() sets the curent line width, measured in pixels. The default value is 1.0.
glLineStipple() sets the stippling pattern for lines, which enables lines to be drawn in a flexible variety of
dot/dash patterns. By default, stippling is switched off (see Section 7.6.2), and must be enabled by calling:
glEnable(GL_LINE_STIPPLE)
Line stippling works on a pixel-by-pixel basis, as the line is rendered into the frame buffer. Pattern is a 16-
bit series of 0s and 1s. When OpenGL renders a line, for each pixel it is about to write, it first consults the
next bit in pattern, starting at the low-order bit, If this bit is a 1, the pixel is written, in the current drawing
colour. If the bit is a 0, the pixel is not written. For example, suppose the pattern specified was (to choose
a random example) 0x3E1F. In binary this is: 0011 1110 0001 1111 So, when drawing a line, OpenGL
would draw the first 5 pixels on, the next 4 off, then one on, the next five on, and the next 2 off. For the
next pixel, OpenGL would return to the low-order bit of the pattern, and repeat.
Drawing Triangles
The different values of mode in glBegin() to create triangles are:
GL TRIANGLES: each triplet of points is drawn as a separate triangle. If the number of vertices
is not an exact multiple of 3, the final one or two vertices are ignored.
GL TRIANGLE STRIP: constructs a set of triangles with the vertices v0, v1, v2 then v2, v1, v3
then v2, v3, v4 and so on. The ordering is to ensure that the triangles are all drawn correctly form
part of surface.
GL TRIANGLE FAN: draws a set of triangles with the vertices v0, v1, v2 then v0, v2, v3 then
v0, v3, v4 and so on.
glBegin (GL_TRIANGLES)
glVertex3f (0.0, 6.0, 4.0)
glVertex3f (0.0, 8.0, 0.0)
glVertex3f (8.0, 6.0, 0.0)
glVertex3f (8.0, 3.0, 0.0)
glVertex3f (6.0, 0.0, 5.0)
glVertex3f (2.0, 0.0, 5.0)
glEnd ()
Drawing Quadrilaterals
We can use two values for mode in glBegin() to create quadrilaterals.
GL QUADS: each set of four vertices is drawn as a separate quadrilaterals. If the number of
vertices is not an exact multiple of 4, the final one, two or three vertices are ignored.
GL QUAD STRIP: constructs a set of quadrilaterals with the vertices v0, v1, v3, v2 then v2, v3,
v5, v4 then v4, v5, v7, v6 and so on.
glBegin (GL_QUADS)
/* or GL_QUAD_STRIP */
glVertex3f (0.0, 6.0, 4.0)
glVertex3f (0.0, 8.0, 0.0)
glVertex3f (8.0, 6.0, 0.0)
glVertex3f (8.0, 3.0, 0.0)
glVertex3f (6.0, 0.0, 5.0)
glVertex3f (2.0, 0.0, 5.0)
glEnd ()
Drawing polygons
We draw a polygon using the following mode in glBegin():
GL POLYGON: the vertices define the boundary of a single convex polygon. The polygon
specified must not intersect itself and must be convex. The following code draws a polygon with 5
vertices.
glBegin (GL_POLYGON)
glVertex3f (0.0, 6.0, 0.0)
glVertex3f (0.0, 6.0, 6.0)
glVertex3f (6.0, 6.0, 6.0)
glVertex3f (9.0, 6.0, 2.0)
glVertex3f (9.0, 6.0, 0.0)
glEnd ()
Polygon attributes
Cube
glutWireCube() draws a cube, with edge length size, centred on (0, 0, 0) in object coordinates. Solid
version: glutSolidCube()
Sphere
glutWireSphere() draws a sphere, of radius radius, centred on (0, 0, 0) in object coordinates. slices is the
number of subdivisions around the Z axis (like lines of longitude); stacks is the number of subdivisions
along the Z axis (like lines of latitude). Solid version: glutSolidSphere()
Cone
glutWireCone() draws a cone, with base radius radius, and height height. The cone is oriented along the
Z axis, with the base placed at Z = 0, and the apex at Z = height. slices is the number of subdivisions
around the Z axis; stacks is the number of subdivisions along the Z axis. Solid
Teapot
Once a current matrix has been selected using glMatrixMode(), all subsequent matrix functions (such as
glRotatef(), etc.) affect the current matrix. For example, to load a translation by (x, y, z) into the modelview
matrix, the code would be: glMatrixMode (GL_MODELVIEW);
5. Setting to identity
8. Scaling
glScalef() creates a matrixM which performs a scale by (x, y, z), and then post-multiplies the current
matrix by M as follows:
9. Rotation
glRotatef creates a matrix M which performs a counter-clockwise rotation of angle degrees. The axis about
which the rotation occurs is the vector from the origin (0, 0, 0) to the point (x, y, z), and then post-multiplies
the current matrix by M as follows:
10. Using the matrix stacks
There are two functions which operate on the current matrix stack: glPushMatrix() and
glPopMatrix(). They behave as you might expect:
glPushMatrix() Pushes the current matrix stack down one level. The matrix on the top of the stack is copied
into the next-to-top position, as shown in Figure 8.3. The current matrix stack is determined by the most
recent call to glMatrixMode(). C is not changed. It is an error if
glPushMatrix() is called when the stack is full.
glPopMatrix() pops the current matrix stack, moving each matrix in the stack one position towards the top
of the stack, as shown in Figure 8.4. The current matrix stack is determined by the most recent call to
glMatrixMode(). C becomes the matrix previously at the second-to-top of the stack. It is an error if
glPopMatrix() is called when the stack contains only one matrix.
11. Viewing
LookAt(): The position of the camera in space – sometimes also called the eyepoint – is given by (eyex,
eyey, eyez). (centerx, centery, centerz) specifies a look point for the camera to “look at”, and a good choice
for this would a point of interest in the scene, and often the center of the scene is used. Together, the points
(eyex, eyey, eyez) and (centerx, centery, centerz) define a view
vector. The last set of gluLookAt()’s arguments specify the up vector of the camera. This defines the
camera’s orientation at the eye point. There is no need for the view vector and the up vector to be defined
at right angles to each other (Although if they’re parallel weird views may result). Often the up vector is
set to a fixed direction in the scene, e.g. pointing up the world Y axis. In the general case, OpenGL twists
the camera around the View vector axis until the top of the camera matches the specified up direction as
closely as possible. What gluLookAt() actually does is to create a transformation matrix which encapsulates
all the specified Camera parameters. This is called the “viewing matrix”, or V. gluLookAt() then
postmultiplies The current modelview matrix (C) by V:
12. Orthographic Projection
glOrtho() creates a matrix for an orthographic projection, and post-multiplies the current matrix (which is
normally the projection matrix) by it:
14. Interaction
The basic OpenGL library has no facilities for interaction – it’s only concerned with rendering. This was a
design decision made in the interests of efficiency and portability. The GLUT library provides some very
rudimentary facilities for creating graphical user interfaces (GUIs). Specifically, the glutMainLoop()
function traps events, and allows an application to deal with them in three ways:
Mouse events are triggered when a mouse button is pressed, and also when the mouse changes
position
Keyboard events are triggered when the user hits an ASCII key or a cursor movement/function
key
Menu events are triggered when the application has defined GLUT pop-up menus and assigned
them to mouse buttons.
Keyboard events
For keyboard events, GLUT calls the application callback function registered by glutKeyboardFunc() or
glutSpecialFunc():
glutKeyboardFunc() registers the application function to call when OpenGL detects a key press generating
an ASCII character. This can only occur when the mouse focus is inside the OpenGL window.
Mouse events
glutMouseFunc() registers an application callback function which GLUT will call when the user Presses
a mouse button within the window. The following values are passed to the callback function: