Open GL Super Bible:3D Modeling and Object Composition
To access the contents, click the chapter and section titles.
Open GL Super Bible
(Publisher: Macmillan Computer Publishing)
Author(s): Waite group Press
ISBN: 1571690735
Publication Date: 08/01/96
Previous
Table of Contents
Next
The Shaft
The shaft of the bolt is nothing more than a cylinder with a bottom on it. We compose a cylinder by plotting xy values around in a circle, and then take two z values at these points and get polygons that approximate the wall of a cylinder. Once again, however, we will compose this wall entirely out of triangles. Figure 10-4 shows the outline of the cylinder.
Figure 10-4 Triangle outline of the bolt shaft
We also create the bottom of the shaft with a triangle fan. Notice that the smaller the step size is around the circle, the smaller the flat facets that make up the cylinder wall and the more closely the wall will approximate a smooth curve.
Listing 10-5 is the code to produce this cylinder. Notice that the normals are not calculated for the triangles using the vertices of the triangles. We usually set the normal to be the same for all vertices, but here wełll break with this tradition to specify a new normal for each vertex. Since we are simulating a curved surface, the normal specified for each vertex would be normal to the actual curve.
Listing 10-5 Rendering the shaft of the bolt
// Creates the shaft of the bolt as a cylinder with one end
// closed.
void RenderShaft(void)
{
float x,y,angle; // Used to calculate cylinder
wall
float height = 75.0f; // Height of the cylinder
float diameter = 20.0f; // Diameter of the cylinder
float normal[3],corners[4][3]; // Storage for vertices
calculations
float step = (3.1415f/50.0f); // Approximate the cylinder
wall with
// 100 flat segments.
// Set material color for head of screw
glColor3f(0.0f, 0.0f, 0.7f);
// counterclockwise polygons face out (the default for triangles)
glFrontFace(GL_CCW);
// First assemble the wall as 100 quadrilaterals formed by
// placing adjoining triangles together
glBegin(GL_TRIANGLES);
// Go around and draw the sides
for(angle = 0.0f; angle < (2.0f*3.1415f); angle += step)
{
// Calculate x and y position of the next vertex
x = diameter*(float)sin(angle);
y = diameter*(float)cos(angle);
// Get the coordinate for this point and extrude the
// length of the cylinder.
corners[0][0] = x;
corners[0][1] = y;
corners[0][2] = -height;
corners[1][0] = x;
corners[1][1] = y;
corners[1][2] = 0.0f;
// Get the next point and do the same
x = diameter*(float)sin(angle+step);
y = diameter*(float)cos(angle+step);
// If finished, use known starting point to close the
surface
if(angle+step < 3.1415*2.0) // Not Finished
{
corners[2][0] = x;
corners[2][1] = y;
corners[2][2] = 0.0f;
corners[3][0] = x;
corners[3][1] = y;
corners[3][2] = -height;
}
else
{
// Finished, use the starting point
corners[2][0] = 0.0f;
corners[2][1] = diameter;
corners[2][2] = 0.0f;
corners[3][0] = 0.0f;
corners[3][1] = diameter;
corners[3][2] = -height;
}
// Instead of using real normal to actual flat section,
// use what the normal would be if the surface were really
// curved. Since the cylinder goes up the z axis, the normal
// points from the z axis out directly through each vertex.
// Therefore we can use the vertex as the normal, as long as
// we reduce it to unit length first.
// First Triangle ////////////////////////////////////////
// Fill the normal vector with the coordinate points
normal[0] = corners[0][0];
normal[1] = corners[0][1];
normal[2] = corners[0][2];
// Reduce to length of one and specify for this point
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[0]);
// Get vertex, calculate unit normal and go
normal[0] = corners[1][0];
normal[1] = corners[1][1];
normal[2] = corners[1][2];
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[1]);
// Get vertex, calculate unit normal and go
normal[0] = corners[2][0];
normal[1] = corners[2][1];
normal[2] = corners[2][2];
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[2]);
// Second Triangle ////////////////////////////////////////
// Get vertex, calculate unit normal and go
normal[0] = corners[2][0];
normal[1] = corners[2][1];
normal[2] = corners[2][2];
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[2]);
// Get vertex, calculate unit normal and go
normal[0] = corners[3][0];
normal[1] = corners[3][1];
normal[2] = corners[3][2];
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[3]);
// Get vertex, calculate unit normal and go
normal[0] = corners[0][0];
normal[1] = corners[0][1];
normal[2] = corners[0][2];
ReduceToUnit(normal);
glNormal3fv(normal);
glVertex3fv(corners[0]);
}
glEnd(); // Done with cylinder sides
// Begin a new triangle fan to cover the bottom
glBegin(GL_TRIANGLE_FAN);
// Normal points down the z axis
glNormal3f(0.0f, 0.0f, -1.0f);
// Center of fan is at the origin
glVertex3f(0.0f, 0.0f, -height);
// Spin around, matching step size of cylinder wall
for(angle = 0.0f; angle < (2.0f*3.1415f); angle += step)
{
// Calculate x and y position of the next vertex
x = diameter*(float)sin(angle);
y = diameter*(float)cos(angle);
// Specify the next vertex for the triangle fan
glVertex3f(x, y, -height);
}
// Close the fan
glVertex3f(0.0f, diameter, -height);
glEnd();
}
Fortunately, the cylinder is wrapped symmetrically around the z-axis. Thus, the normal for each vertex can be found by normalizing (reducing to length 1) the vertex itself. Figure 10-5 shows the output from the SHAFT program.
Figure 10-5 Output from the SHAFT program
Previous
Table of Contents
Next
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.
Wyszukiwarka
Podobne podstrony:
323 326326 32721 (323)bizuteria;slubna,kategoria,323AMP E 323więcej podobnych podstron