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
-
Linux (J310)
-
OpenGL for Windows, OS-X
-
Drivers usually bundled with Mac OS X, or with graphics card.
-
Our labs use MS Visual Studio.NET.
-
OpenGL ES: OpenGL for tablets (iOS, Android)
-
Mesa OpenGL
-
free implementation of OpenGL for the Mac, Windows, Linux,...
- software emulation as well as hardware accelerated
- not supported in labs
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 */
-
compiling (old version of Linux)
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)
#include <GL/gl.h>
#include <GL/glut.h>
void crisscross(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
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);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 399.0, 0.0, 399.0);
glutMainLoop();
}
Here's a variation : square.c
and its output.
crisscross.c: pulling it apart...
-
global state attribute: a global value set for following actions
-
eg. colour, font, patterns, buffering,...
-
include line: for OpenGL, glut utilties
- glut library calls ("glut..."): for window definition, talking to OS
- 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 (gl, glu): actual graphics rendering
- glClearColor: background colour when window 'cleared'
- glMatrixMode: (more later)
- luOrtho2D: assigns coordinate system to window
- glClear: clears whatever attribute given (ie. buffer)
- glColor3f: Defines RGB colour for next rendering command
- glBegin, glEnd: Starts rendering an object
- GL_LINES: every pair of vertices defines a line to draw
- glVertex2i: Defines a 2D vertex (integer values)
- glFlush: makes sure all graphics commands have been emptied to terminal
- Basic flow of control...
- 1) main:
- Sets up window (size, type, coordinate system).
- Sets up drawing callback (via glutDisplayFunc).
- Starts graphics processing (glutMainLoop).
- 2) crisscross:
- Clears the window (white).
- Draws a red X.
- More details below.
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?
-
eg. Mouse? Rollerball? Joystick?...
-
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
-
See these Header Files
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 OS's windowing system)
-
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
-
glViewport(int x, y, w, h);
- marks area of size w by h for graphics drawing, where
lower-left corner set to x,y
-
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 (0=black, 255=white, else grey)
-
RGB mode and color map mode both use RGB colour definitions
-
Many free RGB editors available online.
OpenGL: color map mode
-
bitplane: the amount of memory used per pixel
-
contains color information (plus other stuff on some machines)
-
Graphics cards determine the range of colors you see on CRT. Almost all now use 24-bits RGB.
- Old SGI workstations in our labs had 8-bits RGB!
-
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)
(above image copyright of original authors)
-
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.
main...
glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX);
glutSetColor(1, 0.0, 0.0, 0.0);
glClearIndex(1.0);
User callback...
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 graphics card can display all 16 million colours on screen
at once
-
But what about smaller devices (eg. hand-held game consoles) with cheaper graphics hardware?
(eg. 2 bits for blue???)
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).
- This is probably not convenient for you to use!
- Instead, use glColor3ub for range 0...255.
or glColor3f for float range 0.0... 1.0
-
alpha variation possible (glColour4f)
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 libraries that perform I/O
-
1. GLUT
- comprehensive I/O library
- good teaching environment
- Most OpenGL text books use it. We will use it too.
-
simple lecture examples here
if you want to use it (and more complex examples are here)
-
2. Direct-X (windows): Comprehensive, but complicated!
-
3. Mac OS X, iOS, Android, Linux (X11), etc.: See your OS programming documentation!
OpenGL I/O using Glut
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 (glutDisplayFunc?) 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."
- The C Puzzle Book by Alan Feuer
- 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.
- (Linux)Use "lint" for additional compiler messages.
- Use fprintf statements to list program progress, variable values.
- (Linux) Use "gdb" for run-time debugging. (gdb tutorial).
- Must first compile (gcc) your program with "-g" flag (instead of "-O2").
- Most useful: run your program within gdb, and it will trap memory violations.
- online help lists lots of commands.
- Debuggers like gdb or the one in Visual Studio are NOT algorithm design debuggers!
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)
-
drawing primitives covered thus far have limitations:
-
The OpenGL primitives we have shown do not retain the geometric shapes drawn:
they simply write over pixels in image buffer.
-
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 Photoshop without layers; compare with Illustrator or CorelDraw, in which you can
grab objects (lines, squares, .,..) rescale them, and move them about screen
-
the openGL application should retain model information
-
OpenGL also allows basic object definition using Display lists.
Then you supply objects to OpenGL once only. You tell OpenGL to redraw them as required.
This uses retained mode graphics (vs immediate mode).
-
Other graphics libraries will retain data structures that save the geometric
shapes, as well as complex hierarchies:
glut library:
-
comprehensive, programmer friendly
-
Windows-based systems will permit other I/O to be used
References:
Back
to COSC 3P98.
COSC 3P98 Computer Graphics
Brock University
Dept of Computer Science
Copyright © 2023 Brian J. Ross
(Except noted figures).
http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/OpenGL/
Last updated: January 23, 2023