Lecture 4 - 3D Drawings
Lecture 4 - 3D Drawings
#include <GL/glut.h>
void myinit(void)
{
glClearColor(0.7, 0.7, 0.7, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D( -B/2, B/2, -B/2, B/2);
glMatrixMode(GL_MODELVIEW);
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity (); /* clear the matrix */
/* viewing transformation */
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef (1.0, 2.0, 1.0); /* modeling transformation */
glutWireCube (1.0);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
• The following transformations are specified:
Projection transformation - glFrustum()
Viewing transformation - gluLookAt(),
Modeling transformation - glScalef()
Viewport transformation - glViewport()
1. Viewing transformation
• The viewing transformation, gluLookAt(), positions and aims the
camera towards where the cube is drawn.
• The viewing transformation is analogous to positioning and aiming
a camera.
• In the example, before the viewing transformation can be specified,
the current matrix is set to the identity matrix with
glLoadIdentity().
• This step is necessary since most of the transformation commands
multiply the current matrix by the specified matrix and then set
the result to be the current matrix.
• If you don't clear the current matrix by loading it with the identity
matrix, you continue to combine previous transformation matrices
with the new one you supply.
• In some cases, you do want to perform such combinations, but
you also need to clear the matrix sometimes.
#include <GL/glut.h> void reshape (int w, int h)
void init(void) {
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
{
glMatrixMode (GL_PROJECTION);
glClearColor (0.0, 0.0, 0.0, 0.0);
glLoadIdentity ();
glShadeModel (GL_FLAT); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
} glMatrixMode (GL_MODELVIEW);
void display(void) }
{ int main(int argc, char** argv)
glClear (GL_COLOR_BUFFER_BIT); {
glColor3f (1.0, 1.0, 1.0); glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE |
glLoadIdentity (); /* clear the matrix */
GLUT_RGB);
/* viewing transformation */ glutInitWindowSize (500, 500);
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, glutInitWindowPosition (100, 100);
1.0, 0.0); glutCreateWindow (argv[0]);
glScalef (1.0, 2.0, 1.0); /* modeling init ();
transformation */ glutDisplayFunc(display);
glutWireCube (1.0); glutReshapeFunc(reshape);
glFlush (); glutMainLoop();
} return 0;
}
gluLookAt()
• After the matrix is initialized, the viewing transformation is
specified with gluLookAt().
• The arguments for this command indicate where the camera
(or eye position) is placed, where it is aimed, and which way
is up.
• The arguments used here place the camera at (0, 0, 5), aim
the camera lens towards (0, 0, 0), and specify the up-vector
as (0, 1, 0).
• The up-vector defines a unique orientation for the camera.
• If gluLookAt() was not called, the camera has a default
position and orientation.
• By default, the camera is situated at the origin, points down
the negative z-axis, and has an up-vector of (0, 1, 0).
• The overall effect is that gluLookAt() moves the
camera 5 units along the z-axis.
Syntax of command:
z World
• Your image has an 'up' to it that can be separate from the world's up.
• The blue window in this image can be thought of as the 'near-plane' that
your imagery is drawn on: your monitor, if you will.
• If all you supply is the eye-point and the at-point, that window is free to spin
around. You need to give an extra 'up' direction to pin it down.
• OpenGL will normalize the vector that you supply if it isn't unit length.
• OpenGL will also project it down so that it forms a 90 degree angle with the
'z' vector defined by eye and at(unless you give an 'up' vector that is
in exactly the same direction as the line from 'eye' to 'at').
• Once 'in' (z) and 'up' (y) directions are defined, it's easy
to calculate the 'right' or (x) direction from those two.
• In this figure, the 'supplied' up vector is (0,1,0) if the
blue axis is in the y direction.
• If you were to give (1,1,1), it would most likely rotate
the image by 45 degrees because that's saying that the
top of the blue window should be pointed toward that
direction.
• Consequently the image of the guy would appear to be
tipped (in the opposite direction).
Camera analogy
Task:
• Manipulate the values of the gluLookAt
function’s arguments, to view the object
from different positions:
e.g
gluLookAt (1.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
Task:
• Replace the gluLookAt() call with the modeling transformation glTranslatef() with
parameters (0.0, 0.0, -5.0).
• fovy is the angle of the field of view in the x-z plane; its value must be in the
range [0.0,180.0].
• Aspect is the aspect ratio of the frustum, its width divided by its height.
• Near and far values the distances between the viewpoint and the clipping
planes, along the negative z-axis.
• They should always be positive.
Orthographic Projection
• With an orthographic projection, the viewing volume is
a rectangular parallelepiped, or more informally, a box.
• Unlike perspective projection, the size of the viewing
volume doesn't change from one end to the other, so
distance from the camera doesn't affect how large an
object appears.
• This type of projection is used for applications such as
creating architectural blueprints and computer-aided
design, where it's crucial to maintain the actual sizes of
objects and angles between them as they're projected.
Orthographic Projection
• (left, bottom, -near) and (right, top, -near) are points on the near clipping plane that are
mapped to the lower-left and upper-right corners of the viewport window, respectively.
• (left, bottom, -far) and (right, top, -far) are points on the far clipping plane that are mapped
to the same respective corners of the viewport.
• Both near and far can be positive or negative.
• With no other transformations, the direction of projection is parallel to
the z-axis, and the viewpoint faces toward the negative z-axis.
• Note that this means that the values passed in for far and near are used as
negative z values if these planes are in front of the viewpoint, and positive if
they're behind the viewpoint.
• For the special case of projecting a two-dimensional image onto a two-
dimensional screen, use the Utility Library routine gluOrtho2D().
• This routine is identical to the three-dimensional version, glOrtho(), except
that all the z coordinates for objects in the scene are assumed to lie
between -1.0 and 1.0.
• If you're drawing two-dimensional objects using the two-dimensional vertex
commands, all the z coordinates are zero; thus, none of the objects are
clipped because of their z values.
• The clipping region is a rectangle with the lower-left corner at (left, bottom)
and the upper-right corner at (right, top).
#include <GL/glut.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity (); /* clear the matrix */
/* viewing transformation */
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef (1.0, 2.0, 1.0); /* modeling transformation */
glutWireCube (1.0);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
• As shown in the reshape() routine in the example,
the command called glMatrixMode() is used first,
with the argument GL_PROJECTION.
• This indicates that the current matrix specifies the
projection transformation;
• A few lines later glMatrixMode() is called again, this
time with GL_MODELVIEW as the argument.
• This indicates that succeeding transformations now
affect the modelview matrix instead of the
projection matrix.
4. The Viewport Transformation
• Together, the projection transformation and the viewport
transformation determine how a scene gets mapped onto the
computer screen.
• The projection transformation specifies the mechanics of how
the mapping should occur, and the viewport indicates the
shape of the available screen area into which the scene is
mapped.
• Since the viewport specifies the region the image occupies on
the computer screen, you can think of the viewport
transformation as defining the size and location of the final
processed photograph - for example, whether the
photograph should be enlarged or shrunk.
• The arguments to glViewport() describe the origin of
the available screen space within the window - (0,
• 0) in this example - and the width and height of the
available screen area, all measured in pixels on the
screen.
• This is why this command needs to be called within
reshape() - if the window changes size, the viewport
needs to change accordingly.
• Note that the width and height are specified using the
actual width and height of the window; often, you want
to specify the viewport this way rather than giving an
absolute Size.
Viewport Transformation
Screen Image
Viewport
47
Window vs. Viewport
• Window
– World-coordinate area selected for display
– What is to be viewed
• Viewport
– Area on the display device to which a window is
mapped
– Where it is to be displayed
48
Viewport Transformation
• Window-to-Viewport Mapping
Window Viewport
wy2 vy2
49
Reshape Function
PARAMETERS
•x, y: Specify the lower left corner of the viewport rectangle,
in pixels. The default is (0, 0).
•width, height: Specify the width and height, respectively, of
the viewport.
Manipulating the viewport
void display() {
#include <GL/glut.h> glClear(GL_COLOR_BUFFER_BIT);
glViewport((int) (0.0*deviceWindowWidth), (int) (0.0*deviceWindowHeight),
(int) (0.5*deviceWindowWidth), (int) (1.0*deviceWindowHeight));
int deviceWindowWidth; lineLoop();
int deviceWindowHeight; glViewport((int) (0.5*deviceWindowWidth), (int) (0.0*deviceWindowHeight),
(int) (0.5*deviceWindowWidth), (int) (1.0*deviceWindowHeight));
lineLoop()
void init() { glFlush();
glMatrixMode(GL_PROJECTION); }
glLoadIdentity();
void reshape(int width, int height)
gluOrtho2D(0.0, 1.0, 0.0, 1.0); {
deviceWindowWidth = width;
glClearColor(0.0, 0.0, 0.6, 1.0); deviceWindowHeight = height;
}
glColor3f(1.0, 1.0, 0.0);
glLineWidth(5.0); int main(int argc, char **argv)
} {
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
void lineLoop() { glutInitWindowSize(500, 500);
glBegin(GL_LINE_LOOP); glutCreateWindow("Hello (Viewports) World");
glVertex2d(0.05, 0.50); glutDisplayFunc(display);
glVertex2d(0.50, 0.95); glutReshapeFunc(reshape);
glVertex2d(0.95, 0.50); init();
glutMainLoop();
glVertex2d(0.50, 0.05); return 0;
glEnd(); }
}
Drawing the Scene
Output
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity (); /* clear the matrix */
/* viewing transformation */
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef (1.0, 2.0, 1.0); /* modeling transformation */
glutWireCube (1.0);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Exercise
• Alter the code in the example above, so that the
cube may appear as an orthographic projection
as shown in the diagram below: