chapter 2

Programming with OpenGL

Objectives


Early History of APIs

IFIPS (1973) formed two committees to come up with a standard graphics API

GKS adopted as IS0 and later ANSI standard (1980s)

Programmers Hierarchical Graphics System (PHIGS)

X Window System

PEX combined X and PHIGS

SGI and GL Silicon Graphics (SGI)


OpenGL

OpenGL Evolution

OpenGL Libraries

Software Organization

OpenGL Architecture

OpenGL Functions

OpenGL State

Lack of Objects

OpenGL function format

The command for specifying vertex coordinates has the following forms :
glVertex{2|3|4}{sifd}[v](TYPE coords);
You must specify 2, 3, or 4 coordinates per vertex. You must specify short, integer, float or double as the type of coordinates. You may directly specify the coordinates or supply an array of coordinates in the v form of the command. Several examples follow:

glVertex2s(2,3);
glVertex3d(0.0,0.0, 3.14159);
glVertex4f(2.3,1.0,-2.2,2.0);
GLdouble dvect[ ] = {5.0,9.0,1992.0};
glVertex3dv(dvect); //vform

OpenGL #defines

OpenGl uses a very simple command syntax. All functions begin with gl and each additional word is capitialized :

glClearColor(0.0,0.0,0.0,0.0);
glPushMatrix();

Constants are in uppercase, beginning with GL_, each word is separated by the _ :

GL_POLYGONS, GL_COLOR_BUFFER_BIT


A Simple Program

Generate a square on a solid background

square.c

#include <GLUT/glut.h>

void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush(); }

int main(int argc, char** argv){
glutInit(&argc, argv);
glutCreateWindow("simple");
glutDisplayFunc(mydisplay);
glutMainLoop(); }

Event Loop

Defaults


Programming with OpenGL Part 2: Complete Programs

Objectives

Program Structure


Square.c revisited

main.c

#include <GLUT/glut.h> //include gl

int main(int argc, char** argv) {

glutInit(&argc,argv); //set window properties
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("simple");
glutDisplayFunc(mydisplay); //display callback
init(); //set OpenGL state
glutMainLoop();//enter event loop}


GLUT functions


init.c


Coordinate Systems


OpenGL Camera

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

All parameters are a measurement of DISTANCE from the camera. Unlike a real camera, objects behind the camera are visible when using an orthographic projection. This can be a little confusing.

The camera is at (0, 0, 0) looking down the -z axis. The far plane is located one unit down the -z axis, therefore the far plane is at -z = 1 or z = -1. The near plane is located negative one unit down the -z axis, therefore the near plane is at -z = -1 or z = 1. We are looking at the far plane and the near plane is behind us.


Orthographic Viewing


Transformations and Viewing


Two- and three-dimensional viewing


OpenGL Primitives

glBegin(GLenum mode);

where mode is the type of primitive to be drawn. The allowable 2D/3D primitives are

  1. GL_POINTS : individual points.
  2. GL_LINES : pairs of vertices interpreted as line segments.
  3. GL_LINE_STRIP : connected line segments.
  4. GL_LINE_LOOP : same as 3, segment between first and last segments.
  5. GL_TRIANGLES : triples of vertices interpreted as triangles.
  6. GL_TRIANGLE_STRIP : linked strip of triangles.
  7. GL_TRIANGLE_FAN : linked fan of triangles.
  8. GL_QUADS : quads. of vertices interpreted as 4-sided polygons.
  9. GL_QUAD_STRIP : linked strip of quadrilaterals.
  10. GL_POLYGON : boundary of a simple convex polygon

glEnd();

Drawing a Trangular fan

glBegin(GL_TRIANGLE_FAN);         
              
glVertex3f(0.1, 0.1,0.0);
glVertex3f(0.6, 0.1,0.0);
glVertex3f(0.8,0.3,0.0);
glVertex3f(0.6,0.6,0.0);
glVertex3f(0.1,0.6,0.0);
glVertex3f(0.0,0.3,0.0);
glEnd();

glFlush(); //draw immediately

Drawing Points

A point can be displayed by specifying the size of the point and then drawing the point(s) as in:

glColor3f(1.0,1.0,1.0); //white points
             
glPointSize(7.0); //pen size
glBegin(GL_POINTS); //specify draw primitive
glVertex3f(-10.0,5.0,0.0); //3D point
glVertex3f(10.0,5.0,0.0); //3D point
glEnd();

glFlush(); //draw immediately

Drawing Lines

A line might be displayed by specifying a line width and then drawing the line(s).

glColor3f(0.0,0.0,1.0);  //blue lines
              
glLineWidth(7.0); //line width
glBegin(GL_LINES); //draw 2 vertical lines
glVertex3f(20.0,20.0,0.0);
glVertex3f(20.0,-20.0,0.0);
glVertex3f(-20.0,-20.0,0.0);
glVertex3f(-20.0,20.0,0.0);
glEnd();

glFlush();


Polygon Issues


Attributes


RGB color


Indexed Color


Color and State

Smooth Color


Viewports


Programming with OpenGL Part 3: Three Dimensions

Objectives

Three-dimensional Applications

Sierpinski Gasket (2D)

Example

The gasket as a fractal

Repeated Subdivision Gasket Program

#include <GLUT/glut.h>
/* a point data type >
typedef GLfloat point2[2];
/* initial triangle */
point2 v[]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};
int n; /* number of recursive steps


void triangle( point2 a, point2 b, point2 c)/* display one triangle */ {
glBegin(GL_TRIANGLES);

glVertex2fv(a);
glVertex2fv(b);
glVertex2fv(c);

glEnd(); }

void divide_triangle(point2 a, point2 b, point2 c, int m) {

/* triangle subdivision using vertex numbers */
point2 v0, v1, v2;
int j;
if(m>0) {
for(j=0; j<2; j++)v0[j]=(a[j]+b[j])/2;
for(j=0; j<2; j++)v1[j]=(a[j]+c[j])/2;
for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;
divide_triangle(a, v0, v1, m-1);
divide_triangle(c, v1, v2, m-1);
divide_triangle(b, v2, v0, m-1); }

else(triangle(a,b,c)); /* draw triangle at end of recursion */ }

void display(void) {

glClear(GL_COLOR_BUFFER_BIT);
divide_triangle(v[0], v[1], v[2], n);
glFlush(); }

void myinit() {

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2.0, 2.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glClearColor (1.0, 1.0, 1.0,1.0)
glColor3f(0.0,0.0,0.0); }

int main(int argc, char **argv) {

n=4;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow(“2D Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop(); }


Moving to 3D

3D Gasket

Example triangle code

void triangle( point a, point b, point c){

glBegin(GL_POLYGON);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glEnd(); }

void divide_triangle(point a, point b, point c, int m) {

point v1, v2, v3;
int j;
if(m>0) {
for(j=0; j<3; j++) v1[j]=(a[j]+b[j])/2;
for(j=0; j<3; j++) v2[j]=(a[j]+c[j])/2;
for(j=0; j<3; j++) v3[j]=(b[j]+c[j])/2;
divide_triangle(a,v1, v2, m-1);
divide_triangle(c, v2, v3, m-1);
divide_triangle(b, v3, v1, m-1); }
else(triangle(a,b,c)); }

void tetrahedron( int m) {

glColor3f(1.0,0.0,0.0);
divide_triangle(v[0], v[1], v[2], m);
glColor3f(0.0,1.0,0.0);
divide_triangle(v[3], v[2], v[1], m);
glColor3f(0.0,0.0,1.0);
divide_triangle(v[0], v[3], v[1], m);
glColor3f(0.0,0.0,0.0);
divide_triangle(v[0], v[2], v[3], m); }

Almost Correct


Hidden-Surface Removal

Using the z-buffer algorithm