CISC181: Introduction to OpenGL Course web page: April 15, 2010

Preview:

Citation preview

CISC181:Introduction to OpenGL

Course web page:http://nameless.cis.udel.edu/class_wiki/index.php/

CISC181_S2010

April 15, 2010

Outline

• OpenGL & GLUT basics– Setting up a program – 2-D drawing– 2-D transformations– Applying textures to shapes

OpenGL – What is It?

• GL (Graphics Library): Library of 2-D, 3-D drawing primitives and operations– API for 3-D hardware acceleration

• GLU (GL Utilities): Miscellaneous functions dealing with camera set-up and higher-level shape descriptions

• GLUT (GL Utility Toolkit): Window-system independent toolkit with numerous utility functions, mostly dealing with user interface

• Course web page has links to online function references (functions from each library start with library prefix—i.e., gl*, glu*, glut*)

Event-driven GLUT program structure

1. Configure and open window2. Initialize OpenGL state, program

variables3. Register callback functions

• Display (where rendering occurs)• Resize• User input: keyboard, mouse clicks,

motion, etc. (on Thursday)

4. Enter event processing loopPortions of some slides adapted from “An Interactive Introduction to OpenGL Programming”,D. Shreiner, E. Angel, V. Shreiner, SIGGRAPH 2001 course

Simple OpenGL program (no animation)

#include <stdio.h>#include <GL/glut.h>

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

glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(100, 100);glutCreateWindow(“hello”);init(); // set OpenGL states, variables

glutDisplayFunc(display); // register callback routines

glutMainLoop(); // enter event-driven loop}

adapted from E. Angel

Simple OpenGL program (no animation)

#include <stdio.h>#include <GL/glut.h>

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

glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(100, 100);glutCreateWindow(“hello”);init(); // set OpenGL states, variables

glutDisplayFunc(display); // register callback routines

glutMainLoop(); // enter event-driven loop}

adapted from E. Angel

Initialization

• glutInit: Pass command-line flags on to GLUT• glutInitDisplayMode: OR together bit masks to set modes

on pixel type (indexed vs. true color), buffering, etc.• glutInitWindowSize, glutCreateWindow: Set drawing

window attributes, then make it• init(): Set OpenGL state, program variables

– Use GL types/typedefs GLfloat, GLint, GL_TRUE, GL_FALSE, etc. for cross-platform compatibility

void init() {glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluOrtho2D(0, right, 0, top);

}sets “units” of subsequent draw commands

OpenGL screen coordinates

• Bottom left corner is origin

• gluOrtho2D() sets the units of the screen coordinate system

•gluOrtho2D(0, w, 0, h) means the coordinates are in units of pixels

•gluOrtho2D(0, 1, 0, 1) means the coordinates are in units of “fractions of window size” (regardless of actual window size)

from Hill

Example: Specifying the center of a square

(320, 240)

gluOrtho2D(0, 640, 0, 480)

Example: Specifying the center of a square

(0.5, 0.5)

1

1

gluOrtho2D(0, 1, 0, 1)

Simple OpenGL program

#include <stdio.h>#include <GL/glut.h>

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

glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(100, 100);glutCreateWindow(“hello”);init(); // set OpenGL states, variables

glutDisplayFunc(display); // register callback routines

glutMainLoop(); // enter event-driven loop}

adapted from E. Angel

Rendering Steps (no animation)

• In function registered with glutDisplayFunc():

1. Clear window: glClear(GL_COLOR_BUFFER_BIT)2. Draw shapes

• Set colors, patterns, point/line sizes• Specify type of geometric primitive(s) and list vertices

3. Make offscreen draw buffer the display buffer with glutSwapBuffers()

Callback registration functions

• Render glutDisplayFunc()• Key down in window glutKeyboardFunc()• Key up in window glutKeyboardUpFunc()• Button press/release glutMouseFunc() • Mouse motion glutMotionFunc()

(with button down)• Window reshaping glutResizeFunc() • Nothing happening glutIdleFunc()

• Passive motion, other input devices, etc.: Look these up on GLUT reference pages on web

Example: Keyboard callback

• What key has been pressed and where the cursor is:

glutKeyboardFunc(keyboard);

void keyboard(unsigned char key, int x, int y){ switch(key) { case ‘q’ : case ‘Q’ : exit(1); break; case ‘r’ : case ‘R’ : rotate_mode = GL_TRUE; break; }}

Example: Mouse button callback

• Which mouse button, where, and has it been pressed or released:

glutMouseFunc(mouse);

void mouse(int button, int state, int x, int y){ if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { left_down = TRUE; mouse_x = x; mouse_y = y; } else if (state == GLUT_UP) left_down = FALSE; }}

Example: Idle callback

• Use for animation and continuous update

glutIdleFunc(idle);

void idle(void){// change position variables, etc.

t += dt;

// call glutDisplayFunc() callback ASAP glutPostRedisplay();}

OpenGL Geometric Primitives

Specifying Geometric Primitives

• Primitives are specified usingglBegin(primType);

...

glEnd();

– primType determines how vertices are combinedGLfloat red, green, blue;

GLfloat x, y;

glBegin(primType);for (i = 0; i < nVerts; i++) { glColor3f(red, green, blue); glVertex2f(x, y); ... // change coord. values}glEnd();

OpenGL Command Formats

glVertex3fv( v )

Number ofcomponents

2 - (x,y) 3 - (x,y,z), (r,g,b)4 - (x,y,z,w), (r,g,b,a)

Data Typeb - byteub - unsigned bytes - shortus - unsigned shorti - intui - unsigned intf - floatd - double

Vector

omit “v” forscalar form–

e.g.,glVertex2f(x, y)glColor3f(r, g, b)

glColor3fv( v )

Drawing: Miscellaneous

• glColor(): Range is [0, 1] for each color channel for glColor3f(); [0, 255] for glColor3ub()

• Can set persistent “pen size” outside of glBegin()/ glEnd()– glPointSize(GLfloat size)– glLineWidth(GLfloat width)

• glRect(x1, y1, x2, y2) specifying opposite corners of rectangle is equivalent to GL_POLYGON with four vertices listed (i.e., filled)

Why We Need Transformations

• What can we do so far?– Draw 2-D shapes by exhaustively

listing their vertices

• Something missing:– The ability to specify the intrinsic

shape of an object independently of its location, scale, or orientation

Example: Shape vs. Viewing Issues

Example: Shape vs. Viewing Issues

Example: Shape vs. Viewing Issues

Example: Shape vs. Viewing Issues

Transformations for modeling, viewing

1. Make object model in canonical coordinate frame

2. Transform object with appropriate translation, scaling, rotation as needed

• Also useful for building complex objects from simpler parts

from Hill

2-D Transformations: OpenGL

• 2-D transformation functions*

– glTranslatef(x, y, 0)– glScalef(sx, sy, 0)

– Negative scaling is reflection– glRotatef(theta, 0, 0, 1) (angle in

degrees; direction is counterclockwise)• Notes

– Set glMatrixMode(GL_MODELVIEW) first– Transformations should be specified before

drawing commands to be affected– Multiple transformations are applied in

reverse order

*Technically, these are 3-D

Example: 2-D Translation in OpenGL

Two ways to do this:

glRectf(.25,.25,.75,.75); glTranslatef(.5,.5,0);glRectf(-.25,-.25,.25,.25);

Assuming gluOrtho2D(0, 1, 0, 1)

Example: Order of transformations

glTranslatef(.5,.5,0);glRotatef(45,0,0,1);glRectf(-.25,-.25,.25,.25);

glRotatef(45,0,0,1);glTranslatef(.5,.5,0);glRectf(-.25,-.25,.25,.25);

Remember: Order of application is backwards from drawing commands

Why does the order of transformations seem backwards?

• Because transformations are implemented with matrix multiplications

• Thus the rules of linear algebra dictate that T x R x p means “rotate p, then translate it”

• Can also think of it functionally: T(R(p))

Limiting “Scope” of Transformations

• Transformations are ordinarily applied to all subsequent draw commands

• To limit effects, use push/pop functions:glPushMatrix();

// transform

// draw affected by transform

glPopMatrix();

// draw unaffected by transform

Example: Pushing, popping transformations

glPushMatrix();glTranslatef(.5,.5,0);glRotatef(45,0,0,1);glRectf(-.25,-.25,.25,.25);glPopMatrix();

glPushMatrix();// draw axis linesglPopMatrix();

What is Texture Mapping?

• Spatially-varying modification of surface appearance at the pixel level

• Characteristics– Color– Shininess– Transparency– Bumpiness – Etc.

• “Sprite” when on polygon with no 3-D

from Hill

Texture mapping applications: Billboards

from Akenine-Moller & Haines

Also called ”impostors”: Image aligned polygons in 3-Dfrom www.massal.net/projects

OpenGL texturing steps (Red book)

1. Create a texture object and specify a texture for that object

2. Indicate how the texture is to be applied to each pixel

3. Enable texture mapping with glEnable(GL_TEXTURE_2D)

4. Draw the scene, supplying both texture and geometric coordinates

5. OpenGL does many things with globals and side effects, so it can be confusing!

Create Texture Object

• From where?– Create programmatically (aka “procedurally” --

see Red Book Chap. 9 checker.c)– Load image from file (e.g., load_ppm() in Sprite.cpp)

• Name it– // Get unused “names” – not mandatory

glGenTextures(GLsizei n, GLuint *textures)– // Create texture object w/ default params (or switch to existing

one) glBindTexture(GLenum target, GLuint texture)

• // Store data in bound texture object (no ref because it’s global)glTexImage2D( GLenum target, GLint level,

GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)

Rasterization: Texture application modes

• decal: Overwrite object pixel with texel

• modulate: Combine object pixel with texel via multiplication– Need this for multitexturing (i.e.,

lightmaps)

courtesy of Microsoft

Texture mapping applications: Lightmaps

courtesy of K. Miller

+ =

OpenGL: Texture application modes

• glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param), where param is one of:– GL_REPLACE: Just overwrite surface pixel– GL_DECAL: Use alpha values of surface pixel

and texel to blend in standard way– GL_MODULATE: Multiply surface pixel and

texel colors– GL_BLEND: Blend surface and texel colors

with GL_TEXTURE_ENV_COLOR (see glTexEnv() man page for details)

Alpha Channel

• Remember glColor4f(r,g,b,a)? • a is called the alpha channel and

is used to specify transparency when blending textures

• Used for overlapping sprites in Game! code– load_ppm() sets full transparency

when image pixel color is a particular color, full opacity otherwise

OpenGL: Enabling and Drawing

• To draw textured shape, texturing must first be enabled: glEnable(GL_TEXTURE_2D)

• Load current texture image with glTexImage2D()– Width, height must be powers of 2 (plus 2 if border is

used)– Only one texture current; faster to change textures by

preloading all and switching with glBindTexture() rather than reloading each time (this is what Sprite.cpp does)

• Assign texture coordinates (s, t) to vertices with glTexCoord()

– Similar to glColor() command—sets a property for subsequent vertices that holds until it is changed

Robins’ texture tutor

Recommended