Transformation in OpenGL
with Examples |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
gluLookAt()
glTranslate*()
,
glScale*()
, glRotate*()
glOrtho(left, right, bottom, top, near, far)
glFrustum(fovy, aspect, zNear, zFar)
fovy
is the field of view (in degrees)
in the \(y\) direction, aspect
is
the aspect ration that determines the FOV in the
\(x\) direction, zNear
is the positive
distance from the viewer to the near clipping plane, and
zFar
is the positive
distance from the viewer to the far clipping plane
glPushMatrix()
and glPopMatrix()
)
is important and requires careful thought
/** * The display callback */ void display() { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); // Draw the Sun at the origin with a radius of 2, 16 lines of latitude, // and 16 lines of longitude // // Use a wireframe so we can see the orientation glColor3f(1.0, 1.0, 0.0); glutWireSphere(1.0, 16, 16); // Rotate the local coordinate system // around the z-axis based on the day of the year // // Note: After drawing the sphere we are at the origin. So, we // are rotating around a ray from [0 0 0] to [0 0 1]. glRotatef(((GLfloat) day) / 365.0f * 360.0f, 0.0, 0.0, 1.0); // Translate the local coordinate system along the x-axis the // radius of the Earth's orbit // // Note: The x-axis has already been rotated. glTranslatef(4.0, 0.0, 0.0); // To rotate the Moon around the center of the Earth we need // a different local coordinate system. Save the current // local coordinate system first glPushMatrix(); // Rotate the new local coordinate system around the z-axis // based on the day of month glRotatef(((GLfloat) dom) / 28.0f * 360.0f, 0.0, 0.0, 1.0); // Translate the new local coordinate along the x-axis the // radius of the Moon's orbit glTranslatef(1.0, 0.0, 0.0); // Draw the Moon glColor3f(1.0, 1.0, 1.0); glutWireSphere(0.1, 4, 4); // Pop the previous local coordinate system glPopMatrix(); // Rotate the local coordinate system around the z-axis based on // the hour of the day // // Note: The origin is now at the appropriate point on the orbit. glRotatef(((GLfloat) hour) / 24.0f * 360.0f, 0.0, 0.0, 1.0); // Draw the Earth // // Use a wireframe so we can see it revolve glColor3f(0.0, 0.0, 1.0); glutWireSphere(0.5, 16, 16); glPopMatrix(); glFlush(); glutSwapBuffers(); }
/** * The display callback */ void display() { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); // Translate the local coordinate system to the hinge // of the first block glTranslatef(-1.0, 0.0, 0.0); // Rotate the local coordinate system around the z-axis // // Note: We are rotating around a ray to [0 0 1]. glRotatef((GLfloat) alpha, 0.0, 0.0, 1.0); // Translate the local coordinate system back to the center glTranslatef(1.0, 0.0, 0.0); // Draw the first block glutWireCube(2.0); // Translate the local coordinate system to the hinge // of the second block glTranslatef(1.0, 0.0, 0.0); // Rotate the local coordinate system around the z-axis // // Note: We are rotating around a ray to [0 0 1]. glRotatef((GLfloat) beta, 0.0, 0.0, 1.0); // Translate the local coordinate system to the center of the // second block glTranslatef(1.0, 0.0, 0.0); // Draw the second block glutWireCube(2.0); glPopMatrix(); glFlush(); glutSwapBuffers(); }
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <GL/glut.h> /** * \file * An application that displays a first person view of a simple world. * * On Linux, compile with: * g++ -o firstperson -Wall firstperson.c -lglut -lGL -lGLU * * NOTE: The camera/viewer starts in the middle of the world. So, you should * probably move back several times to see everything. * * @author Prof. David Bernstein, James Madison University */ static GLfloat x = 0.0, z = 0.0, angle = 0.0; /** * Convert degrees to radians. * * @param degrees The angle in degrees * @return The angle in radians */ inline GLfloat deg2rad(GLfloat degrees) { return degrees * M_PI / 180.0; } /** * Convert radians to degrees * * @param radians The angle in radians * @return The angle in degrees */ inline GLfloat rad2deg(GLfloat radians) { return radians * (180.0 / M_PI); } /** * Draw the objects in the world. */ void drawWorld() { glColor3f(1.0f, 1.0f, 1.0f); // The "near" side of the world glPushMatrix(); glTranslatef(0.0, 0.0, 5.0); glRotatef(-90.0, 1.0, 0.0, 0.0); glutSolidCone(1.0, 1.0, 10, 10); glPopMatrix(); // The "right" side of the world glPushMatrix(); glTranslatef(5.0, 0.0, 0.0); glutSolidTorus(0.5, 1.0, 10, 10); glPopMatrix(); // The "left" side of the world glPushMatrix(); glTranslatef(-5.0, 0.0, 0.0); glutSolidSphere(1.0, 10, 10); glPopMatrix(); // The "far" side of the world glPushMatrix(); glTranslatef(0.0, 0.0, -5.0); glutSolidTeapot(1.0); glPopMatrix(); } /** * The display callback. */ void display() { glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset the local coordinate system glLoadIdentity(); // Rotate around the y-axis glRotatef(angle, 0.0, 1.0, 0.0); // Translate the local coordinate system "backwards" an // appropriate amount (based on the rotation angle) glTranslatef(-x, 0.0, -z); // Draw the world drawWorld(); glFlush(); glutSwapBuffers(); } /** * Initialize GLUT and OpenGL. */ void init() { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow("First Person"); glClearColor(0.0, 0.0, 0.0, 1.0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Use the default light } /** * Handle keyboard events. */ void keyboard(unsigned char key, int xMouse, int yMouse) { GLfloat deltaX, deltaZ; // Move forward or backward if ((key == 'f') || (key == 'b')) { // Calculate the change in x and z necessary for a 1-unit // move in the direction I am facing deltaX = sin(deg2rad(angle)); deltaZ = cos(deg2rad(angle)); if (key == 'f') { x += deltaX; z -= deltaZ; } else if (key == 'b') { x -= deltaX; z += deltaZ; } } // Rotate right (clockwise) or left (counter-clockwise) else if (key == 'r') { angle += 10.0; if (angle > 360) angle -= 360; } else if (key == 'l') { angle -= 10.0; if (angle < 0) angle += 360; } // Reset else if (key == ' ') { angle = 0.0; x = 0.0; z = 0.0; } glutPostRedisplay(); } /** * The reshape callback (i.e., the function that is called * each time the window is re-sized). * * @param width The new width * @param height The new height */ void reshape(int width, int height) { GLfloat aspect; glViewport(0, 0, (GLsizei) width, (GLsizei) height); // Setup the projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); aspect = (GLfloat) width / (GLfloat) height; gluPerspective(60.0, aspect, 1.0, 1000.0); } /** * The entry point of the application. * * @param argc The number of command line arguments * @param argv The array of command line arguments * @return A status code */ int main(int argc, char **argv) { // Initialize glutInit(&argc, argv); init(); // Callbacks glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); // Start the event loop glutMainLoop(); return 0; }