July 8, 2002Serguei Mokhov, mokhov@cs.concordia.ca 1 Little Intro to OpenGL COMP471 - Computer...

Preview:

Citation preview

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

1

Little Intro to OpenGL

COMP471 - Computer Graphics

Edition 1.2, October 2, 2002

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

2

Contents

• Demos• Setting up Visual C++ to work with OpenGL• Working under Linux with OpenGL• Basics• Sample Programs

– skeleton.cpp Explained– sampleglprogram.cpp

• Other Examples

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

3

Setting up Visual C++ to work with OpenGL

1. Click main menu "File", then click menu item "New...".

2. Use Tab or mouse to select option "Projects“3. Use mouse to highlight the project type -- Win32

Console Application, then input the project name4. Click “OK” followed by clicking the “Finish”

button, you will create an empty project.5. Add all source code (*.h, *.cpp, *.c) into the

current project.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

4

Setting up Visual C++ to work with OpenGL (2)

7. Set the OpenGL library linkage.• Click main menu “Project”, then click menu item

“Settings…” followed by using mouse or Tab key to select option "Link".

• In the edit box "Object/library modules", three OpenGL libraries are appended: glu32.lib glut32.lib opengl32.lib (note that there is one space between library names).

• If you plan to use glaux, add glaux.lib as well.

8. Compile and link your project by using "F7" or the toolbar.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

5

Working under Linux with OpenGL

• You’ll need to link your compiled object files with the following libraries:

-lglut -lGL -lGLU -L/usr/X11R6/lib -lXmu -lXext -lXt -lXi -lX11

Grab example makefile from the web.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

6

Basics

• State Machine– Transformations– Light– Color– Textures– Viewing

• OpenGL Coordinate System• OpenGL: Event Driven

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

7

Basics (2)

• Matrices and Matrix Operations– Model-View Matrix– Projection Matrix– Matrix Stack

• Polygons in Open GL• Viewing

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

8

Polygons (GL_POLYGONS)

• By default are “two-sided”

• Counter clockwise (cube example)

• Concave

• Not necessarily “flat”

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

9

Viewing

• Changing Model (skeleton)• Changing Projection Matrix (sample)• Changing Camera position w/ gluLookAt()gluLookAt(

0.0, 0.0, g_fDistance, // position

0.0, 0.0, 0.0, // direction0.0, 1.0, 0.0 // up-vector

);

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

10

skeleton.cpp Explained: Headers

• #include stuff

#include <GL/glut.h>#include <math.h>#include <iostream.h>#include <strstream.h>#include <iomanip.h>

glut.h includes glu.h and gl.h, it also defines all needed macros

In labs, remove GL, because the sysadmins installed glut.h above it

Note: if you decide not to useglut.h, but still want/need to do someOpenGL, you’ll have to include gl.hand/or glu.h; Pay attention in WindowsHowever, make sure you include windows.h before any of the, sinceIt defines some macros neededgl/glu.h

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

11

skeleton.cpp Explained: Globals

• Global Constants and Variables// Initial size of graphics window.const int WIDTH = 600;const int HEIGHT = 400;

// Current size of window.int width = WIDTH;int height = HEIGHT;

That’s what it says. All sizes are in pixels.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

12

skeleton.cpp Explained: Globals

• Global Constants and Variables// Mouse positions, normalized to [0,1].double xMouse = 0.5;double yMouse = 0.5;

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

13

skeleton.cpp Explained: Globals

• Global Constants and Variables// Bounds of viewing frustum.double nearPlane = 5;double farPlane = 15;

Object in bold is calledfrustum. Only thosegraphical objects, entirelyor partially, happened tobe inside this frustum arevisible on screen.

nearPlane

farPlane

Camera

155

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

14

skeleton.cpp Explained: Globals

• Global Constants and Variables// Viewing angle.double fovy = 40.0;

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

15

skeleton.cpp Explained: Globals

• Global Constants and Variables// Variables.double alpha = 0; // Set by idle function.double beta = 0; // Set by mouse X. // Set by mouse Y.double distance = -(farPlane - nearPlane) / 2;

x

y

z•

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

16

skeleton.cpp Explained: main()

• Typical steps in main()…void main (int argc, char **argv){

// GLUT initialization. ...

// Register call backs....// Display ...

// GLUT loop}

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

17

skeleton.cpp Explained: main()

• GLUT Initialization, p. 646// GLUT initialization.glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize(width, height);glutCreateWindow("GLUT Skeleton Program");

Command line options. Must call glutInit() the very first thing.

Use double buffering (to avoid flickering) and RGB palette.

Initial graphical window size.

Creates graphical window with all settings before. Must be called the last. NOTE: Window is created, but NOT shown yet.

Window title bar. Renders useless during execution.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

18

Callbacks

• Callbacks are user-defined functions designed to react on specific events:– Whenever OpenGL decided it needs to redraw window contents– What to do when a user resizes a window.– Handle mouse motions…– React on keyboard,– What to do during idle period (no input from user),– and so on.

• For OpenGL to become aware of your callbacks, you need to register them within it before you start drawing things.

• Some of the callbacks are mandatory, such as display, so that OpenGL know how to render your graphics.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

19

skeleton.cpp Explained: main()

• Registering callbacks…// Register call backs.glutDisplayFunc(display);glutReshapeFunc(reshapeMainWindow);glutKeyboardFunc(graphicKeys);glutSpecialFunc(functionKeys);glutMotionFunc(mouseMovement);glutIdleFunc(idle);

User-defined functions

Knowing how to display the modelHow to resize on resize event…

How to react on “ordinary” keys…How to react on special keys (F1..F12, etc)

Catching a mouse …What to do when there’s nothing to do…

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

20

skeleton.cpp Explained: main()

• The rest...

// Display help.help();

// Enter GLUT loop.glutMainLoop();

All non-graphical output goes to STDOUT

This is the very last thing you call in the main(). Upon this call finally all the created windows are shown, and

the OpenGL state machine starts running.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

21

Callbacks: display()

• display()// This function is called to display the scene.void display (){

// {Clearing viewport and setting up initial matrices}…// Translate using Y mouse.…// Rotation from idle function.…// Rotation using X mouse.…// Draw model axes.…// Draw an object.…// {Double Buffering}

}

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

22

Callbacks: display()

• display()

glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();

Clears the color buffer of the viewport with current color

(image if it were would stay)

We’re going to operate on the Model/View Matrix now.

Initial “value” of the model/view matrix is identity

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

23

Callbacks: display()

• display()// Translate using Y mouse.distance = - (yMouse * (farPlane - nearPlane) + nearPlane);glTranslatef(0, 0, distance);

float x -zy

NOTE: z-axis goes to us from screen, i.e. it’s a

normal to screen’s surface

Make sure we’re inside the viewing volume.

Before we translate the object, it’s centered at the origin, for

us to see it, we need to move it far enough by z

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

24

Callbacks: display()

• Rotation// Rotation from idle function.glRotatef(alpha, 0, 1, 0);

// Rotation using X mouse.beta = 180.0 * xMouse;glRotatef(beta, 1, 0, 0);

Apply rotation transformation by y axis.

Apply rotation transformation by x axis

when using mouse.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

25

Callbacks: display()• Drawing graphical primitives.

• Always encapsulated inside glBegin/glEnd block// Draw model axes.glBegin(GL_LINES);

// X axisglColor3f(1, 0, 0);glVertex3f(0, 0, 0);glVertex3f(2, 0, 0);// Y axisglColor3f(0, 1, 0);glVertex3f(0, 0, 0);glVertex3f(0, 2, 0);// Z axisglColor3f(0, 0, 1);glVertex3f(0, 0, 0);glVertex3f(0, 0, 2);

glEnd();

R G B

The color persists until next getColor*() is called.

We connect vertices with lines. (Other things are

polygons, etc.)

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

26

Callbacks: display()

• Wire sphere…

// Draw an object.glColor3f(0, 1, 1);glutWireSphere(1, 20, 20);

Wire sphere, cube and other objects are also good for

“visual debugging”. P. 659

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

27

Callbacks: display()

• Double Buffering– To avoid flickering– To increase performance

• While one buffer is being displayed, the other one is being drawn “off-line”

• Then you swap the buffers, and do the same thing.• This way you don’t see actual drawing when the

program is running, so you can avoid flickering on a lower-resolution monitors and display adapters.

• In OpenGL we use: glutSwapBuffers();

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

28

Callbacks: reshapeMainWindow()

• reshapeMainWindow// Respond to window resizing, preserving proportions.// Parameters give new window size in pixels.void reshapeMainWindow (int newWidth, int newHeight){ width = newWidth; height = newHeight; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fovy, GLfloat(width) / GLfloat(height), nearPlane, farPlane);}

Drawing region in the window where all graphics is mapped.

All subsequent transformations are now upon projection matrix.

Projection matrix is initialized as identity

matrix

Define viewing volume (frustum), applying matrix transformations.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

29

sampleglprogram.cpp

• Has a very similar structure as skeleton.cpp, but there’s one significant difference:– Viewing Transformation is performed upon the

Projection Matrix every time display() is invoked.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

30

// This function is called to display the scene.void display (){ setView(); glClear(GL_COLOR_BUFFER_BIT);

// set modelling mode glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ....}

Performs viewing transformation.

Perform model transformation after.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

31

void setView(){ // Must set it up in Projection Matrix glMatrixMode(GL_PROJECTION); glLoadIdentity();

// Rotation about X from UP-DOWN Arrow key glRotatef(beta, 1, 0, 0);

// Rotation about Y from idle function. glRotatef(alpha, 0, 1, 0);

if(projType)gluPerspective(fovy, (GLfloat) 1.0, nearPlane, farPlane);

elseglOrtho(

viewWindowLeft,viewWindowRight,viewWindowBottom,viewWindowTop,nearPlane,farPlane

);}

Perform model transformation after.

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

32

gluLookAt()

• Manipulates the Camera

• The best way to observe the model

gluLookAt(

0.0, 0.0, g_fDistance, // position0.0, 0.0, 0.0, // direction0.0, 1.0, 0.0 // up-vector

);

July 8, 2002 Serguei Mokhov, mokhov@cs.concordia.ca

33

Matrix Stack

void drawSphere(GLdouble Radius, GLdouble x, GLdouble y, GLdouble z){ glPushMatrix(); // translate the table to its position

glTranslated(x, y, z); //draw glut sphere

glutWireSphere(Radius, 20, 20); glPopMatrix();}

Recommended