0% found this document useful (0 votes)
28 views3 pages

OpenGL 3D Animation Example

This document contains code for rendering 3D shapes with animation in OpenGL. It defines functions to initialize OpenGL, display rotating 3D objects including a cube and pyramid, handle window redraw events, and set up a timer to continuously redraw and update the rotation angles. The main function initializes GLUT and registers callbacks for display, reshape, and a timer to trigger redraws and animate the rotations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views3 pages

OpenGL 3D Animation Example

This document contains code for rendering 3D shapes with animation in OpenGL. It defines functions to initialize OpenGL, display rotating 3D objects including a cube and pyramid, handle window redraw events, and set up a timer to continuously redraw and update the rotation angles. The main function initializes GLUT and registers callbacks for display, reshape, and a timer to trigger redraws and animate the rotations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

/*

* [Link]: 3D Shapes with animation


*/

#include <GL/glut.h> // GLUT, include glu.h and gl.h

/* Global variables */
char title[] = "3D Shapes with animation";
GLfloat anglePyramid = 0.0f; // Rotational angle for pyramid [NEW]
GLfloat angleCube = 0.0f; // Rotational angle for cube [NEW]
int refreshMills = 15; // refresh interval in milliseconds [NEW]

/* Initialize OpenGL Graphics */


void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and
opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective
corrections
}

/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth
buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix

// Render a color-cube consisting of 6 quads with different colors


glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glRotatef(angleCube, 1.0f, 1.0f, 1.0f); // Rotate about (1,1,1)-axis [NEW]

glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads


// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);

// Bottom face (y = -1.0f)


glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);

// Front face (z = 1.0f)


glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);

// Left face (x = -1.0f)


glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);

// Right face (x = 1.0f)


glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube

// Render a pyramid consists of 4 triangles


glLoadIdentity(); // Reset the model-view matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move left and into the screen
glRotatef(anglePyramid, 1.0f, 1.0f, 0.0f); // Rotate about the (1,1,0)-axis
[NEW]

glBegin(GL_TRIANGLES); // Begin drawing the pyramid with 4 triangles


// Front
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);

// Right
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);

// Back
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f);

// Left
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f);
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f);
glEnd(); // Done drawing the pyramid

glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)

// Update the rotational angle after each refresh [NEW]


anglePyramid += 0.2f;
angleCube -= 0.15f;
}

/* Called back when timer expired [NEW] */


void timer(int value) {
glutPostRedisplay(); // Post re-paint request to activate display()
glutTimerFunc(refreshMills, timer, 0); // next timer call milliseconds later
}

/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;

// Set the viewport to cover the new window


glViewport(0, 0, width, height);

// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}

/* Main function: GLUT runs as a console application starting at main() */


int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint
event
glutReshapeFunc(reshape); // Register callback handler for window re-size
event
initGL(); // Our own OpenGL initialization
glutTimerFunc(0, timer, 0); // First timer call immediately [NEW]
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}

Common questions

Powered by AI

The primary transformations applied to the 3D cube are translation and rotation. First, the cube is translated along the X-axis by 1.5f and moved into the screen by -7.0f along the Z-axis, which positions it within the viewable area of the scene . Then, the cube is rotated using the 'glRotatef' function around the (1,1,1) axis, which is a diagonal axis through the cube's volume. This rotation is continuously updated after each frame by decrementing the angle by 0.15f, creating an animated effect . These transformations contribute to the visualization by ensuring that the cube is visible to the observer from different perspectives as it rotates.

The rotational angles for the pyramid and the cube are updated differently, with 'anglePyramid' being incremented by 0.2f and 'angleCube' decremented by 0.15f after each frame . This difference in update rates causes the pyramid to rotate in a positive direction more prominently and swiftly than the cube, which rotates more slowly and in the opposite direction. Consequently, this variation creates distinct visual animations for each shape, enhancing the overall dynamism of the scene as both objects animate at different speeds and directions.

Defining vertices in counter-clockwise order is crucial as it determines the front face of each polygon in OpenGL. This allows the graphics system to correctly compute face normals for lighting calculations and perform back-face culling, improving rendering efficiency. In the source code, this is implemented in functions like 'glBegin(GL_QUADS)', where each face of the cube is specified with vertices listed in a counter-clockwise sequence, e.g., 'glVertex3f(1.0f, 1.0f, -1.0f)' through 'glVertex3f(1.0f, -1.0f, -1.0f)' for the right face . This systematic ordering ensures correct rendering and culling operations for the 3D object.

A perspective projection is chosen over orthographic projection because it mimics real-world vision, where objects appear smaller as they are further away, adding realism to the 3D scene. This is especially useful in animations, as it enhances the depth perception of rotating objects. In the program, perspective projection is set up using 'gluPerspective', which specifies the field of view angle (45.0f), the aspect ratio, and distance specifications for the near and far clipping planes (0.1f and 100.0f, respectively). This configuration creates a frustum-shaped viewing volume, providing realistic rendering of the animated shapes.

Depth testing is significant in this OpenGL program because it ensures that objects are rendered with their correct spatial relationships, avoiding visual artifacts where objects that should be occluded are mistakenly drawn on top. Depth testing is implemented by calling 'glEnable(GL_DEPTH_TEST)', which activates the depth buffer. By setting the depth function with 'glDepthFunc(GL_LEQUAL)', the program determines whether a pixel should be drawn based on its depth value relative to another . This allows for accurate rendering of overlapping objects, especially when animating 3D shapes like the pyramid and the cube.

Enabling smooth shading with 'glShadeModel(GL_SMOOTH)' influences the rendered graphics by interpolating the colors of vertices across the surface of polygons, resulting in a smooth transition between colors. In this OpenGL program, it enhances visual realism by preventing abrupt changes in color and lighting across surfaces, providing a more natural and appealing look on the 3D objects . For example, the gradients on the faces of shapes due to lighting changes appear smoother, contributing to a more polished visual effect.

The use of a double buffering mechanism in the OpenGL program offers several advantages, primarily eliminating flickering during animations. 'glutInitDisplayMode(GLUT_DOUBLE)' sets double buffering, where one buffer is used for rendering the current frame while the other stores the upcoming frame. After rendering completion, 'glutSwapBuffers()' swaps them, making transitions seamless . This mechanism allows drawing operations to complete in background (back buffer), not visible to the user until swapping occurs, leading to smoother animations devoid of visible rendering anomalies and providing a higher-quality visual experience.

The use of colors in the OpenGL program enhances visualization by making each face of the 3D shapes distinct and easily identifiable. Different colors are assigned to different faces of both the cube and the pyramid, such as green for the top face and orange for the bottom face of the cube . This color differentiation helps viewers perceive depth and orientation of the 3D shapes more clearly by providing visual cues, thus making the scene more interesting and easy to understand.

The 'glutTimerFunc' function sets up a mechanism for timing, allowing the continuous updating and refreshing of the animation frames. It schedules the next timer event by specifying the refresh rate in milliseconds and invokes a callback function, 'timer', once the specified period has elapsed . Within the 'timer' function, 'glutPostRedisplay' is called to request a redraw of the window, triggering the display function that updates the angles for both the pyramid and cube, thus contributing to the animation effect. This creates the appearance of smooth animation by regularly updating the scene.

The design of the 'display' function is pivotal to the functionality of the OpenGL animation as it handles rendering the 3D shapes and updating their transformations. Within 'display', the function first clears the color and depth buffers to prepare for new frame rendering, ensuring no remnants from previous frames interfere . It then sets the matrix mode and resets transformations with 'glLoadIdentity', positioning each shape in the scene through translations, followed by applying rotation using 'glRotatef'. By executing 'glutSwapBuffers' at the end, the function swaps the buffers, allowing for smooth, flicker-free animation. This cyclic approach effectively renders frames in an orderly fashion for real-time animations.

You might also like