EECS 487: Interactive Computer Graphics!

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

13 Δεκ 2013 (πριν από 4 χρόνια και 18 μέρες)

121 εμφανίσεις

EECS 487: Interactive
Computer Graphics
!
Lecture
3
: Introduction to OpenGL and GLUT
!
What is OpenGL?
!
A set of APIs to interface with
"
the graphics hardware
!


used to manage the GPU resources to render image
!


sets up the graphics pipeline for rendering
!


deals only with low-level geometric primitives:
"
points, lines, polygons
!


no commands for drawing high-level objects, e.g., sphere (GLU)
!


no commands for system, I/O, and windowing or UI tasks (GLUT)
!


is hardware-independent
!


is cross platform, usually bundled with the OS, windowing
subsystem, and/or graphics card driver software
!
What is GLU?
!
A graphics library built on top of
OpenGL that comes bundled with
OpenGL and provides higher-level
modeling
primitives such as:
!


curves
!


surfaces
!


quadric: sphere, cylinder, disk
!


tessellation
!


NURBS
!


mip
maps
!


camera and projection controls
!
Application must provide to OpenGL
"
(usually with the help of a GUI toolkit):
!
Device context
:
!


abstraction of families of output media,
"
e.g., screen, off-line image buffer, printer
!
GL rendering context
:
!


window and data structure
"
containing all OpenGL
"
state info
!


multiple OpenGL windows
"
need different contexts
!


e.g., different scenes or
"
different views of the same scene
!
Device and Window Abstractions
!
A lightweight library for creating and managing
windows and widgets for OpenGL apps
!
Provides a single context
!


easy to learn
!


but used only for prototyping!
!
Cross platform
!


some other cross-platform GUI toolkits:
"
Fltk
,
GLFW
,
gtk
,
Qt
,
wxWidgets
, etc.
!


see “Links

Graphics tools” on course web site
!
GL

U
tility
T
oolkit
!
GL
!
GLU
!
GLUT
!
GLX
!
Xlib
!
Hardware
!
Application Program
!
WGL
!
Win32
!
AGL
!
CGL
!
OS (driver)
!
NSOpenGL
!
Cocoa
!
Carbon
!
gtk
!
OpenGL
and Related APIs
!
(simplified view)
!
The OpenGL Graphics Pipeline
!
Vertex
"
Processor
!
Rasterization
!
Fragment
!
Processor
!
Texture
!
Assembly
!
Framebuffer
!
Per-Pixel
"
Operations
!
Application
!
Geometric Pipeline
!
Pixel Pipeline
!
Programmable
Shader
!
Draw primitives into the
framebuffer
!
!
Primitives:
!


points
!


line segments
!


polygons
!


application provides vertex data (
x
,
y
,
z
)
!


pixel rectangles
!


bitmaps
!


application provides pixel data
!
What OpenGL Does
!
geometric
pipeline
!
pixel pipeline
!
Drawing
101
All geometric objects can be represented
"
as
a set of vertices
in
2D
or
3D
!
Draw objects by
specifying
the vertices and
"
how they are to be
connected
to form primitives:
!
1.

specify how the vertices are to be connected:
"
glBegin(connection
);
2.

specify the vertices:
"
glVertex
*(…);
3.

specify end of primitive:
"
glEnd
();
Drawing
101
Examples
!
To draw a line:
!
glBegin(GL_LINES
);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glEnd
();
To draw a triangle:
!
glBegin(GL_TRIANGLES
);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd
();
To draw a quadrilateral polygon (quad):
!
glBegin(GL_QUADS
);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glVertex2f(x3,y3);
glEnd
();
(
x
0
,
y
0
)
!
(
x
1
,
y
1
)
!
(
x
0
,
y
0
)
!
(
x
1
,
y
1
)
!
(
x
2
,
y
2
)
!
(
x
0
,
y
0
)
!
(
x
1
,
y
1
)
!
(
x
2
,
y
2
)
!
(
x
3
,
y
3
)
!
Note the
order of
vertices!
!
Connection Types
!


note vertex ordering
!


GL_POLYGON and GL_QUADS must be simple and convex!
!
OpenGL Command Syntax
!
API
!
gl

glu

glut
glX

agl

wgl

base
call
!
Color
Normal
Flush
Vertex
...
argument
count
!
2 – (
x
,
y
)
!
3 – (
x
,
y
,
z
)
!
4 – (
x
,
y
,
z
,
w
) or
!
4 – (
r
,
g
,
b
, a
)
!
argument data type
!
b

8
bit
!
GLbyte

ub

8
bit unsigned
!
GLubyte
,
GLboolean

s

16
bit
!
GLshort

us
16
bit unsigned
!
GLushort

i

32
bit
!
GLint
,
GLsizei

ui

32
bit unsigned
!
GLuint
,
GLenum
,
GLbitfield

f

32
bit
!
GLfloat
,
GLclampf

d

64
bit
!
GLdouble
,
GLclampd

vector
!
omit ‘
v
’ for scalar form
!
glVertex2f(x,y)
gl
Vertex
3
f
v
( . . . )
Drawing Block
!
Multiple
glBegin
()
...
glEnd
()
blocks allowed
!


each block specifies a
single type
of primitive
!


multiple instances
of primitive allowed inside each block
!


loops, conditions etc. allowed inside each block
!


normal C code and changing attributes like vertex color
allowed, but not other OpenGL commands
!
Drawing
101
To draw a
3D
triangle mesh:
!


glBegin(GL_TRIANGLES
);


emit a list of vertices

for (
int

i
=0;
i
<
n
;
i
++) {


every triple makes a face

glVertex3fv(v[i++]);


similarly for quad mesh

glVertex3fv(v[i++]);
glVertex3fv(v[i]);
}
glEnd
();
!
Or more efficiently (fewer calls to
glVertex
()
):
!


GL_TRIANGLE_STRIP


GL_TRIANGLE_FAN


GL_QUAD_STRIP

Drawing Wireframe Meshes
!
Draw polygon boundary edges only:
!
glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE);
glBegin(GL_TRIANGLES
);
for (
int

i
=0;
i
<
n
;
i
++) {

glVertex3fv(v[i++]);

glVertex3fv(v[i++]);

glVertex3fv(v[i]);
}
glEnd
();
!
Hidden surface removal:
!
glPolygonMode(GL_FRONT
, GL_LINE);
glPolygonMode(GL_BACK
, GL_FILL);
// fill
w
/ background color


was once an important problem
!
Yu
!
Drawing Shaded Polygon
!
glVertex
*()
!


specifies position only
!


drawn in current color
!
What do these commands draw?
!
glColor3f(0.0,
1.0
,0.0);
!
glBegin(GL_TRIANGLES
);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd
();
!
Drawing Shaded Polygon
!
Within a
glBegin
()
...
glEnd
()
block
!


normal C code and changing attributes like vertex color
allowed, but not other OpenGL commands
!
What do these commands draw?
!
glColor3f(0.0,
1.0
,0.0);
!
glBegin(GL_TRIANGLES
);
glVertex3fv(v[i++]);
glColor3f(0.0,0.0,
1.0
);
glVertex3fv(v[i++]);
glColor3f(
1.0
,0.0,0.0);
glVertex3fv(v[i]);
glEnd
();
!
Setting the Rendering Color
!
void glColor3
f
(GLfloat red,
GLfloat
green,
GLfloat
blue);
f

for float (single-precision)
!
Example of other color functions:
!
glColor3d():
rgb
-double,
glColor3s():
rgb
-short,
glColor4i():
rgba-int


void glColor3f
v
(const
GLfloat
*
rgb
);
v
for vector: pass values as array
!
!
Color value is
persistent
till next
glColor()
call
"

GL state machine
!
Programming Paradigms
!
What is the difference between:
!


functional and procedural programming?
!


procedural and object-oriented programming?
!
!
What is event-based programming?
!
!
OpenGL programming is state-machine based
!
OpenGL State Machine
!
OpenGL is a state machine
!
Majority of OpenGL functions do not cause anything to be
drawn; instead, they
modify OpenGL state
!
!
The few calls that actually draw a primitive all use the
current state
in drawing the primitive
!


example draw calls:
glVertex
,
glDrawElements

!
Application sets and changes state variables by issuing
OpenGL API calls
prior to
sending down primitives
!


the state variables indicate where and how an application wants a
primitive to be drawn
!


background color
!


vertex color
!


camera location, orientation, field of view
!


light source: number, color, location
!


polygon drawing mode: points, lines, filled
!


normal vectors
!


material properties
!


texture coordinates
!


whether to enable depth, transparency, fog
!


current viewing and projection transformations (matrices)
!
Example State Variables
!
OpenGL Attribute Stack
!
State variables can be saved on an attribute stack, with elements
pushed to and popped from the stack
!


example stack manipulation calls:
glPushAttrib
()
,
glPopAttrib
()
Primitives drawn will reflect the current state (top of the stack)
!
OpenGL State
!
OpenGL Attribute Stack
!
The OpenGL Graphics Pipeline
!
Vertex
"
Processor
!
Rasterization
!
Fragment
!
Processor
!
Texture
!
Assembly
!
Framebuffer
!
Per-Pixel
"
Operations
!
Application
!
Geometric Pipeline
!
Pixel Pipeline
!
Programmable
Shader
!
OpenGL State
!
Typical OpenGL Program Structure
!
See the
Installing and Using GLUT and OpenGL
course note for
sample code

(
http://www.eecs.umich.edu/sugih/courses/eecs487/glut-
howto
/sample.c)
!
!
1.

Create a window and bind OpenGL to this window
!


OpenGL API calls draw/render within this window
!


what to use to create the window?
!


what to use to interact with the graphics?
!
2.

Register event handlers (call-back functions)
!
A Simple OpenGL/GLUT Program
!
#include <GL/
glut.h
>

int

main(int

argc
, char *
argv
[])
{

glutInit(&argc
,
argv
);


/* Create the window first before drawing! */

glutInitDisplayMode(GLUT_SINGLE
| GLUT_RGBA);


/* single buffered, RGBA color (more later) */

glutInitWindowSize((int)width
, (
int)height
);
wd =
glutCreateWindow(“Title
”);
/* wd is the window handle */


/* register callback functions/event handlers */


glutReshapeFunc(
reshape
);

glutDisplayFunc(
display
);

glutIdleFunc(
refresh
);

glutKeyboardFunc(
kbd
);

glutPassiveMotionFunc(
move
);

glutMouseFunc(
click
);

glutMotionFunc(
drag
);


glutMainLoop
();
return 0;
}
name of
"
callback
functions
!
(optional)
!
see
sample.c

Event-Driven Programming
!
GLUT programs are event-driven
"
(most modern GUI programs are)
!


example events: window resized, covered, exposed,
"
mouse moved, button clicked, key pressed, etc.
!
You need to register a callback function (handler)
for each event you want to handle on your own
!
!
GLUT’s
main loop runs without an exit
!


if an event occur, its handler is called
!


upon handler exit, control returns to the main loop
!
Typical OpenGL Program Structure
!
3.

Set up drawing canvas and coordinate system
!
4.

Prepare the canvas: set up state variables on
attribute stack
!
5.

Loop:
!


clear
framebuffer
!


perhaps change the screen mapping
!


or change the coordinate system or projection matrix
!


set up lights, camera
!


draw primitives
!


complete drawing
!
Setting Up the Drawing Canvas
!
If you don’t plan on changing your coordinate
system or perspective often, set up the canvas
outside the GLUT main loop
!
!
Or you can change them every time the window
is reshaped
!


GLUT calls the
reshape()
function
when a window is
first created, before the first call to the
display()

function
!
Setting Up the Drawing Canvas
!
Define the screen mapping and coordinate
system (e.g., in
reshape()
):
!
!


tell OpenGL to use the whole window for drawing:
"
void glViewport(0, 0,
window_width
,
window_height
);



set up orthographic projection:
"
glMatrixMode(GL_PROJECTION
);
glLoadIdentity
();
gluOrtho2D(0.0,
window_width
, 0.0,
window_height
);
!


we’ll see more of this when we discuss transformations;
"
for now, we use a simple
2D
orthographic parallel projection,
looking straight into the scene
!
Typical OpenGL Program Structure
!
3.

Set up drawing canvas and coordinate system
!
4.

Prepare the canvas: set up state variables on
attribute stack
!
5.

Loop:
!


clear
framebuffer
!


perhaps change the screen mapping
!


or change the coordinate system or projection matrix
!


set up lights, camera
!


draw primitives
!


complete drawing
!
OpenGL Default
Framebuffer
!
Framebuffer
: a collection of images that store information
representing the image OpenGL eventually displays
!
OpenGL default
framebuffer
consists of:
!


color buffer(s)
: contains info about the color of each pixel, there
could be up to
4
color buffers: two for double buffering, which,
together with the other
2,
enable stereoscopic rendering
!


depth (or
z
-) buffer
: stores depth info of each pixel, allowing
closer pixels to be drawn over those farther away
!


stencil buffer
: for masked rendering
!


multisample
buffer
: for anti-aliasing
!


accumulation buffer
: for GFX
!


auxiliary color buffer(s)
: for off-screen rendering
!
subsumed by
FBO since
OpenGL
3
!
Clear
Framebuffer
!
Always clear the
framebuffer
first!
"
(what happens otherwise?)
!
!


set clearing color:
!
void
glClearColor(red
, green, blue, alpha);



perform the actual clear operation
!
void
glClear(GL_COLOR_BUFFER_BIT
);



other buffers can also be cleared, e.g., to clear the depth
buffer use
GL_DEPTH_BUFFER_BIT
!
Typical OpenGL Program Structure
!
3.

Sets up drawing canvas and coordinate system
!
4.

Prepare the canvas: sets up state variables on
attribute stack
!
5.

Loop:
!


clear
framebuffer
!


perhaps change the screen mapping
!


or change the coordinate system or projection matrix
!


set up lights, camera
!


draw primitives
!


complete drawing
!
Rendering a Line in OpenGL
!
All GL rendering happens inside the
display()
handler
!
For GL window to render a line:
!
void
display(void
)
{
/* clear the screen to white */
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT
);

/* draw line */
glBegin(GL_LINES
);

glVertex2f(x0,y0);
glVertex2f(x1,y1);
glEnd
();
glFlush
();
/* force rendering to start */
/* or
glFinish
()
which returns only upon
completion of rendering */
}
Completing the Drawing
!
Issued GL commands may be stuck in buffers along
the pipeline, e.g., waiting for more commands to be
issued before sending them in batch
!
You need to flush all these buffers if you have no
more commands to issue, to start rendering
!


void
glFlush(void
);

flushes the buffers and starts execution of commands
!


void
glFinish(void
);

waits for commands to finish executing before returning
!


void
glutSwapBuffers(void
);
"
if double buffered

GLUT Program Skeleton
!
#include <GL/
glut.h
>

int

main(int

argc
, char *
argv
[])
{

glutInit(&argc
,
argv
);


/* Create the window first before drawing! */

glutInitDisplayMode(GLUT_SINGLE
| GLUT_RGBA);


/* single buffered, RGBA color */

glutInitWindowSize((int)width
, (
int)height
);
wd =
glutCreateWindow(“Title
”); /* wd is the window handle */


/* register callback functions/event handlers */

glutReshapeFunc(
reshape
);

glutDisplayFunc(
display
);


glutIdleFunc(
refresh
);

glutKeyboardFunc(
kbd
);

glutPassiveMotionFunc(
move
);

glutMouseFunc(
click
);

glutMotionFunc(
drag
);


glutMainLoop
();
return 0;
}
name of
"
callback
functions
!
(optional)
!
see
warmup.c
Lab
0
Tasks (In Order)
!
1.

Draw two points on the screen:
GL_POINTS
!
2.

Connect the two points into a line:
GL_LINES
3.

Change the line to
3
-pixel thick

4.

Draw filled squares at both end points:
!


perturb coordinates, use
GL_QUADS
5.

Draw a thin line at the
x
- and
y
-axes
!
6.

Shift the coordinate system by (
-1
,
-1
) every
100
ms
!
7.

Draw outline, instead of filled, squares at both end points
!
8.

Draw a filled square around the Origin
!
9.

Change cursor to
GLUT_CURSOR_CROSSHAIR
whenever
mouse cursor is near an end point
!
10.

Allow end points to be dragged around the screen, with the
line re-drawn between the new end points
!
Grading Policy
!
Regrade
:
!


within
5
working days
"
(except Final Exam and HW
2
, same day)
!


written request
!


whole work will be
regraded
!
Late days:
!


4
free late days total
for programming assignments
!


including weekends
!


no need to inform us to use any of your free late days
!


keep track of your own free late day usage
!
Help with
PAs
stops
2
days before due date
!
Late Penalty
!
Applied to
PAs

after
free late days are used up
!
Applied to HW
1
and Labs immediately
!
HW
2
will not be accepted late (
soln
handed out same day)
!
Penalty schedule:
!




24
hours:
4%




48
hours:
8+4=12%




72
hours:
12+12=24%




96
hours:
16+24=40%




120
hours:
20+40=60%


work more than
5
days late will not be accepted
!
Example:
!


PA
worths

100
points, work late by
24
hours and
10

mins
!


if no free late days left:
12
points late penalty
!


if 1 free late day left:
8
points late penalty
!


turning in
HWs

after lecture has started
is considered one day late
!
Lab Grading
!
During lab session and lab grading time ONLY
!
No lab grading in lecture
!
Lab grading during office hours only if no other
students are waiting with questions
!
Do NOT accost Landon outside the lab
!
Late Lab Submission
!
Email SHA
1
to Landon
!
Subject: EECS487 Late Submission Lab #
Content: the result of running
!
%
openssl
sha1 [files …]
!
Once you have computed the SHA
1
,
don’t make any
more changes to the files
, or your SHA
1
will become
invalid
!
!
Must still be graded in person by
Landon
before the
next lab is due
or get a zero for the lab
!
Use
MFiles
to upload/download files or use
ssh
and
scp
or
afs
:
!
!
1.

Come pre-installed on Linux and Mac OS X
"
Mac OS X can also use the
Fugu
app for
scp

http://rsug.itd.umich.edu/software/fugu/

2.

GUI-based
OpenAFS
for Mac OS X and Windows:
http://www.openafs.org/

File Up/Download and SHA
1
!
3.

With Visual Studio:
!


SHA
1

(
not MD
5
)
:
"
http://www.nirsoft.net/utils/
hash_my_files.html



Putty:
"
http://
www.chiark.greenend.org.uk
/~
sgtatham
/putty/



WinSCP
:

http://sourceforge.net/projects/winscp/
4.

Command line alternative for Windows:
"
install
Cygwin
(
http://
www.cygwin.com
/
)
"
along with the following packages:
!


Devel
:
gcc-g
++,
gdb
, make
!


Editors: vim
!


Graphics:
libglut-devel
!


Net:
openssh
!


X11:
xhost
,
xinit
,
libGLU
!
For Windows:
!
Collaboration
!


All work must be done individually
!


Cheating and plagiarizing are not tolerated
!


To pass off the implementation of an algorithm
"
as that of another is also considered cheating:
!


e.g., insertion sort is
not
heap sort
!


if you can not implement a required algorithm,
"
you
must inform the teaching staff when turning in your assignment
!


Homeworks
: consultation of online and offline sources
allowed, but must not be copied verbatim, you need to
show that you have understood the material. Cite your
sources, including classmates and roommates, but not
teaching staff or required readings
!


Exams: see course Grading Policy web page
!