opengl glut tutorial

 


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

Post a Comment

Previous Post Next Post

Contact Form