2D Drawing &
OpenGL
• Outline
• World Space & Screen Space
Matrices
• Intro to OpenGL & GLUT
• 2D Texture Mapping
Screen Space
• Ultimately, we display our images and
graphics in screen space.
Pixels are addressed in screen-space
coordinates.
Screen Space
• However, screen space depends on:
the resolution of the display. I.e., the
number of pixels in x and y.
the size of the window that displays our
graphics.
• the zero point of the screen coordinate
system.
• the window aspect ratio.
Screen Coordinate Systems
GLUT
Windows API
X Windows under Unix / Linux
Apple QuickDraw
OpenGL
World Space
• Often, we want to structure our graphics
independent of screen or window sizes.
• We do so by defining world space where
we specify our graphics.
• World space provides the natural
coordinate system for the problem at
hand.
Normalized Device Coordinates
• Between world and screen space, we
introduce an intermediate “rendering
space” with normalized device
coordinates.
• NDC is similar to screen space, but
without any hardware display
dependencies.
• We pick the following convenient
coordinate system:
Why Introduce NDC?
• Simplifies many rendering operations and
makes them more amenable to a HW
implementation.
• Clipping
• Computing coefficients for interpolation
• Converting to fixed-point representation
• Separates the bulk of geometry
processing from the specifics of
rasterization.
World to NDC Mapping
• The transformation between world
coordinates and NDC is a simple scale
and offset.
• To compute the scale and offset, we
specify example
• input coordinate values and their desired
output values.
World to NDC Mapping
• For x coordinates:
World to NDC Mapping
• NDC coordinates are a scale and
displacement of world coordinates:
NDC to Screen Mapping
World to Screen Mapping
• The NDC to screen mapping could also be
implemented as a matrix transformation.
• Generally, it is not (dedicated hardware)
• World-to-NDC: floating point
• NDC-to-screen: fixed point
• Inserts an opportunity to compensate for
differences in coordinate frames:
Summary
Viewport
• We can also define a rectangular viewport
in pixel coordinates.
• All objects inside the NDC window are
mapped inside of the viewport.
Outline
World Space & Screen Space
Matrices
Intro to OpenGL & GLUT
2D Texture Mapping
Matrices
Matrix: An array of elements that follow certain
rules.
We use uppercase letters to indicate a matrix:
• A matrix that has n rows and m columns is said
to be of order n x m.
• We always mention the numbers of rows first.
Square Matrices
Row and Column Vectors
A 1 x n matrix is called a row vector.
A n x 1 matrix is called a column vector.
We will use lower case bold letters to indicate
vectors.
• In graphics (and in this class) we mostly use
column vectors.
Transpose of a Matrix
The transpose of A is written as AT.
AT is formed by interchanging rows and
columns of matrix A.
The transpose of a row vector is a column
vector.
Addition and Subtraction
• Addition and subtraction of matrices is
defined by addition and subtraction of their
corresponding elements.
• Note: We can only add / subtract matrices
of the same order.
Multiplication by a Scalar
• Scalar: an ordinary real (e.g., float)
number.
• To multiply a matrix by a scalar, we
• multiply each element of the matrix by the
number.
• Examples:
Matrix x Column Vector
.
Matrix x Column Vector
Linear Combinations
• A linear combination of m vectors is a
vector of the form:
• Where a1, a2, …, am are scalars.
• Example:
Examples
Compute the matrix-vector product:
Outline
• World Space & Screen Space
Matrices
• Intro to OpenGL & GLUT
• 2D Texture Mapping
Graphics APIs
API stands for Application Program Interface.
• It is a collection of routines that the programmer
can call, along with a model of how the routines
work together to produce graphics.
• As a programmer you see only the interface.
You are
• therefore shielded from the specifics of the
underlying
• graphics hardware or software.
Scene Graph vs. Low Level API
• Scene graph API:
• Implemented on top of a low level API.
• Specify rendering hints to the hardware.
• Controls the objects in the scene through a
scene graph.
• Low level API:
• Controls the 3D rendering directly.
• Very efficient implementation, close to
hardware.
Current Graphics APIs
• Scene graph APIs:
• Java3D
• VRML
• OpenInventor
• POVRay
• Low level APIs:
• OpenGL
• Direct3D (part of Microsoft’s DirectX)
OpenGL
• Window system independent.
• Operating system independent.
• Initially developed by Silicon Graphics Inc.
• OpenGL Architecture Review Board (ARB)
• Scales from PC to very high-end engines.
• Intuitive, procedural interface with C bindings.
• Version 1.4 commonly available on PCs.
• OpenGL 2.0 just introduced
OpenGL Extensions
• Many extensions for high-end features.
• Some extensions are ratified by the ARB:
• GL_ARB_multitexture();
• GL_ARB_multisample();
• Some are agreed on by multiple vendors:
• GL_EXT_abgr();
• Others are vendor specific:
• GL_ATI_vertex_array_object();
• GL_NV_register_combiners();
OpenGL and GLUT
Related APIs
• GLUT (OpenGL Utility Toolkit)
Portable windowing API
Not officially part of OpenGL
• OpenGL
• Initially developed by Silicon Graphics Inc
• OpenGL Architecture Review Board (ARB)
• AGL, GLX, WGL
• Glue between OpenGL and windowing systems
• GLU (OpenGL Utility Library)
• Part of OpenGL
• NURBS, tessellators, quadric shapes, etc
Preliminaries
• Header files (C:\Program Files\Microsoft
Visual Studio\Vc98\include\gl\)
#include <GL/glut.h> // must go first!
#include <GL/gl.h>
#include <GL/glu.h>
• Static libraries (C:\Program Files\Microsoft
Visual Studio\Vc98\lib\)
• Opengl32.lib / Glu32.lib / Glut32.lib /
• Dynamic link libraries (C:\windows\system\ for
Win98)
• Opengl32.dll / Glu32.dll / Glut32.
Preliminaries
• Add opengl32.lib glu32.lib glut32.lib to
your link options.
OpenGL Command Formats
Enumerated Types
• OpenGL defines numerous types for
compatibility:
OpenGL Geometric Primitives
• These are all the geometric primitives of
OpenGL:
A Simple Example
• Primitives are specified using
glBegin( primType );
glVertex2f(…); //One or more call
glEnd();
• primType determines how the vertices are
combined
Shapes Tutorial
OpenGL’s State Machine
• All rendering attributes are encapsulated in the OpenGL
state.
• Rendering styles.
• Shading and lighting.
• Texture mapping, etc.
• Setting State
glPointSize( size );
glLineStipple( repeat, pattern );
glShadeModel( GL_SMOOTH );
Enabling Features
glEnable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
OpenGL State Variables
• You can query the State Machine to determine the state
of any variable.
• Any feature you enable or disable with glEnable /
• glDisable as well as numeric settings set with glSet
• can be queried with the many variations of glGet.
• Example: Setting the current drawing color.
GLubyte color[3];
glColor3ub( color[0],color[1],color[2] );
glColor3bv( color );
...
GLfloat colorf[3];
glGetFloatv( GL_CURRENT_COLOR,colorf );
GLUT Basics
• GLUT handles all interactions with the windows system
and user input devices (mouse, keyboard).
• Advantages:
Portable (Windows, Mac, Linux)
Minimal overhead (hides many details)
Appeal to C-hackers
• Disadvantages:
Ugly (outdated call-back-based event handling)
Limited interaction
Global variables galore
A Simple Program
GLUT Windows
• Create a top-level window with:
int id = glutCreateWindow(char *name);
Create sub-windows with:
glutCreateSubWindow(int id, x, y, w, h);
id: ID of the parent window.
x, y: Position relative to the parent window.
w, h: Width and height in pixels.
• Set the current window:
glutSetWindow( int id );
• Get the id of the current window:
int id = glutGetWindow(void);
Initialize
Executed before any other OpenGL calls.
• By default, GLUT sets up a viewport. We
only need to mess with it if the window
size changes.
Using Double Buffering
1) Request a double buffered color buffer.
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
2) Clear color buffer.
glClear( GL_COLOR_BUFFER_BIT );
3) Render scene.
4) Request swap of front and back buffers.
glutSwapBuffers();
• Repeat steps 2-4 for animation
• glutSwapBuffers swaps the buffers of the
current
• window, if double buffered.
Immediate Mode
• Most OpenGL calls are immediately
executed.
Some notable exceptions are display lists.
• Finish all OpenGL drawing with a call to:
glFlush();
• glutSwapBuffers performs an implicit call to
• glFlush before it returns.
The Event Model
• Events from the input hardware are
queued into an event queue.
• Application routines (event handlers or
callbacks) handle specific event types.
GLUT Callback Functions
Register callbacks with GLUT:
• For subwindows, register the callbacks
right after the
• call to glutCreateSubwindow();
Keyboard Callback
Process keyboard input:
Mouse Callbacks
• GLUT lets you define several callback
functions for mouse events:
glutMouseFunc( mouseButton );
• Mouse button press or release events.
glutMotionFunc( mouseMove );
• Mouse movement while button is pressed
events.
Mouse Button Callback
• Design a callback function mouseButton as
follows:
void mouseButton( int button, int state, int x, int y );
int button: GLUT_LEFT_BUTTON,
GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
int state: GLUT_UP, GLUT_DOWN
int x, int y: mouse position
• Important: the mouse position y coordinate is
reversed
• from the OpenGL screen coordinate system!
Mouse Motion
• Design a callback function mouseMove as
follows:
void mouseMove( int x, int y );
• This event only occurs if the mouse is
moved while some button is held down.
Display
• Do all of your drawing here:
Viewport Mapping in OpenGL
• In OpenGL the world-to-viewport mapping
happens automatically every time a vertex
is drawn.
• OpenGL also automatically clips parts of
the object that lie outside the viewport
window.
• In 2D, the world window is set by
gluOrtho2D(), and the viewport is set by
glViewport().
OpenGL Functions
• GLUT code to establish a window on the
screen:
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
• World-to-NDC mapping:
• gluOrtho2D(w.left,w.right,w.bottom,w.top);
• NDC-to-screen mapping:
glViewport(0,0,(GLsizei)w,(GLsizei)h);
OpenGL Code
• We usually set up the world-to-screen
mapping in an initialize() routine that is
called during startup:
Displaying Images
• When we display images, we typically
want that our world coordinates match our
screen coordinates:
Writing Pixels
To write an image of size (w x h) to the
display:
glDrawPixels( w, h, GL_RGB, GL_UNSIGNED_BYTE,*array);
The image is written at the current raster
position.
• To change the raster position:
glRasterPos2i(x, y);
• The default is (0,0)
Reading Pixels
• To read pixels (w x h) from the display
starting at (x,y):
• glReadPixels( x, y, w, h, GL_RGB,
GL_UNSIGNED_BYTE, *array);
• When reading pixels make sure you know
the number of bits of resolution in the
display.
• Check using glGetIntegerv(GL_RED_BITS, &nbits);
Resize Callback
• A reasonable choice we recommend is:
Animation
• We can simply change the variables to the
OpenGL calls over time.
• For example, we can change the rectangle
position by incrementing it every time step.
• When and where do we change the
variables?
• When do we call glutSwapBuffers() ?
Animation 1
• We can update the variables in the idle
callback:
Animation 2
• We can call the GLUT timer CB at
specified intervals: