Expanding on the last tutorial, we'll now make the object into TRUE 3D object, rather than 2D objects in a 3D world. We
will do this by adding a left, back, and right side to the triangle, and a left, right, back, top and bottom to the square.
By doing this, we turn the triangle into a pyramid, and the square into a cube.
We'll blend the colors on the pyramid, creating a smoothly colored object, and for the square we'll color each face a
different color.
GLvoid DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left And Into The Screen
glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Pyramid On It's Y Axis
glBegin(GL_POLYGON); // Start Drawing The Pyramid
A few of you have taken the code from the last tutorial, and made 3D objects of your own. One thing I've been asked quite
a bit is "how come my objects are not spinning on their axis? It seems like they are spinning all over the screen". In
order for your object to spin around an axis, it has to be designed AROUND that axis. You have to remember that the
center of any object should be 0 on the X, 0 on the Y, and 0 on the Z.
The following code will create the pyramid around a central axis. The top of the pyramid is one high from the center, the
bottom of the pyramid is one down from the center. The top point is right in the middle (zero), and the bottom points are
one left from center, and one right from center.
Note that all polygons are drawn in a counterclockwise rotation. This is important, and will be explained in a future
tutorial, for now, just know that it's good practice to make objects either clockwise or counterclockwise, but you
shouldn't mix the two unless you have a reason to.
We start off by drawing the Front Face. Because all of the faces share the top point, we will make this point red on all
of the triangles. The color on the bottom two points of the triangles will alternate. The front face will have a green
left point and a blue right point. The the triangle on the right side will have a blue left point and a green right
point. By alternating the bottom two colors on each face, we make a common colored point at the bottom of each face.
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
Now we draw the right face. Notice the the two bottom point are drawn one to the right of center, and the top point is
drawn one up on the y axis, and right in the middle of the x axis. causing the face to slope from center point at the
top out to the right side of the screen at the bottom.
Notice the left point is drawn blue this time. By drawing it blue, it will be the same color as the right bottom corner
of the front face. Blending blue outwards from that one corner across both the front and right face of the pyramid.
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
Now for the back face. Again the colors switch. The left point is now green again, because the corner it shares with the
right face is green.
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
Finally we draw the left face. The colors switch one last time. The left point is blue, and blends with the right
point of the back face. The right point is green, and blends with the left point of the front face.
We're done drawing the pyramid. Because the pyramid only spins on the Y axis, we will never see the bottom, so there is
no need to put a bottom on the pyramid. If you feel like experimenting, try adding a bottom using a quad, then rotate
on the X axis to see if you've done it correctly. Make sure the color used on each corner of the quad matches up with
the colors being used at the four corners of the pyramid.
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd(); // Done Drawing The Pyramid
Now we'll draw the cube. It's made up of six quads. All of the quads are drawn in a counter clockwise order. Meaning
the first point is the top right, the second point is the top left, third point is bottom left, and finally bottom right.
When we draw the back face, it may seem as though we are drawing clockwise, but you have to keep in mind that if we were
behind the cube looking at the front of it, the left side of the screen is actually the right side of the quad, and
the right side of the screen would actually be the left side of the quad.
Notice we move the cube a little further into the screen in this lesson. By doing this, the size of the cube appears
closer to the size of the pyramid. If you were to move it only 6 units into the screen, the cube would appear much
larger than the pyramid, and parts of it might get cut off by the sides of the screen. You can play around with this
setting, and see how moving the cube further into the screen makes it appear smaller, and moving it closer makes it appear
larger. The reason this happens is perspective. Objects in the distance should appear smaller :)
glLoadIdentity();
glTranslatef(1.5f,0.0f,-7.0f); // Move Right And Into The Screen
glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Cube On X, Y & Z
glBegin(GL_QUADS); // Start Drawing The Cube
We'll start off by drawing the top of the cube. We move up one unit from the center of the cube. Notice that the Y axis
is always one. We then draw a quad on the Z plane. Meaning into the screen. We start off by drawing the top right point
of the top of the cube. The top right point would be one unit right, and one unit into the screen. The second point
would be one unit to the left, and unit into the screen. Now we have to draw the bottom of the quad towards the viewer.
so to do this, instead of going into the screen, we move one unit towards the screen. Make sense?
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Blue
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
The bottom is drawn the exact same way as the top, but because it's the bottom, it's drawn down one unit from the center
of the cube. Notice the Y axis is always minus one. If we were under the cube, looking at the quad that makes the
bottom, you would notice the top right corner is the corner closest to the viewer, so instead of drawing in the distance
first, we draw closest to the viewer first, then on the left side closest to the viewer, and then we go into the screen
to draw the bottom two points.
If you didn't really care about the order the polygons were drawn in (clockwise or not), you could just copy the same
code for the top quad, move it down on the Y axis to -1, and it would work, but ignoring the order the quad is drawn in
can cause weird results once you get into fancy things such as texture mapping.
glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
Now we draw the front of the Quad. We move one unit towards the screen, and away from the center to draw the front face.
Notice the Z axis is always one. In the pyramid the Z axis was not always one. At the top, the Z axis was zero. If you
tried changing the Z axis to zero in the following code, you'd notice that the corner you changed it on would slope into
the screen. That's not something we want to do right now :)
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
The back face is a quad the same as the front face, but it's set deeper into the screen. Notice the Z axis is now minus
one for all of the points.
glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
Now we only have two more quads to draw and we're done. As usual, you'll notice one axis is always the same for all the
points. In this case the X axis is always minus one. That's because we're always drawing to the left of center because
this is the left face.
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
This is the last face to complete the cube. The X axis is always one. Drawing is counter clockwise. If you wanted to,
you could leave this face out, and make a box :)
Or if you felt like experimenting, you could always try changing the color of each point on the cube to make it blend the
same way the pyramid blends. You can see an example of a blended cube by downloading Evil's first GL demo from my web
page. Run it and press TAB. You'll see a beautifully colored cube, with colors flowing across all the faces.
glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
rtri+=0.2f; // Increase The Rotation Variable For The Triangle
rquad-=0.15f; // Decrease The Rotation Variable For The Quad
}
By the end of this tutorial, you should have a better understanding of how objects are created in 3D space. You have to
think of the OpenGL screen as a giant piece of graph paper, with many transparent layers behind it. Almost like a giant
cube made of of points. Some of the points move left to right, some move up and down, and some move further back in the
cube. If you can visualize the depth into the screen, you shouldn't have any problems designing new 3D objects.
If you're having a hard time understanding 3D space, don't get frustrated. It can be difficult to grasp right off the
start. An object like the cube is a good example to learn from. If you notice, the back face is drawn exactly the same
as the front face, it's just further into the screen. Play around with the code, and if you just can't grasp it, email
me, and I'll try to answer your questions.
Jeff Molofee (NeHe)
* DOWNLOAD Visual C++ Code For This Lesson.
* DOWNLOAD Visual Fortran Code For This Lesson.
( Conversion by Jean-Philippe Perois )
* DOWNLOAD Delphi Code For This Lesson.
( Conversion by Brad Choate )
* DOWNLOAD Linux Code For This Lesson.
( Conversion by Richard Campbell )
* DOWNLOAD Irix Code For This Lesson.
( Conversion by Lakmal Gunasekara )
* DOWNLOAD Solaris Code For This Lesson.
( Conversion by Lakmal Gunasekara )
* DOWNLOAD Mac OS Code For This Lesson.
( Conversion by Anthony Parker )
* DOWNLOAD Power Basic Code For This Lesson.
( Conversion by Angus Law )
* DOWNLOAD BeOS Code For This Lesson.
( Conversion by Chris Herborth )
* DOWNLOAD Java Code For This Lesson.
( Conversion by Darren Hodges )