What is GLUT?
GLUT is the OpenGL Utility Toolkit.
It is a platform independant toolkit with utilty functions to help
with basic window tasks
Creating a Window
GLUT can be used to create a windows as follows
int main ( int argc , char ∗∗ argv ) {
g l u t I n i t (&a r gc , a r g v ) ;
g l u t I n i t D i s p l a y M o d e (GLUT DEPTH| GLUT DOUBLE
| GLUT RGBA) ;
g l u t I n i tW i n d o w S i z e ( 800 , 800 ) ;
gl u tC rea teWi n d ow ( ”Te s t Window” ) ;
gl u tMai n L o o p ( ) ;
// Neve r r e t u r n s
r e t u r n EXIT SUCCESS ;
}
But Empty Windows Are Pointless
We can tell GLUT to use a given drawing function
. . .
g l u t D i s p l a y F u n c ( d i s p l a y ) ;
. . .
with a function pointer!
v o i d d i s p l a y ( ) {
g l C l e a r (GL DEPTH BUFFER BIT |
GL COLOR BUFFER BIT) ;
}
But Nothing
But Nothing Happens
The window making code in the previous slide used a double
buffered window so the display code doesn’t actually do anything.
You need to swap the buffers before an image will appear at the
end of display() using
g l u t Sw a p B u f f e r s ( ) ;
The Black Screen of Victory
So now we have a blank window. By adding in OpenGL commands
into the display function we can make the window display what we
want.
v o i d d i s p l a y ( ) {
g l C l e a r (GL DEPTH BUFFER BIT |
GL COLOR BUFFER BIT) ;
g lR e n d e rC o o lIm a g e ( ) ;
g l u t Sw a p B u f f e r s ( ) ;
}
Moving Pictures
Now that we have a static image on the screen, we want to move
to the next step. A changing image. We can specify a function for
GLUT to use when nothing is happening to update the state of the
world.
. . .
g l u t I d l e F u n c ( c h a n g i f y ) ;
. . .
with a function pointer!
v o i d c h a n g i f y ( ) {
//Update t h e w o r l d s t a t e c o o l y
}
The Image Is Still Stationary
Even though we have updated what should be drawn we haven’t
actually told anything that the screen needs to redraw. As far as
everything else is concerned redrawing would just draw the original
thing again.
To get around this, we use the following command at the end of
changify() to say that the screen needs to be redrawn because it
has actually changed.
v o i d c h a n g i f y ( ) {
//Update t h e w o r l d s t a t e c o o l y
g l u t P o s t R e d i s p l a y ( ) ;
}
So You Can Only Make Movies
At the moment, we can show animations, but we can’t interact
with them. Essentially we have made a movie. As this is software,
there should be a way of letting the user interact with your
software somehow.
How to Speak Computer
GLUT supports several different kinds of input which we will look
at
I
Window re-size/shape
I Keyboard
I Mouse
I Right click menus
I Waiting
The Screen Ratio Diet
In terms of interaction dragging a window is pretty boring, but
reshaping it might allow the user to change the shape of objects on
the screen.
Enforcing Behaviours
There isn’t a single correct option when dealing with changes in
screen size and shape. Thankfully GLUT gives us a way to tailor
the behaviour to our needs. We can assign a screen resize callback
to make any appropriate adjustments
.
. . .
g l u tR e s ha p e F u n c ( r e s h a p e ) ;
. . .
v o i d r e s h a p e ( i n t wid th , i n t h e i g h t ) {
//Do s om e t hi n g s e n s i b l e
}
What different ways are there of sensibly dealing with a change is
screen size and shape?
Keyboard Input - ASCII
Suppose we want to go to the extreme of having keyboard input.
First we shall consider how to deal with events which correspond
to the typing of an ASCII character. Note that you don’t know at
which point in the press/release cycle this is triggered. Also note
that information about the mouse location is also provided.
. . .
gl u tK e y b oa r d F u n c ( k e y p r e s s ) ;
. . .
v o i d k e y p r e s s ( u n s i g n e d c h a r key , i n t mouseX ,
i n t mouseY) {
i n t mod = g l u t G e t M o d i f i e r s ( ) ;
i f ( key == ’ i ’ && mod == GLUT ACTIVE SHIFT)
{
p r i n t f ( ”The mouse i s a t %d %d\n” , mouseX
, mouseY) ;
}
}
What About The Arrow Keys?
GLUT has a separate callback for non ASCII keypresses. Similar to
the previous, it also gives you the mouse position, but now you
need to compare the result to special constants for each key. You
still need glutGetModifiers() to find out about ALT, CTRL and
SHIFT.
g l u t S p e c i a l F u n c ( s p e c i a l p r e s s ) ;
. . .
v o i d s p e c i a l p r e s s ( i n t key , i n t mouseX , i n t
mouseY) {
i f ( key == GLUT KEY RIGHT) {
p r i n t f ( ”The mouse i s a t %d %d\n” , mouseX
, mouseY) ;
}
}
So Seriously, What About the Mouse?
Just like we have callbacks for the keyboard, we have similar ones
for the mouse. Much like how the keyboard can see the mouse,
calling glutGetModifiers() is used in the mouse callback function to
find out about the state of certain keyboard keys.
gluMouseFunc ( mouse ) ;
. . .
v o i d mouse ( i n t bu t t on , i n t s t a t e , i n t x , i n t y
) {
i f ( b u t t o n == GLUT LEFT BUTTON && s t a t e ==
GLUT DOWN) {
p r i n t f ( ”The mouse i s a t %d %d\n” , x , y ) ;
}
}
What About Mouse Movement
The previous function told us only when mouse buttons are
pushed. We need two different functions in order to track when
the mouse is moving
gl u tM o ti o n F u n c (mouseMove ) ;
g l u t P a s s i v eM o t i o n F u n c ( pa s si v eM o v e ) ;
. . .
v o i d mouseMove ( i n t x , i n t y ) {
p r i n t f ( ”A b u t t o n i s down and t h e mouse i s a t
%d %d\n” , x , y ) ;
}
v o i d pa s si v eM o v e ( i n t x , i n t y ) {
p r i n t f ( ”No b u t t o n s a r e down and t h e mouse i s
a t %d %d\n” , x , y ) ;
}
Looking at all these functions. Surely they remind you of
something. Have you seen anything that looks similar to this
before
Context Menus: The One True Path
So we have mouse and keyboard interaction, but what about right
click menus? These are standard things and yet making them with
the existing functions would be a lot of work.
To deal with this GLUT has its own mechanism for creating right
click menus.
i n t submenu = gl u tC r ea t eM e n u ( v i o l e n c eM e n u ) ;
glu tAddMenuEn t ry ( ” Shoo t ” , 0 ) ;
glu tAddMenuEn t ry ( ” E x pl o d e ” , 1 ) ;
i n t menu = gl u tC r ea t eM e n u (mainMenu ) ;
glu tAddMenuEn t ry ( ” F i s h ” , 0 ) ;
glu tAddMenuEn t ry ( ”Meat” , 1 ) ;
glu tAddMenuEn t ry ( ” C hi ck e n ” , 2 ) ;
glutAddSubMenu ( ” E x t r a F u n c t i o n s ” ,submenu ) ;
gl u tA t tac hMe n u (GLUT RIGHT BUTTON) ;
The Menus - They Do Nothing!
So we have a menu, but we don’t actually have any code to deal
with the menu. However, in hte previous slide we did specify which
functions would be used to respond to each menu being clicked.
So all we need is to define those functions.
v o i d mainMenu ( i n t i t em ) {
i f ( i t em == 0 ) p r i n f ( ”You c l i c k e d f i s h \n” ) ;
i f ( i t em == 1 ) p r i n f ( ”Moo\n” ) ;
i f ( i t em == 2 ) p r i n f ( ”Bawk\n” ) ;
}
v o i d v i o l e n c eM e n u ( i n t i t em ) {
i f ( i t em == 0 ) p r i n f ( ”Peow Peow\n” ) ;
i f ( i t em == 1 ) {
i n t ∗ f ;
∗∗ f = 500 ;
}
}
Waiting
Suppose we want to have something happen after a specified
amount of time? Well GLUT has a function for that too. It takes a
time in milliseconds, a function and a value that lets you identify
where it came from. The function will be called at some point
after the requested amount of time has passed. There is no
mechanism for cancelling a request, but the value parameters
allows you to work out that it should be ignored.
i n t m i l l i s = 1000 ;
gl u tTim e r F u n c ( m i l l i s , c o o l S t u f f , 0 ) ;
. . .
v o i d c o o l S t u f f ( i n t v a l u e ) {
i f ( v a l u e ==0 ) {
//Do s om e t hi n g r e l e v a n t
}
}
Stoke Fonts
Stroke fonts are pretty much like everything else with GL. You use
a transform to set where you want them to be drawn, and draw as
normal. They will draw from where the translation moved to, and
drawing each character translates the model view matrix to fit the
next characted into place.
v o i d d i s p l a y ( ) {
g l T r a n s l a t e f ( 0 , 10 , 0 ) ;
g l S c a l e f ( 0 . 05 , 0 . 05 , 0 . 05 ) ;
g l C o l o r 3 f ( 0 , 1 . 0 , 0 ) ;
f o r ( u n s i g n e d i n t i = 0 ; i < l e n g t h ; i++) {
g l u t S t r o k e C h a r a c t e r (GLUT STROKE ROMAN, s [ i ] ) ;
}
g l u t P o s t R e d i s p l a y ( ) ;
}
Stroke Fonts Killed Santa
There are in fact only 2 stroke fonts supported by GLUT:
GLUT STROKE ROMAN and GLUT STROKE MONO ROMAN.
On top of that, each drawing operation affects the model view
matrix. This means that you need to undo all of the changes after
you finish drawing, otherwise you may not be sure where exactly
you are in the world.
Also you are writing words in the world. What if you just want
your writing to be in a fixed position of the screen
Journey to Flatland
We can also draw raster text to the screen. Raster cooridinates are
transformed the same way that normal vertex coordinates are using
the model view and projection matricies. Raster coordinates are
however tracked independantly.
g l C o l o r 3 f ( 1 . 0 , 0 , 0 ) ;
g l R a s t e r P o s 2 f ( 0 , 0 ) ;
f o r ( u n s i g n e d i n t i = 0 ; i < l e n g t h ; i++) {
g l u t B i t m a p C h a r a c t e r (GLUT BITMAP TIMES ROMAN
24 , s [ i ] ) ;
}
Life in Flatland
Every call to glutBitmapCharacter(. . . ) results in the current offset
for drawing being moved by the exact amount of space necessary
for that character to be drawn. This is good as it means that you
can draw strings with an easy loop.
It has the following fonts
GLUT BITMAP 8 BY 13
GLUT BITMAP 9 BY 15
GLUT BITMAP TIMES ROMAN 10
GLUT BITMAP TIMES ROMAN 24
GLUT BITMAP HELVETICA 10
GLUT BITMAP HELVETICA 12
GLUT BITMAP HELVETICA 18
But What Can We Actually Do?
We have looked at a number of GLUT commands which allow us
to respond to input and write text to the screen, but we still can’t
actually draw anything.
To this end we need OpenGL and GLU to actually have output on
the screen. So lets recap some basic OpenGL and have a look at a
basic program
Look Mum - A Triangle!
We give co-ordinates for points inside of glBegin(). These are
coordinates in the rendering world, and will be mapped back to the
real world by OpenGL.
g l B e g i n (GL TRIANGLES) ;
g l V e r t e x 3 f ( 0 , 1 , 0 ) ;
g l V e r t e x 3 f(−1 , 0 , 0 ) ;
g l V e r t e x 3 f ( 1 , 0 , 0 ) ;
glE n d ( ) ;
Drawing Shapes
Diffent parameters result in different shapes being drawn
GL POINTS
GL LINES
GL LINE STRIP
GL LINE LOOP
GL TRIANGLES
GL TRIANGLE STRIP
GL TRIANGLE FAN
GL QUADS
GL QUAD STRIP
GL POLYGON