2. Intro to OpenGL
Brock University
COSC 3P98 Computer Graphics
Instructor: Brian J. Ross
Intro to OpenGL
-
OpenGL: open architecture graphics library for 2D and 3D graphics
-
grew from Silicon Graphic's GL
-
there is a OpenGL standards committee
-
lots of different implementations; some are commercial, others freeware
-
supported on Linux, Windows, Mac,...
-
documentation:
-
OpenGL Programming Guide (Red Book), and OpenGL Reference
Manual (Blue Book)
-
lots of books available: go to amazon.com
-
Characteristics:
-
immediate-mode graphics: (default) graphics commands execute when
invoked
-
buffered, display list graphics also possible: saves commands and
issues them in a packet
OpenGL platforms
-
1. Linux (J310)
-
2. Mesa OpenGL
-
a freeware "Mesa OpenGL" library exists for the Mac, Windows, Linux,...
-
not supported in labs
-
3. OpenGL for Mac, Windows, ...
-
Drivers usually bundled with OS, or with graphics card.
-
Our labs use MS Visual Studio.NET.
Compiling OpenGL on Linux (with GLUT I/O library)
#include <GL/gl.h>
#include <GL/glut.h> /* or "glut.h" if copied locally */
/* plus any others you need */
cc -float -prototypes -O2 -s -o crisscross crisscross.c -L /usr/X11R6/lib -lc -lglut -lGL
-lGLU -lX11 -lXmu -lXi -lXext -lm
-
fullwarn- extra checking
-
O2- optimizer
-
s - stripped of debug info
-
c - C library
-
-L- directory to search for system libraries (eg. X-windows)
-
glut- glut I/O library (replace "-lglut" with "libglut.a" if copied
locally)
-
GL - OpenGL libary
-
GLU - OpenGL Utility library
-
X11, Xmu, Xext, Xi - X windows libraries
-
m - math
-
Important system directories in unix:
-
/usr/include/ : this contains the ".h" files. For example, if you use
this in your C file:
#include
Then this header file is found here: /usr/include/FreeImage.h
-
If you use this...
#include "FreeImage.h"
then the header is in your local working directory where you are compiling
your source.
-
/usr/lib/ : this folder contains the library files used for linking. For example, in the above compile line, "-lm" means there is a library file here: /usr/lib/m.a
-
Replace "-lfreeimage" with "freeimage.a" if the FreeImage library file is in your working
directory
See this tutorial
for setting up OpenGL and GLUT on MS Visual Studio.
See WWW
for examples, Makefile, ... (as well as many more GLUT library examples)
Simple OpenGL program: green.c
/*
* green.c
* This program draws a green window. (Yawn!)
*/
#include <GL/gl.h>
#include <GL/glut.h>
void green (void) {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(400, 400);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutCreateWindow ("green");
glutDisplayFunc(green);
glClearColor (0.0, 1.0, 0.0, 1.0);
glutMainLoop();
return(0);
}
Green.c
-
global state attribute: a global value set for following actions
-
eg. colour, font, patterns, buffering,...
-
include line: for OpenGL, glut utilties
-
glut library calls: for window opening
-
glutInit: starts up Glut I/O: needed for window output, any I/O,
etc
-
glutInitWindowSize: defines pixel dimensions of window
-
glutInitDisplayMode: defines type of graphics - single buffer, RGB
colour mode
-
glutCreateWindow: creates a window (via X windows) with given name
-
glutDisplayFunc: you give Glut the name of drawing routine whenever
window must be redisplayed
-
glutMainLoop: starts Glut processing; should be called only once
per program
-
OpenGL calls: actual graphics
-
glClearColor: background colour when window 'cleared'
-
glClear: clears whatever attribute given (ie. buffer)
-
glFlush: makes sure all graphics commands have been emptied to terminal
Steps in an OpenGL program
-
Query the availability of graphics resources
-
used for portable code
-
what hardware? (not all graphics features supported by all hardware)
-
eg. size of screen? 8 bit graphics or 24 bit graphics?
-
Initialize graphics library (global attributes, winopen)
-
Call OpenGL routines to do things (body of application program)
-
Terminate
OpenGL command structure
-
OpenGL commands begin with "gl" prefix (closed name space)
-
also glu prefix for OpenGL Utility commands; glut for glut
-
#args specified in command name if variable number of arguments possible
-
arguments are normally absolute, but indirect (array) args possible if
command permits a "v" suffix
-
data type of arguments specified as well
| Suffix |
Data type |
Typical C equiv |
OpenGL type defn |
| b |
8-bit integer |
signed char |
GLbyte |
| s |
16-bit integer |
short |
GLshort |
| i |
32-bit integer |
long |
GLint, GLsizei |
| f |
32-bit float |
float |
GLfloat, GLclampf |
| d |
64-bit float |
double |
Gldouble, GLclampd |
| ub |
8-bit unsigned integer |
unsigned char |
GLubyte, GLboolean |
| us |
16-bit unsigned integer |
unsigned short |
GLushort |
| ui |
32-bit unsigned integer |
unsigned long |
GLuint, GLenum, GLbitfield |
OpenGL: vertices
-
vertex: a 2D (x,y) or 3D (x,y,z) point on a plane/in space, which defines
the endpoint of part of a geometric figure
-
vertices should reside within a mathematical space you define
-
default uses window size values, but you should set your own
-
eg. specifying vertices...
-
glVertex2i (25, 60);
-
glVertex3f(2.4, -.0007, 0.0);
-
glVertex3iv(vert1); /* GL-style vertex */
-
Drawing: form of instructions...
glColor3f(1.0, 0.0, 0.0); <-- Red
glBegin(GL_LINE_LOOP); <-- connected closed-loop lines is object type
glVertex2iv(vert1); <-- each defines an endpoint for part of object
glVertex2iv(vert2); being drawn, def'd in a vector
glVertex2iv(vert3);
glVertex2iv(vert4);
glEnd();

-
immediate mode plotting: drawing within glBegin--glEnd is done ASAP (can
be network delay)
-
glPointSize, glLineWidth: define pixel size of points, lines
OpenGL: geometric primitives
-
glBegin(XXX); ... glEnd();
-
the type of primitive is specified in glBegin
-
Possible primitives...
-
GL_POINTS: point at each vertex
-
GL_LINES: line between each pair of vertices
-
GL_POLYGON: a polygon between vertices
-
GL_TRIANGLES: triangles (preferred for 3D graphics)
-
GL_LINE_STRIP: continuing lines
-
and others
- glEnable(GL_POINT_SMOOTH); // smooth points, lines
OpenGL: coordinate systems
-
screen coordinates: eg 760 by 1024
-
mouse coordinates returned by I/O library routines are these
-
window size: the pixel range that is used for drawing
-
"logical" coordinates: the mathematical coordinate range you are using
-
in your application's model
-
for example, a mathematical function might use a coordinate system
-
-0.3 < X < -0.29, 50000 < Y < 50000000
-
it is convenient for programs to use the model's coordinate system and
let OpenGL convert it into the window's pixel coordinates (which in turn
are automatically converted to the screen coordinates by OpenGL/X)
-
use:
-
glutInitWindowSize - to indicate size of window (ie. plotting area
size)
-
glOrtho(GLdouble left, right, bottom, top, near, far);
-
needed for 2D and 3D graphics; 2D case -- make sure near and far have a
non-zero dimension
-
OpenGL requires you use glOrtho, even after defining window size
-
gluOrtho2D(left, right, bottom, top)
-
to specify the logical 2D coordinate system which is to be mapped into
the window positions indicated
-
glutInitWindowPosition(int x, y);
- put top-left corner of window at this location on screen
| glutInitWindowSize(400, 400);
gluOrtho2D(0, 500, 100, 200); |
 |
OpenGL color
-
color maps: used to map color information to CRT hardware
-
TV screens have 3 "guns": red, green, blue
-
during horizontal scans, each gun fires at either red, green, or blue
-
phosphors on screen (look closely at a monitor screen)
-
combinations of different intensities of these phosphors create different
colours when viewed from afar
OpenGL: RGB color scheme
-
2 major color modes: RGB mode, color map mode
-
RGB: "red green blue" standard of colour
-
3 values for R, G, B yield different colours
-
equal values for each give neutral shades (000=black, 111=white, else grey)
-
RGB mode and color map mode both use RGB colour definitions
-
on O2, use "cedit" program to play with RGB colours
OpenGL: color map mode
-
bitplane: the amount of memory used per pixel
-
contains color information (plus other stuff on some machines)
-
different graphics cards use different size bitplanes: determines the range of colors you see on CRT
-
colormap mode: bitplane refers to entry in a table that has RGB value
-
easier to change lots of pixel values in one shot: just change table value
-
also, 8 bits per R,G,B then available
-
(RGB mode: must change each pixel separately)
-
color map table: 8 (or 12 bit) index = 256 (or 4096 ) colours to store
and see at one time
-
hardware itself determines the number of these you can see at once
-
table entries use full 24 bits for R, G, B information
-
must use glut to set up colour map mode in your windowing system
(X, Windows,...)
-
glutInitDisplayMode (GLUT_SINGLE | GLUT_INDEX);
-
glutSetColor(4, 0.5, 0.5, 1.0);
-
sets table entry 4 to RGB color (.5, .5, 1)
-
glClearIndex(FLOAT index);
-
index is a value containing colour for screen clears (like RGB mode's glClearColor)
-
glIndexi(TYPE index);
-
index is a value indexing color map (see manual)
-
eg.
glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX);
glutSetColor(1, 0.0, 0.0, 0.0);
glClearIndex(1.0);
glClear(GL_COLOR_BUFFER_BIT);
glutSetColor(10, 1.0, 0.0, 0.0);
glIndexi(10);
glBegin(GL_POLYGON);
glVertex2i(50, 50);
glVertex2i(100, 100);
glVertex2i(0, 0);
glEnd(); /* a red triangle was drawn */
OpenGL: RGB mode
-
In RGB mode, each bitplain specifies RGB data directly
-
24 bit: full 8 bits per R, G, B
-
8 bit (older): 3 bits for R and G, 2 bits for B
-
RGB mode is required for most 3D graphics with shading
-
hence, in RGB mode, 24-bit O2 can display all 16 million colours on screen
at once
-
But what about 8 bit PC's with older graphics cards? 2 bits for blue???
-
solution: "dithering" : technique that uses pixel patterns to simulate
different colours
-
if you look closely at a dithered section of screen, you can see patterns
of coloured pixels; move away, and a "colour" appears
OpenGL: RGB mode
-
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA);
-
starts RGB mode (default is color map mode)
-
glClearColor(1.0, 1.0, 1.0, 1.0)
-
specifies R, G, B, alpha (transparency) of default window colour
-
keep alpha=1 (no transparency)
-
glClear(GL_COLOR_BUFFER_BIT)
-
clears window
-
can clear other things (more later)
-
glColor3f(1.0, 0.0, 0.0)
-
says: full red, no blue, no green
-
Important bug-avoiding point: integer variation (glColor3i)
uses range of integer value in 'int' to specify colour (eg. -32768...32767)
; use glColor3ub for range 0...255.
-
alpha variation possible (glColour4f)
#include <GL/gl.h>
#include <GL/glut.h>
void crisscross(void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2i(50, 50);
glVertex2i(350, 350);
glVertex2i(50, 350);
glVertex2i(350, 50);
glEnd();
glFlush();
}
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(400,400);
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("Glut Crisscross");
glutDisplayFunc(crisscross);
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(1.0, 0.0, 0.0);
glOrtho(0.0, 400.0, 0.0, 400.0, 0.0, 1.0);
glutMainLoop();
}
Here's a variation : square.c
and its output.
I/O and OpenGL
-
OpenGL does not support I/O (windowing, mouse, keyboard,...)
-
a system-dependency which OpenGL avoids; after all, there are many systems
out there (X-windows, Windows, Macintosh,...)
-
however, can't do graphics without I/O!
-
Some freeware libraries that perform I/O
-
1. GLUT
-
comprehensive I/O library, more suitable to real applications
-
simple lecture examples here
if you want to use it (and more complex examples are here)
-
2. aux
-
bare essentials for windowing, mouse and keyboard I/O, double buffering
(animation)
-
described in OpenGL Programming Guide (1e)
-
Very buggy - avoid! (nobody supports it anyway)
OpenGL I/O using Glut
-
documentation: Look here for GLUT online manual.
-
See above for basic use for Window I/O.
-
callback loop: an interrupt-driven loop defined within Glut, which
handles all possible events from keyboard, mouse, X-windows,...
-
essentially defines cases of a case-statement within a large while-loop
-
Callback registration: programmer specifies the procedures glut should
execute when different I/O actions are seen
-
glutDisplayFunc(void (*func)(void))
-
assigns function to call when current window must be redisplayed
-
glutPostRedisplay (void)
-
Marks active window as needing redisplay by glutDisplayFunc.
-
glutReshapeFunc(void (*func) (int width, int height))
-
function to call when current window is reshaped; the parameters are the
new size of reshaped window
-
glutIdleFunc(void (*func) (void))
-
function to call when no activity occurring (eg. during animation)
-
glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))
-
sets key processing routine
-
x and y are mouse coordinates when the key 'key' was pressed
-
see glutGetModifiers for state of modifier keys (eg. ctrl,...)
-
glutMouseFunc(void (*func)(int button, int state, int x, int y))
-
mouse function callback
-
button: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
-
state: GLUT_UP, GLUT_DOWN
-
x, y: mouse coordinates
-
glutMotionFunc (void (*func)(int x, int y))
-
function to call when mouse is moving in window, when a button is pressed
-
glutPassiveMotionFunc(void (*func)(int x, int y))
-
function to call when mouse is moving in window, when no buttons are pressed
-
glutMainLoop(void)
-
starts GLUT processing; should be called only once in program
OpenGL programs with glut I/O:
Style
- Notice the difficulty in passing data to routines when the Glut library is used.
- For example, the function given to glutDisplayFunc cannot be accessed directly by other code: how do you pass data to it?
- The reason is that Glut processing is geared towards
object-oriented programs.
- Properly, you should define C++ objects with which to converse with.
- In C, you will need global variables.
- Global variables are nasty: can result in horrendous programs.
- Simple solution: put all your global variables in a "global structure".
- Then always access these variables using the global structure name as a prefix. This solves any ambiguity problems!
- Example: rotate2.c
- You should not call any OpenGL rendering calls outside of the Glut
callback routines. For example, don't try clearing the screen in your main
program - that should be done in a callback. If you need the window cleared
initially, the glutDisplayFunc callback routine should do that.
It might need a flag within itself to keep track of when it should clear
the screen or not.
- Related to this, make use of glutPostRedisplay. It can be used to mark a window as needing redisplay. Then the appropriate callback (glutDisplayFun?) can redraw it automatically.
C programming and debugging
- C advantages:
- Fast.
- Good optimizing compilers.
- Low-level: can do almost anything with hardware.
- Portable.
- C disadvantages:
- Low-level: freedom to do anything means anything can happen.
- Minimal memory management: not like Java!
- Cryptic compiler messages.
- Even more cryptic run-time behaviour.
- Eg. "Bus error." or "Segmentation fault. Core dumped."
- Common OpenGL run-time behaviors:
- Window appears and disappears right away.
- Window appears, full of mess (eg. background desktop images)
- Program says "Bus error" or...
- Some debugging advice:
- Carefully design your system. Don't program at the terminal!
- Incremental design: use small functional components (not huge functions).
- Incremental implementation: Implement modules. Test them separately.
Put them together after tested.
- Use "lint" for additional compiler messages.
- Use fprintf statements to list program progress, variable values.
- Use "dbx" for run-time debugging.
- Must first compile your program with "-g" flag (instead of "-O2").
- use: dbx program
- Most useful: run your program within dbx, and it will trap memory violations.
- online help lists lots of commands.
- Dbx is NOT an algorithm design debugger!
Comments
-
OpenGL advantages:
-
device independent
-
Fast! If hardware acceleration exists, then high quality graphics possible
in realtime
-
2D and 3D (3D will be extension of 2D shapes, but in 3D coordinate space)
-
sophisticated features: shadows, fog, textures, lighting effects (later
in course)
-
popular standard: OpenGL applications may begin to appear for PC's
-
drawing primitives covered thus far have limitations:
-
OpenGL primitives looked at do not retain the geometric shapes drawn: they
simply writes over pixels in its raster display
-
If you want to delete a line, rescale a square, or do other re-editing,
the application program has to send additional commands to do it;
-
akin to using MacPaint; compare with MacDraw, in which you can grab objects
(lines, squares, .,..) rescale them, and move them about screen
-
the openGL application should retain model information
-
Some graphics libraries will retain data structures that save the geometric
shapes:
-
eg. VRML
- But also see OpenGL's display lists!
-
glut library:
-
comprehensive
-
Windows-based systems will permit other I/O to be used
References:
Back
to COSC 3P98 index
COSC 3P98 Computer Graphics
Brock University
Dept of Computer Science
Copyright © 2009 Brian J.
Ross (Except noted figures).
http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/OpenGL/
Last updated: September 15, 2009