|
![]() |
![]() |
|
| Cube rendered with Orthographic Projection |
Cube rendered with Perspective Projection |
![]() |
![]() |
|
| Scene rendered with Orthographic Projection | Scene rendered with Perspective Projection |
|
|
|
Examples:
e.g. Viewer is at origin looking in the negative z-axis
| void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); |
| Creates a matrix for a perspective-view frustum and multiplies the current matrix by it. The frustum's viewing volume is defined by the parameters: (left, bottom, -near) and (right, top, -near) specify the (x, y, z) coordinates of the lower-left and upper-right corners of the near clipping plane; near and far give the distances from the viewpoint to the near and far clipping planes. They should always be positive. |
Let
| l | = | left | r | = | right | |
| b | = | bottom | t | = | top | |
| n | = | near | f | = | far |
The transformation matrix is given by
| l ≤ x' ≤ r | and | b ≤ y' ≤ t |

Therefore
#define PI 3.14159265389
double calculateAngle(double size, double distance)
{
double radtheta, degtheta;
radtheta = 2.0 * atan2 (size/2.0, distance);
degtheta = (180.0 * radtheta) / PI;
return (degtheta);
}
|
Example: Suppose all the coordinates in your object satisfy the equations
and the 'camera' is at ( 8, 9, 10 )
Then the center of the bounding box is (1, 6, 0).
The radius r of a bounding sphere is
the distance from the center of the box to any corner,
, say (3, 7, 5). That is,
| r = ½ size | = | ![]() |
Thus,
| Distance d | = |
|
and
| void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far); |
| Creates a matrix for a symmetric perspective-view frustum and multiplies the current matrix by it. fovy is the angle of the field of view in the y-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 are the distances between the viewpoint and the clipping planes, along the negative z-axis. They should always be positive. |
|
|
| void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); |
| Creates a matrix for an orthographic parallel viewing volume and multiplies the current matrix by it. (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. |
The corresponding transformation matrix for glOrtho(l, r, b, t, n, f ) is:
| void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); |
| Defines a pixel rectangle in the window into which the final image is mapped. The (x, y) parameter specifies the lower-left corner of the viewport, and width and height are the size of the viewport rectangle. By default, the initial viewport values are (0, 0, winWidth, winHeight), where winWidth and winHeight are the size of the window. |
Left Figure:
gluPerspective(fovy, 1.0, near, far); glViewport(0, 0, 400, 400) |
Right Figure:
gluPerspective(fovy, 1.0, near, far); glViewport (0, 0, 400, 200); |
To avoid the distortion, modify the aspect ratio of the projection to match the viewport:
gluPerspective(fovy, 2.0, near, far); glViewport(0, 0, 400, 200); |
The depth (z) coordinate is encoded during the viewport transformation (and later stored in the depth buffer). You can scale z values to lie within a desired range with the glDepthRange() command.
| void glDepthRange(GLclampd near, GLclampd far); |
| Defines an encoding for z coordinates that's performed during the viewport transformation. The near and far values represent adjustments to the minimum and maximum values that can be stored in the depth buffer. By default, they're 0.0 and 1.0, respectively, which work for most applications. These parameters are clamped to lie within [0,1]. |
far side is less precise
either
visible-surface algorithm -- find which surfaces are visible
or
hidden-surface-removal algorithms -- remove those surfaces that should not be visible to the viewer
| void glPushMatrix(void); |
| void glPopMatrix(void); |
| void glMatrixMode( GLenum mode ); | Specifies whether the modelview, projection, or texture matrix will be modified. mode: GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE. |
To examine the transformation matrix:
Example
/*
* cube_mat.cpp
* This program demonstrates examining the transformation matrix values.
*
* A wireframe cube is rendered.
*/
#include <GL/glut.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void init(void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glShadeModel (GL_FLAT);
}
//print the transformation matrix
template<class T>
void print_mat ( T m[][4] )
{
cout.precision ( 4 );
cout << fixed;
for ( int i = 0; i < 4; ++i ) {
cout << "\t";
for ( int j = 0; j < 4; ++j )
cout << m[j][i] << "\t";
cout << endl;
}
cout << endl;
}
void display(void)
{
float p[4][4];
double pd[4][4];
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0.0, 1.0, 0.0); //green color
glLoadIdentity (); // clear the matrix
glMatrixMode (GL_PROJECTION);
// viewing transformation
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_PROJECTION_MATRIX,&p[0][0]);
cout << "Projection Matrix:" << endl;
print_mat ( p );
glGetDoublev(GL_MODELVIEW_MATRIX, &pd[0][0]);
cout << "Modelview Transformation Matrix:" << endl;
print_mat ( pd );
glScalef (1.0, 2.0, 1.0); // modeling transformation
glGetFloatv(GL_MODELVIEW_MATRIX,&p[0][0]);
cout << "Scale Matrix:" << endl;
print_mat ( p );
glRotatef ( 45, 0, 0, 1 );
glGetDoublev(GL_MODELVIEW_MATRIX, &pd[0][0]);
cout << "Scale Rotation Matrix:" << endl;
print_mat ( pd );
glutWireCube (1.0);
glFlush ();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
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);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
|
|
| void glClipPlane(GLenum plane, const GLdouble *equation); |
|
Defines a clipping plane. The equation argument points to the four
coefficients of the plane equation, Ax + By + Cz + D = 0. Clip away
space of Ax + By + Cz + D < 0.
plane is GL_CLIP_PLANEi, where i is an integer specifying which of the available clipping planes to define. |
You need to enable each additional clipping plane you define:
You can disable a plane with
Example: Clipped Wireframe Sphere
|
|
Note again: M2M1 ≠ M1M2
glLoadIdentity(); //M = I glTranslatef(); //M = I.T = T glRotate(); //M = M.R = T.R glScale(); //M = M.S = T.R.S draw_a_point( P ); //Q = M.P = T.R.S.P
Note that the equivalent order of operation on P is : scale, rotate, translate
Suppose we want to rotate an object about a 'z' axis through ( -1, 0, 0 ). We can achieve this by moving everything by 1, do the rotation, and move things back by 1.
Question: Which of the following is correct?
glTranslatef ( 1.0, 0.0, 0.0 ); glRotatef( degrees, 0.0, 0.0, 1.0 ); glTranslatef ( -1.0, 0.0, 0.0 ); draw_object(); |
Or
glTranslatef ( -1.0, 0.0, 0.0 ); glRotatef( degrees, 0.0, 0.0, 1.0 ); glTranslatef ( 1.0, 0.0, 0.0 ); draw_object(); |
Example: Building an Articulated Robot Arm
glTranslatef (-1.0, 0.0, 0.0); glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); glPushMatrix(); glScalef (2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); |
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
glutWireCube (1.0);
glPopMatrix();
|
|
![]() |
Robot Arm with fingers:
Previously, 4th component is either 0 or 1; works well with affine transformations, involving matrix multiplications
Trouble with perspective transformation:
The trick: Consider two sets of coordinates to represent the same point if one is a non-zero multiple of the other --> extending the homogeneous coordinate representation:
The matrix is nonsingular: