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
Displaying the Results
Once we have determined the viewing, lighting, and material parameters, all that remains is to render the scene. Listing 10-3 shows the code outline used to display our bolt and bolt pieces. The SomeFunc() line is just a placeholder for function calls to render the head, shaft, and threads individually. We save the matrix state, perform any rotations (defined by the keyboard activity, as in all this bookłs previous examples), and call a function that renders some specific object or part of an object.
Listing 10-3 Rendering the object, allowing for rotated views
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save the matrix state
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Rotate about x and y axes
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
// Specific code to draw the object
SomeFunc(); // Place Holder
glPopMatrix();
// Flush drawing commands
glFlush();
}
Constructing a Model, One Piece at a Time
Any given programming task can be separated into smaller, more manageable tasks. This makes the smaller pieces easier to handle and code, and introduces some reusability into our code base, as well. Three-dimensional modeling is no exception, you will create large complex systems out of many smaller and more manageable pieces.
We have decided to break the bolt down into three pieces: head, shaft, and thread. Certainly this makes it much simpler for us to consider each section graphically, but it also give us three objects that we can reuse. In more complex modeling applications, this reusability is of crucial importance. In a CAD-type application, for example, you would probably have many different bolts to modelwith various lengths, thickness, and thread density. Instead of the RenderHead() function that draws the head of the bolt in this example, you might want to write a function that takes parameters specifying the number of sides, thickness, and diameter of the bolt head.
Another thing we will do is model each piece of our bolt in coordinates that are most convenient for describing the object. Most often, objects are modeled around the origin and then translated and rotated into place. Later, when composing the final object, we can translate the components, rotate them, and even scale them if necessary to assemble our composite object.
The Head
The head of our bolt has six smooth sides and is smooth on top and bottom, as well. We can construct this solid object with two hexagons that represent the top and bottom of the head, and a series of quadrilaterals around the edges to represent the sides. We could use GL_QUAD and GL_POLYGON to draw this with a minimum number of vertices; however, as wełve mentioned previously, you should always use triangles whenever possible. For any accelerated OpenGL hardware (and even some software routines), it may actually be faster to draw two triangles arranged together rather than a single quadrilateral.
Figure 10-2 illustrates how the bolt head will be constructed with triangles. We use a triangle fan with six triangles for the top and bottom sections of the head. Then each face of the side of the bolt is composed of two triangles.
Figure 10-2 Triangle outline of bolt head
A total of 24 triangles are used to draw the head of the bolt: 6 each on the top and bottom, and 12 more to compose the sides of the bolt head. Listing 10-4 is the function that renders the head of the bolt. Figure 10-3 shows the output of this program, HEAD, in this chapterłs subdirectory on the CD. Notice that this code contains no functions that we havenłt yet covered, but itłs more substantial than any of the simpler chapter examples.
Figure 10-3 Output from the HEAD program
Listing 10-4 Rendering the head of the bolt
// Creates the head of the bolt
void RenderHead(void)
{
float x,y,angle; // Calculated positions
float height = 25.0f; // Thickness of the head
float diameter = 30.0f; // Diameter of the head
float normal[3],corners[4][3]; // Storage of vertices and normals
float step = (3.1415f/3.0f); // step = 1/6th of a circle =
hexagon
// Set material color for head of bolt
glColor3f(0.0f, 0.0f, 0.7f);
// Clockwise polygons face out, set for fans
glFrontFace(GL_CW);
// Begin a new triangle fan to cover the top
glBegin(GL_TRIANGLE_FAN);
// All the normals for the top of the bolt point straight up
// the z axis.
glNormal3f(0.0f, 0.0f, 1.0f);
// Center of fan is at the origin
glVertex3f(0.0f, 0.0f, 0.0f);
// Divide the circle up into 6 sections and start dropping
// points to specify the fan
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, 0.0f);
}
// Last vertex closes the fan
glVertex3f(0.0f, diameter, 0.0f);
// Done drawing the fan that covers the bottom
glEnd();
// Now draw the bottom of the bolt head. Switch to
// clockwise polygons facing out.
glFrontFace(GL_CCW);
// Begin a new triangle fan to cover the bottom
glBegin(GL_TRIANGLE_FAN);
// Normal for bottom points straight down the negative z axis
glNormal3f(0.0f, 0.0f, -1.0f);
// Center of fan is at the origin
glVertex3f(0.0f, 0.0f, -height);
// Divide the circle up into 6 sections and start dropping
// points to specify the fan
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);
}
// Last vertex, used to close the fan
glVertex3f(0.0f, diameter, -height);
// Done drawing the fan that covers the bottom
glEnd();
// Build the sides out of triangles (two each). Each face
// will consist of two triangles arranged to form a
// quadrilateral
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 hex point
x = diameter*(float)sin(angle);
y = diameter*(float)cos(angle);
// start at bottom of head
corners[0][0] = x;
corners[0][1] = y;
corners[0][2] = -height;
// extrude to top of head
corners[1][0] = x;
corners[1][1] = y;
corners[1][2] = 0.0f;
// Calculate the next hex point
x = diameter*(float)sin(angle+step);
y = diameter*(float)cos(angle+step);
// Make sure we aren't done before proceeding
if(angle+step < 3.1415*2.0)
{
// If we are done, just close the fan at a
// known coordinate.
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
{
// We aren't done, the points at the top
and bottom
// of the head.
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;
}
// The normal vectors for the entire face will
// all point the same direction
calcNormal(corners, normal);
glNormal3fv(normal);
// Specify each triangle separately to lie next
// to each other.
glVertex3fv(corners[0]);
glVertex3fv(corners[1]);
glVertex3fv(corners[2]);
glVertex3fv(corners[0]);
glVertex3fv(corners[2]);
glVertex3fv(corners[3]);
}
glEnd();
}
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:
21 (323)323 32607 (318)318 (B2006) Koszty działalności operacyjnej w kalkulacyjnym rachunku zysków i stratwroclaw,firmy m,318bizuteria;slubna,kategoria,323więcej podobnych podstron