Little Intro to OpenGL

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

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

85 εμφανίσεις

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 name

4.
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, // direction


0.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 use

glut.h, but still want/need to do some

OpenGL, you’ll have to include
gl.h

and/or
glu.h
; Pay attention in Windows

However, make sure you include

windows.h before any of the, since

It defines some macros needed

gl/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 called

frustum. Only those

graphical objects, entirely

or partially, happened to

be inside this frustum are

visible on screen.

nearPlane

farPlane

Camera

15

5

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 model

How 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

-
z

y

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 axis


glColor3f(1, 0, 0);


glVertex3f(0, 0, 0);


glVertex3f(2, 0, 0);


// Y axis


glColor3f(0, 1, 0);


glVertex3f(0, 0, 0);


glVertex3f(0, 2, 0);


// Z axis


glColor3f(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);


else


glOrtho


(



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, // position


0.0, 0.0, 0.0, // direction


0.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();

}