Last week
Angel/Shreiner/Mller
Overview of a graphics system
Output device
Input devices
Image formed and stored in frame buffer
Machiraju/Zhang/Mller
Cmpt 361
Torsten Mller
Ray tracing: the algorithm
for each pixel on screen
determine ray from eye through pixel
if ray shoots into infinity, return a background color
if ray shoots into light source, return light color appropriately
find closest intersection of ray with an object
Most
expensive
cast off shadow ray (towards light sources)
if shadow ray hits a light source, compute light contribution
according to some illumination model
cast reflected and refracted ray, recursively calculate pixel
color contribution
return pixel color after some absorption
Machiraju/Zhang/Mller
The algorithm
for each polygon in the scene
project its vertices onto viewing (image) plane
for each pixel inside the polygon formed on viewing plane
determine point on polygon corresponding to this pixel
get pixel color according to some illumination model
get depth value for this pixel (distance from point to plane)
if depth value < stored depth value for the pixel
update pixel color in frame buffer
update depth value in depth buffer (z-buffer)
end if
Question: What does the depth buffer store after running the z-buffer
end if
algorithm for the scene? Does polygon order change depth? Image?
Machiraju/Zhang/Mller
Programming using OpenGL:
A first introduction (version 3.2)
CMPT 361
Introduction to Computer Graphics
Torsten Mller
Angel/Shreiner/Mller
Development of the
OpenGL API
Angel/Shreiner/Mller
Early History of APIs
IFIPS (1973) formed two committees to come
up with a standard graphics API
Graphical Kernel System (GKS)
2D but contained good workstation model
Core
Both 2D and 3D
GKS adopted as IS0 and later ANSI standard
(1980s)
GKS not easily extended to 3D (GKS-3D)
Far behind hardware development
Angel/Shreiner/Mller
PHIGS and X
Programmers Hierarchical Graphics System
(PHIGS)
Arose from CAD community
Database model with retained graphics (structures)
X Window System
DEC/MIT effort
Client-server architecture with graphics
PEX combined the two
Not easy to use (all the defects of each)
Angel/Shreiner/Mller
SGI and GL
Silicon Graphics (SGI) revolutionized the
graphics workstation by implementing the
pipeline in hardware (1982)
To access the system, application programmers
used a library called GL
With GL, it was relatively simple to program
three dimensional interactive applications
Angel/Shreiner/Mller
10
OpenGL
The success of GL lead to OpenGL (1992), a
platform-independent API that was
Easy to use
Close enough to the hardware to get excellent
performance
Focus on rendering
Omitted windowing and input to avoid window
system dependencies
Angel/Shreiner/Mller
11
OpenGL Evolution
Originally controlled by an Architectural
Review Board (ARB)
Members included SGI, Microsoft, Nvidia, HP,
3DLabs, IBM,
Now Khronos Group
Was relatively stable (through version 2.5)
Backward compatible
Evolution reflected new hardware capabilities
3D texture mapping and texture objects
Vertex and fragment programs
Allows platform specific features through
Angel/Shreiner/Mller
extensions
12
OpenGL Architecture
Angel/Shreiner/Mller
13
Modern OpenGL
Performance is achieved by using GPU rather
than CPU
Control GPU through programs called shaders
Applications job is to send data to GPU
GPU does all rendering
Angel/Shreiner/Mller
14
http://gridtalk-project.blogspot.com/2010/07/future-of-computing-gpgpu.html
Angel/Shreiner/Mller
15
OpenGL 3.1
Totally shader-based
No default shaders
Each application must provide both a vertex and a
fragment shader
No immediate mode
Few state variables
Most 2.5 functions deprecated
Backward compatibility not required
Angel/Shreiner/Mller
16
Other Versions
OpenGL ES
Embedded systems
Version 1.0 simplified OpenGL 2.1
Version 2.0 simplified OpenGL 3.1
Shader based
WebGL
Javascript implementation of ES 2.0
Supported on newer browsers
OpenGL 4.1 and 4.2
Angel/Shreiner/Mller
Add geometry shaders
and tessellator
17
What About Direct X?
Windows only
Advantages
Better control of resources
Access to high level functionality
Disadvantages
New versions not backward compatible
Windows only
Recent advances in shaders are leading to
convergence with OpenGL
Angel/Shreiner/Mller
18
OpenGL Libraries
OpenGL core library
OpenGL32 on Windows
GL on most unix/linux systems (libGL.a)
OpenGL Utility Library (GLU)
Provides functionality in OpenGL core but avoids
having to rewrite code
Will only work with legacy code
Links with window system
GLX for X window systems
WGL for Windows
Angel/Shreiner/Mller
AGL for Macintosh
19
GLUT
OpenGL Utility Toolkit (GLUT)
Provides functionality common to all window
systems
Open a window
Get input from mouse and keyboard
Menus
Event-driven
Code is portable but GLUT lacks the functionality
of a good toolkit for a specific platform
No slide bars
Angel/Shreiner/Mller
20
Graphics libraries
GLUI: GLUT-based user interface library
(libglui)
Offer controls to OpenGL applications, e.g.,
buttons,
checkboxes,
radio buttons,
etc.
Angel/Shreiner/Mller
21
freeglut
GLUT was created long ago and has been
unchanged
Amazing that it works with OpenGL 3.1
Some functionality cant work since it requires
deprecated functions
freeglut updates GLUT
Added capabilities
Context checking
Angel/Shreiner/Mller
22
GLEW
OpenGL Extension Wrangler Library
Makes it easy to access OpenGL extensions
available on a particular system
Avoids having to have specific entry points in
Windows code
Application needs only to include glew.h and
run a glewInit()
Angel/Shreiner/Mller
23
Software Organization
Angel/Shreiner/Mller
24
OpenGL is an API
Application Programmers Interface:
a link between
low-level: graphics hardware
high-level: application program you write
OpenGL ES (for embedded systems): a subset of desktop OpenGL, providing
lightweight interface for 2D/3D graphics on mobile and hand-held devices, etc.
Angel/Shreiner/Mller
25
OpenGL Functions
Angel/Shreiner/Mller
26
OpenGL Functions
Primitives
Points
Line Segments
Triangles
Attributes
Transformations
Viewing
Modeling
Control (GLUT)
Input (GLUT)
Query
Angel/Shreiner/Mller
27
OpenGL State
OpenGL is a state machine
OpenGL functions are of two types
Primitive generating
Can cause output if primitive is visible
How vertices are processed and appearance of
primitive are controlled by the state
State changing
Transformation functions
Attribute functions
Under 3.1 most state variables are defined by the
application and Angel/Shreiner/Mller
sent to the shaders
28
Lack of Object Orientation
OpenGL is not object oriented so that there are
multiple functions for a given logical function
glUniform3f
glUniform2i
glUniform3dv
Underlying storage mode is the same
Easy to create overloaded functions in C++ but
issue is efficiency
Angel/Shreiner/Mller
29
OpenGL function format
function name
dimensions
glUniform3f(x,y,z)
x,y,z are floats
belongs to GL library
glUniform3fv(p)
p is a pointer to an array
Angel/Shreiner/Mller
30
OpenGL #defines
Most constants are defined in the include files
gl.h, glu.h and glut.h
Note #include <GL/glut.h> should
automatically include the others
Examples
glEnable(GL_DEPTH_TEST)
glClear(GL_COLOR_BUFFER_BIT)
include files also define OpenGL data types:
GLfloat, GLdouble, ...
Angel/Shreiner/Mller
31
OpenGL and GLSL
Shader based OpenGL is based less on a state
machine model than a data flow model
Most state variables, attributes and related pre
3.1 OpenGL functions have been deprecated
Action happens in shaders
Job is application is to get data to GPU
Angel/Shreiner/Mller
32
GLSL
OpenGL Shading Language
C-like with
Matrix and vector types (2, 3, 4 dimensional)
Overloaded operators
C++ like constructors
Similar to Nvidias Cg and Microsoft HLSL
Code sent to shaders as source code
New OpenGL functions to compile, link and
get information to shaders
Angel/Shreiner/Mller
33
Today
Development of the OpenGL API
OpenGL Architecture
OpenGL as a state machine
OpenGL as a data flow machine
Functions
Types
Formats
Simple program
Shaders
Readings: Sections 2.1-2.10
Angel/Shreiner/Mller
Colours and attributes
34
First Simple Program
Angel/Shreiner/Mller
35
Objectives
Build a complete first program
Introduce shaders
Introduce a standard program structure
Simple viewing
Two-dimensional viewing as a special case of
three-dimensional viewing
Initialization steps and program structure
Angel/Shreiner/Mller
36
Program Structure
Most OpenGL programs have a similar structure that consists of
the following functions
main():
enters event loop (last executable statement)
init(): sets the state variables
specifies the callback functions
opens one or more windows with the required properties
viewing
attributes
initShader():
create geometry
read, compile and link shaders
callbacks
Display function
Angel/Shreiner/Mller
Input and window functions
37
main.c
#include <GL/glew.h>
#include <GL/glut.h>
includes gl.h
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0); specify window properties
glutCreateWindow("simple");
display callback
glutDisplayFunc(mydisplay);
glewInit();
set OpenGL state and initialize shaders
init();
glutMainLoop();
}
enter event loop
Angel/Shreiner/Mller
38
GLUT functions
glutInit allows application to get command line arguments
and initializes system
gluInitDisplayMode requests properties for the window
(the rendering context)
RGB color
Single buffering
Properties logically ORed together
glutInitWindowSize in pixels
glutInitWindowPosition from top-left corner of
display
glutCreateWindow create window with title simple
glutDisplayFunc display callback
Angel/Shreiner/Mller
glutMainLoop enter infinite event loop
39
Immediate Mode Graphics
Geometry specified by vertices
Locations in space (2 or 3 dimensional)
Points, lines, circles, polygons, curves, surfaces
Immediate mode
Each time a vertex is specified in application, its
location is sent to the GPU
Old style uses glVertex
Creates bottleneck between CPU and GPU
Removed from OpenGL 3.1
Angel/Shreiner/Mller
40
Retained Mode Graphics
Put all vertex and attribute data in array
Send array to GPU to be rendered immediately
Almost OK but problem is we would have to
send array over each time we need another
render of it
Better to send array over and store on GPU for
multiple renderings
Angel/Shreiner/Mller
41
Display Callback
Once we get data to GLU, we can initiate the
rendering with a simple callback
void mydisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFlush();
}
Arrays are buffer objects that contain vertex
arrays
Angel/Shreiner/Mller
42
Vertex Arrays
Vertices can have many attributes
Position
Color
Texture Coordinates
Application data
A vertex array holds these data
Using types in vec.h
point2 points[3] = {point2(0.0, 0.0),
point2( 0.0, 1.0), point2(1.0, 1.0)};
Angel/Shreiner/Mller
43
Vertex Array Object
Bundles all vertex data (positions, colors, ..,)
Get name for buffer then bind
GLuint abuffer;
glGenVertexArrays(1, &abuffer);
glBindVertexArray(abuffer);
At this point we have a current vertex array but
no contents
Use of glBindVertexArray lets us switch
between VBOs
Angel/Shreiner/Mller
44
Buffer Object
Buffer objects allow us to transfer large
amounts of data to the GPU
Need to create, bind, and identify data
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER,
sizeof(points), points, GL_STATIC_DRAW);
Data in current vertex array is sent to GPU
Angel/Shreiner/Mller
45
Initialization
Vertex array objects and buffer objects can be
set up in init()
Set clear color and other OpenGL parameters
Set up shaders as part of initialization
Read
Compile
Link
First lets consider a few other issues
Angel/Shreiner/Mller
46
Coordinate Systems
The units in points are determined by the application and
are called
object (or model) coordinates
world coordinates
model view transform
Viewing specifications usually are also in object coordinates
transformed through
eye (or camera) coordinates
clip coordinates
normalized device coordinates
window (or screen) coordinates
projection transform
OpenGL also uses some internal representations that usually
are not visible to the application but are important in the
Angel/Shreiner/Mller
shaders
47
OpenGL Camera
OpenGL places a camera at the origin in object
space pointing in the negative z direction
The default viewing volume
is a box centered at the
origin with sides of
length 2
Angel/Shreiner/Mller
48
Orthographic Viewing
In the default orthographic view, points are
projected forward along the z axis onto the
plane z=0
z=0
z=0
Angel/Shreiner/Mller
49
Viewports
Do not have to use the entire window for the
image: glViewport(x,y,w,h)
Values in pixels (window coordinates)
Angel/Shreiner/Mller
50
Transformations and Viewing
In OpenGL, projection is carried out by a
projection matrix (transformation)
Transformation functions are also used for
changes in coordinate systems
Pre 3.0 OpenGL had a set of transformation
functions which have been deprecated
Three choices
Application code
GLSL functions
Angel/Shreiner/Mller
vec.h and mat.h
51
OpenGL Shaders
Angel/Shreiner/Mller
Objectives
Simple Shaders
Vertex shader
Fragment shaders
Programming shaders with GLSL
Finish first program
Angel/Shreiner/Mller
53
Vertex Shader Applications
Moving vertices
Morphing
Wave motion
Fractals
Lighting
More realistic models
Cartoon shaders
Angel/Shreiner/Mller
54
Fragment Shader Applications
Per fragment lighting calculations
per vertex lighting
Angel/Shreiner/Mller
per fragment lighting
55
Fragment Shader Applications
Texture mapping
smooth shading
environment
mapping
Angel/Shreiner/Mller
bump mapping
56
Writing Shaders
First programmable shaders were programmed
in an assembly-like manner
OpenGL extensions added for vertex and
fragment shaders
Cg (C for graphics) C-like language for
programming shaders
Works with both OpenGL and DirectX
Interface to OpenGL complex
OpenGL Shading Language (GLSL)
Angel/Shreiner/Mller
57
GLSL
OpenGL Shading Language
Part of OpenGL 2.0 and up
High level C-like language
New data types
Matrices
Vectors
Samplers
As of OpenGL 3.1, application must provide
shaders
Angel/Shreiner/Mller
58
Simple Vertex Shader
in vec4 vPosition;
void main(void)
{
gl_Position = vPosition;
}
Angel/Shreiner/Mller
59
Simple Fragment Program
out vec4 fColor;
void main(void)
{
fColor = vec4(1.0,0.0,0.0,1.0);
}
Angel/Shreiner/Mller
60
Execution Model
Application
Program
Vertex data
Shader Program
Shader Program
glDrawArrays
GPU
Fragment
Fragment
Color
Vertex
Angel/Shreiner/Mller
Data Types
C types: int, float, bool
Vectors:
float vec2, vec3, vec4
Also int (ivec) and boolean (bvec)
Matrices: mat2, mat3, mat4
Stored by columns
Standard referencing m[row][column]
C++ style constructors
vec3 a = vec3(1.0, 2.0, 3.0)
Angel/Shreiner/Mller
vec2
b
=
vec2(a)
62
Pointers
There are no pointers in GLSL
We can use C structs which
can be copied back from functions
Because matrices and vectors are basic types
they can be passed into and out from GLSL
functions, e.g.
mat3 func(mat3 a)
Angel/Shreiner/Mller
63
Qualifiers
GLSL has many of the same qualifiers such as
const as C/C++
Need others due to the nature of the execution model
Variables can change
not at all (const)
Once per primitive (uniform)
Once per vertex (attribute)
Once per fragment (varying)
At any time in the application
Vertex attributes are interpolated by the rasterizer
into fragment attributes
Angel/Shreiner/Mller
64
Uniform Qualified
Variables that are constant for an entire
primitive
Can be changed in application and sent to
shaders
Cannot be changed in shader
Used to pass information to shader such as the
bounding box of a primitive
Angel/Shreiner/Mller
65
Attribute Qualifier
Attribute-qualified variables can change at
most once per vertex
There are a few built in variables such as
gl_Position but most have been
deprecated
User defined (in application program)
Use in qualifier to get to shader
in float temperature
in vec3 velocity
Angel/Shreiner/Mller
66
Varying Qualified
Variables that are passed from vertex shader to
fragment shader
Automatically interpolated by the rasterizer
Old style used the varying qualifier
varying vec4 color;
Now use out in vertex shader and in in the
fragment shader
out vec4 color;
Angel/Shreiner/Mller
67
Example: Vertex Shader
const vec4 red = vec4(1.0,0.0,0.0,1.0);
in vec4 vPosition;
out vec4 color_out;
void main(void)
{
gl_Position = vPosition;
color_out = red;
}
Angel/Shreiner/Mller
68
Required Fragment Shader
in vec4 color_out;
out vec4 fColor;
void main(void)
{
fColor = color_out;
}
Angel/Shreiner/Mller
69
Passing values
call by value-return
Variables are copied in
Returned values are copied back
Three possibilities
in
out
inout (deprecated)
Angel/Shreiner/Mller
70
Operators and Functions
Standard C functions
Trigonometric
Arithmetic
Normalize, reflect, length
Overloading of vector and matrix types
mat4 a;
vec4 b, c, d;
c = b*a; // a column vector stored as a 1D array
d = a*b; // a row vector stored as a 1D array
Angel/Shreiner/Mller
71
Swizzling and Selection
Can refer to array elements by element using []
or selection (.) operator with
x, y, z, w
r, g, b, a
s, t, p, q
a[2], a.b, a.z, a.p are the same
Swizzling operator lets us manipulate
components
vec4 a;
2.0);
a.yz = vec2(1.0,
Angel/Shreiner/Mller
72
Colour and attributes
Angel/Shreiner/Mller
73
Objectives
Expanding primitive set
Adding color
Vertex attributes
Uniform variables
Angel/Shreiner/Mller
74
OpenGL Primitives
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
Angel/Shreiner/Mller
75
Polygon Issues
OpenGL will only display triangles
Simple: edges cannot cross
Convex: All points on line segment between two
points in a polygon are also in the polygon
Flat: all vertices are in the same plane
Application program must tessellate a polygon
into triangles (triangulation)
OpenGL 4.1 contains a tessellator
nonsimple polygon Angel/Shreiner/Mller
nonconvex polygon
76
Polygon Testing
Conceptually simple to test for simplicity and
convexity
Time consuming
Earlier versions assumed both and left testing
to the application
Present version only renders triangles
Need algorithm to triangulate an arbitrary
polygon
Angel/Shreiner/Mller
77
Good and Bad Triangles
Long thin triangles render badly
Equilateral triangles render well
Maximize minimum angle
Delaunay triangulation for unstructured points
Angel/Shreiner/Mller
78
Triangularization
d
Convex polygon
c
Start with abc, remove b, then acd, .
Angel/Shreiner/Mller
79
Attributes
Attributes determine the appearance of objects
Colour (points, lines, polygons)
Size and width (points, lines)
Stipple pattern (lines, polygons)
Polygon mode
Display as filled: solid color or stipple pattern
Display edges
Display vertices
Only a few (glPointSize) are supported by
OpenGL functions
Angel/Shreiner/Mller
80
RGB colour
Each colour component is stored separately in
the frame buffer
Usually 8 bits per component in buffer
Colour values can range from 0.0 (none) to 1.0
(all) using floats or over the range from 0 to
255 using unsigned bytes
Angel/Shreiner/Mller
81
Indexed Colour
Colours are indices into tables of RGB values
Requires less memory
indices usually 8 bits
not as important now
Memory inexpensive
Need more colors for shading
Angel/Shreiner/Mller
82
Smooth Colour
Default is smooth shading
OpenGL interpolates vertex colors across visible
polygons
Alternative is flat shading
Colour of first vertex
determines fill color
Handle in shader
Angel/Shreiner/Mller
83
Setting Colours
Colours are ultimately set in the fragment
shader but can be determined in either shader
or in the application
Application colour: pass to vertex shader as a
uniform variable or as a vertex attribute
Vertex shader color: pass to fragment shader as
varying variable
Fragment color: can alter via shader code
Angel/Shreiner/Mller
84
More GLSL
Angel/Shreiner/Mller
85
Objectives
Coupling shaders to applications
Reading
Compiling
Linking
Vertex Attributes
Setting up uniform variables
Example applications
Angel/Shreiner/Mller
86
Linking Shaders with
Application
Read shaders
Compile shaders
Create a program object
Link everything together
Link variables in application with variables in
shaders
Vertex attributes
Uniform variables
Angel/Shreiner/Mller
87
Program Object
Container for shaders
Can contain multiple shaders
Other GLSL functions
GLuint myProgObj;
myProgObj = glCreateProgram();
/* define shader objects here */
glUseProgram(myProgObj);
glLinkProgram(myProgObj);
Angel/Shreiner/Mller
88
Vertex Attributes
Vertex attributes are named in the shaders
Linker forms a table
Application can get index from table and tie it
to an application variable
Similar process for uniform variables
Angel/Shreiner/Mller
89
Vertex Attribute Example
#define BUFFER_OFFSET( offset )
((GLvoid*) (offset))
GLuint loc =
glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( loc );
glVertexAttribPointer( loc, 2, GL_FLOAT,
GL_FALSE, 0, BUFFER_OFFSET(0) );
Angel/Shreiner/Mller
90
Uniform Variable Example
GLint angleParam;
angleParam = glGetUniformLocation(myProgObj,
"angle");
/* angle defined in shader */
/* my_angle set in application */
GLfloat my_angle;
my_angle = 5.0 /* or some other value */
glUniform1f(angleParam, my_angle);
Angel/Shreiner/Mller
91
Double Buffering
Updating the value of a uniform variable opens
the door to animating an application
Execute glUniform in display callback
Force a redraw through
glutPostRedisplay()
Need to prevent a partially redrawn frame
buffer from being displayed
Draw into back buffer
Display front buffer
Angel/Shreiner/Mller
Swap buffers after
updating finished
92
Adding Double Buffering
Request a double buffer
glutInitDisplayMode(GLUT_DOUBLE)
Swap buffers
void mydisplay()
{
glClear();
glDrawArrays();
glutSwapBuffers();
}
Angel/Shreiner/Mller
93
Idle Callback
Idle callback specifies function to be executed
when no other actions pending
glutIdleFunc(myIdle);
void myIdle()
{
// recompute display
glutPostRedisplay();
}
Angel/Shreiner/Mller
94
Adding Color
If we set a color in the application, we can
send it to the shaders as a vertex attribute or as
a uniform variable depending on how often it
changes
Lets associate a color with each vertex
Set up an array of same size as positions
Send to GPU as a vertex buffer object
Angel/Shreiner/Mller
95
Setting Colors
typedef vec3 color3;
color3 base_colors[4] = {color3(1.0, 0.0. 0.0),
.
color3 colors[NumVertices];
vec3 points[NumVertices];
//in loop setting positions
colors[i] = basecolors[color_index]
position[i] = .
Angel/Shreiner/Mller
96
Setting Up Buffer Object
//need larger buffer
glBufferData(GL_ARRAY_BUFFER,
sizeof(points) + sizeof(colors),
NULL, GL_STATIC_DRAW);
//load data separately
glBufferSubData(GL_ARRAY_BUFFER,
0, sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER,
sizeof(points), sizeof(colors), colors);
Angel/Shreiner/Mller
97
Second Vertex Array
// vPosition and vColor identifiers in vertex shader
loc = glGetAttribLocation(program, vPosition);
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0));
loc2 = glGetAttribLocation(program, vColor);
glEnableVertexAttribArray(loc2);
glVertexAttribPointer(loc2, 3, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(sizeofpoints));
Angel/Shreiner/Mller
98