Programming with OpenGL and GLUT

trexpeeverΛογισμικό & κατασκευή λογ/κού

13 Δεκ 2013 (πριν από 3 χρόνια και 7 μήνες)

71 εμφανίσεις

Programming

with OpenGL and GLUT

Glenn G. Chappell

CHAPPELLG@member.ams.org

U. of Alaska Fairbanks


CS 381 Lecture Notes

Friday, September 12, 2003

12 Sep 2003

CS 381

2

Review:

The Design of OpenGL


Recall:


The overall API design.


What ideas guided the design of the API?


Naming conventions


How are names of functions, constants,
and types are put together?


Types


OpenGL defines its own simple types.


Why?


What type
-
related pitfalls should you watch out
for?

12 Sep 2003

CS 381

3

Review:

The Design of OpenGL


Attributes & Primitives


OpenGL functions as a
state machine
.


There are three kinds of functions:


Those that set state.


Those that return state.


Those that draw.


Drawing is done via
primitives
.


States are used to set
attributes

of those
primitives.

12 Sep 2003

CS 381

4

Review:

OpenGL Primitives


The ten
glBegin
-
style OpenGL Primitives


Points (1 primitive)


GL_POINTS


Polylines (3 primitives)


GL_LINES


GL_LINE_STRIP


GL_LINE_LOOP


Filled Polygons (6 primitives)


Triangles


GL_TRIANGLES


GL_TRIANGLE_STRIP


GL_TRIANGLE_FAN


Quadrilaterals


GL_QUADS


GL_QUAD_STRIP


General Polygons


GL_POLYGON


Know

the ten primitives!
Know

the associated vertex orderings!

12 Sep 2003

CS 381

5

Introduction to GLUT:

What is GLUT?


GLUT = OpenGL Utility Toolkit


Not part of OpenGL.


By Mark J. Kilgard, formerly of SGI, currently at NVIDIA.


“GLUT is designed for constructing small to medium sized OpenGL
programs.”


Features


Simplifies some OpenGL operations.


OS
-
independent interface for windows, pop
-
up menus, mouse,
keyboard, text fonts.


Optional flow
-
of
-
control handling for event
-
driven programming.


Utility functions for drawing shapes: sphere, cube, torus, etc.


C/C++ Header:
<GL/glut.h>
.


This includes
gl.h

and
glu.h

for you, as well as
windows.h

if it is
needed.


Note: The handling of
windows.h

is sometimes incorrect under Cygwin.
You might need to
#include

it yourself if you use Cygwin.

12 Sep 2003

CS 381

6

Introduction to GLUT:

Thoughts on GLUT


I do not consider GLUT to be suitable for developing
professional
-
quality, production code.


We use it because:


It allows for OS
-
independent GUI programming.


It allows for short, easy
-
to
-
write programs that use graphics
in interesting ways.


It provides a relatively painless introduction to event
-
driven
programming.


So, as we cover event
-
driven programming:


Do
not

think, “Future employers will be happy that I know
GLUT.”


Instead, consider what general ideas about event
-
driven
programming are illustrated by the specific commands and
techniques we cover.

12 Sep 2003

CS 381

7

Introduction to GLUT:

Writing GLUT Programs


Start with an already written program.


Use the web or your own previous work.


Give credit where credit is due!


GLUT handles overall flow of control.


You write functions to …


Initialize OpenGL states and your own variables.


Draw things.


Handle
events

(mouse clicks, window changes,
keypresses, etc.).


Do something when nothing else happens.


These functions are called by GLUT, not you.

12 Sep 2003

CS 381

8

Introduction to GLUT:

An Example GLUT Program


We will now look at
intro2d.cpp
, a
simple OpenGL/GLUT program.


This program does 2
-
D graphics.


3
-
D CG is a bit trickier; I
suggest

(but do
not require) that you stick with 2
-
D for
assignment 2.


Source code is on the web page.


You can use it to base your own programs
on, if proper credit is given.

12 Sep 2003

CS 381

9

intro2d.cpp
:

Overview


5 functions:
main
,
display
,
idle
,
keyboard
,
init


Function
main


Does initialization & window creation.


Tells GLUT about
display
,
idle
,
keyboard

functions.


Turns control over to GLUT.


Function
init


Called by
main

to initialize GL states, print instructions.


Function
display


Called by GLUT when something needs to be drawn.


Updates the contents of the window.


Function
idle


Called by GLUT when nothing else is happening.


In this program, the idle function only does error checking.


Function
keyboard


Called by GLUT when a key is pressed.


Only handles ASCII keypresses. Use a GLUT “special” function for
other keys.

12 Sep 2003

CS 381

10

intro2d.cpp
:

Beginning

// intro2d.cpp

// by Glenn G. Chappell

// September 2003

//

// For CS 381

// Introductory 2
-
D OpenGL/GLUT program



Put comments like this on all programs for this class and

every other program you write for the rest of your life
.


#include <GL/glut.h> // GLUT stuff,


includes OpenGL headers as well



Put this line at the beginning of all GLUT programs.


Again, the OpenGL headers are included by
glut.h
.

12 Sep 2003

CS 381

11

intro2d.cpp
:

Function
main

[1/4]

int main(int argc, char ** argv)

{


// Initialize OpenGL/GLUT


glutInit(&argc, argv);



Above is always the same (
argc
,
argv

come from Unix command
-
line).



glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);



Main GLUT display configuration call


One parameter: multiple options bitwise
-
or’ed together.


GLUT_SINGLE

means 1
color

buffer (stores the color of a pixel).


GLUT_RGB

means store actual color (no color look
-
up table [LUT]).


OpenGL Buffers


All looks like the
viewport

(portion of window where drawing occurs) in terms
of size, but hold different kinds of data.


Color buffers

hold color. Essentially, color buffer = frame buffer.


Can allocate other buffers, e.g.,
GLUT_DEPTH

for a
depth buffer
.

12 Sep 2003

CS 381

12

intro2d.cpp
:

Function
main

[2/4]


// Make a window


glutInitWindowSize(startwinsize, startwinsize);


glutInitWindowPosition(50, 50);


glutCreateWindow("CS 381
-

Introductory 2
-
D Program");



Specify window size (x,y), position (x,y), and title.


OS
may

ignore these and put window wherever it feels like.


Function
glutCreateWindow

also creates an “OpenGL context”.


An
OpenGL context

is a copy of all the OpenGL states related to a
particular output channel (generally a window).


So, don’t set any OpenGL states until after doing
glutCreateWindow
.


You can have multiple contexts. Changing a state (e.g., drawing
color) in one context does not affect the others.

12 Sep 2003

CS 381

13

intro2d.cpp
:

Function
main

[3/4]


// Initialize GL states & register callbacks


init();


glutDisplayFunc(display);


glutIdleFunc(idle);


glutKeyboardFunc(keyboard);



Tell GLUT what function to call to draw window contents (display), what
to call when nothing is happening (idle), and what to call when an ASCII
keypress happens (keyboard).


display
,
idle
,
keyboard

are
callbacks
; need to be
registered

with
GLUT.


Other callbacks can be registered using functions like


glutMouseFunc

(for mouse events)


glutReshapeFunc

(for when the user resizes the window)


and others …


These functions only
register

the callbacks; they do not
call

them.

12 Sep 2003

CS 381

14

intro2d.cpp
:

Function
main

[4/4]


// Do something


glutMainLoop();



return 0;

}



Very little has actually happened so far; we have merely done
initialization.


But now we turn control over to GLUT, callbacks get called, and
the program really starts running.


GLUT handles high
-
level flow of control from now on; when
something needs to be done, GLUT calls the appropriate
callback.



return 0;
” is just to keep the compiler happy. Since
glutMainLoop

never returns, this line is never executed.

12 Sep 2003

CS 381

15

intro2d.cpp
:

Function
init

[1/2]

void init()

{


glClearColor(1.0, 1.0, 1.0, 0.0);



Here we set various GL
states
.


The first state to set is the clear color.


This is the color to set all pixels to when the viewport is
cleared. Think of it as the background color.


Set to white: 100% red, 100% green, 100% blue.


4
th

parameter is
alpha
.


Alpha is used for many things; most common use is
transparency
.


Alpha not used in this program, but it is a required
parameter.

12 Sep 2003

CS 381

16

intro2d.cpp
:

Function
init

[2/2]


glMatrixMode(GL_PROJECTION);


glLoadIdentity();


gluOrtho2D(0.0, 1.0, 0.0, 1.0);


glMatrixMode(GL_MODELVIEW); // Always go back to


model/view mode



In OpenGL, drawing data is sent through a pipeline, in which
transformations are applied to vertex coordinates. These
transformations are stored as 4
×
4 matrices.


Here, we set up the matrix to do the
projection

onto the screen.


What is important to know now is that the 4 parameters of
gluOrtho2D

set up a coordinate system for the window:


x
-
coordinate of
left

side


x
-
coordinate of
right

side


y
-
coordinate of
bottom


y
-
coordinate of
top

12 Sep 2003

CS 381

17

intro2d.cpp
:

Function
display

[1/5]

void display()

{


glClear(GL_COLOR_BUFFER_BIT);



The first thing to do when displaying is to clear the buffer.


glClear

sets every pixel in the color buffer to the color specified
with
glClearColor
.


Can clear other buffers (if they were allocated by the
glutInitDisplayMode

call).

12 Sep 2003

CS 381

18

intro2d.cpp
:

Function
display

[2/5]


glColor3d(0.9, 0.1, 0.1);



Sets the
drawing color
.


This is the color of upcoming vertices.


Drawing color is another GL state.


glColor

can take several forms with different types of
parameters.


What does “
3d
” mean?

12 Sep 2003

CS 381

19

intro2d.cpp
:

Function
display

[3/5]


glBegin(GL_QUADS);


glVertex2d(0.1, 0.1);


glVertex2d(0.9, 0.1);


glVertex2d(0.9, 0.9);


glVertex2d(0.1, 0.9);


glEnd();



Specifying the coordinates of actual things to draw is done between
glBegin

and
glEnd
.


glVertex

call gives coordinates;
GL_QUADS

tells how to use them.


Coordinate system was specified by the
glOrtho2D

call.


Recall:
GL_QUADS

is a GL
primitive
; it means draw a series of quadrilaterals.


Indentation between
glBegin

and
glEnd

is helpful.


It is not required, of course.


Only a very limited set of GL commands are allowed between
glBegin

and
glEnd
.

12 Sep 2003

CS 381

20

intro2d.cpp
:

Function
display

[4/5]


glFlush();

}



glFlush

says “start drawing now”.


Another possibility is
glFinish
: start and wait until done.


In this class,
always

flush at the end your display function. Use
glFlush
,
glFinish
, or

glutSwapBuffers

(to be discussed later).

12 Sep 2003

CS 381

21

intro2d.cpp
:

THE RULES


Rules for callbacks (display in particular):

1.
You
never

call your callback functions. Only GLUT
does that.

2.
The display function
only

does drawing (which may
include GL state changes).

3.
No drawing is done outside the display function (but
state changes may be done).


These rules are for this class.


Later in life, you may want to break them.


But think hard first; they’re good rules.

12 Sep 2003

CS 381

22

STOPPED


We stopped here on Friday,
September 12.


We will continue with the following
slides on Monday.

12 Sep 2003

CS 381

23

intro2d.cpp
:

Function
keyboard

void keyboard(unsigned char key, int x, int y)

{


switch (key)


{


case ESCKEY: // ESC: Quit


exit(0);


break;


}

}



GLUT calls the keyboard function whenever an ASCII keypress happens.


Use the GLUT “special” function for non
-
ASCII (like arrow keys).


The ASCII value of the keypress is in
key
. Mouse position is in
x
,
y
.


Your keyboard (or special) function will usually be one big
switch
.


Why did I put in the (unnecessary)
break
?

12 Sep 2003

CS 381

24

intro2d.cpp
:

Function
idle


// Print OpenGL errors, if there are any


(for debugging)


if (GLenum err = glGetError())


{


cerr << "OpenGL ERROR: " << gluErrorString(err)


<< endl;


}



GLUT calls the idle function whenever nothing else needs doing.


It is useful for making time
-
dependent changes to the scene.


Here, we check for OpenGL errors, and print a message if there
is an error.


This is a rather atypical use of the idle function.