OpenGL III: Moving and rotating 3D shapes (Views: 302)
Problem/Question/Abstract: In this article I'll show you how to create 3D shapes, which is just an extension of the last article, also you'll see how to rotate around the same shape axis or rotate around other object (like the solar system) Answer: Ok, this is the 3rd of a series of articles on OpenGL, so far we have seen: OpenGL I: Hello World, Setup a Delphi OpenGL Application OpenGL II: Moving and rotating 2D shapes Now we're gonna expand on the last article to create 3D shapes, rotate them around their own axis and rotating objects around some other object (like a solar system) To accomplish such thing we're still going to use the same basic OpenGL instructions but because this is graphics, one line in the wrong place makes a huge difference As I stated in my last article, OpenGL just follows instructions like "move forward", "turn left X degrees", etc, so just with that you know is not the same: "move forward 10 units", "turn left 90 degrees" than: "turn left 90 degrees", "move forward 10 units" simple, right?? well, just those simple rules will make a difference when you want to rotate an object around it's own axis or around other object axis Rotating in the object own axis would be something like: "move to 0, 0, 0", "move forward 10 units", "turn left X degrees", "draw a shape", "inc(X, 1.0)" very simple, we move to a fixed position (10 units forward) turn X degrees, X gets incremented later, so that makes the shape rotate around its own axis and then we draw the shape, and increment the angle In Delphi would be something like: glTranslatef(-0.5, 0.0, -15.0); // Move 0.5 Units Left And 15.0 units Into The Screen glRotatef(rquad, 0.0, 1.0, 1.0); // Rotate The Quad On The Y and Z axis ( NEW ) glBegin(GL_QUADS); // We are going to draw a cube, so let's use QUADS glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.5, -0.5); // Top Left glVertex3f(-0.5, 0.5, -0.5); // Top Right {. . .} glEnd(); rquad := rquad + 1.0; Now to rotate around that object we just drew, we would have to do the following: "cancel previous rotation", "turn left X degrees", "move 3 units into screen", "turn right Y degrees", "draw shape" The first important thing to notice here is that we didn't use "move 0, 0, 0", which means we're going to keep drawing from the position where we drew the last shape The second thing is cancelling the previous rotation, why is that? Because if you don't, when you move forward X units, is going to move into whatever direction the last angle was, that might be what you want, but if you want your shape to rotate in a different axis, then you have to cancel the rotation, and then rotate to where you want and then move... confusing? luckily you'll get to play with the source code and see what happens when you cancel and when you don't. The third thing is rotating to the angle that you want (this actually makes the rotation around the first object posible) Move 3 units into screen, This to separate the new shape from the last, if we don't move to any direction, we will draw this shape in the same place!, maybe rotated to a different angle but in the same coordinates Finally we do a last rotation around a new variable angle and draw the shape. This last rotation will make the new object rotate around it's own axis just like the solar system, the earth rotates around the sun, and then also rotates around it's own axis, makes sense? I hope so let's look at the Delphi code: //Notice we don't use glLoadIdentity here, which means we are at whatever position we drew the quad glRotatef(-rquad, 0.0, 1.0, 1.0); // Cancel the previous rotation!!! glRotatef(rtri, 0.0, 1.0, 0.0); // Rotate The Triangle On The Y axis (around the quad) glTranslatef(0.0, 0.0, 3.0); // Move 3.0 Units Into The screen glRotatef(rtri, 0.0, 0.0, 1.0); // Let's rotate the pyramid, while we rotate around the quad glBegin(GL_TRIANGLES); // We're gonna draw a pyramid, so let's use TRIANGLES glColor3f(1.0, 0.0, 0.0); // Red glVertex3f(0.0, 0.5, 0.0); // Top Of Triangle (Front) {. . .} glEnd(); rtri := rtri + 2.0; ok, that's it on explanations, here's the source code for the drawing procedure I added a polygon to the scene just to show you how to create them Also check the coloring mix on the pyramid function DrawGLScene(): Bool; { All Rendering Done Here } begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Clear Screen and Depth Buffer glLoadIdentity(); //Reset The View glTranslatef(-0.5, 0.0, -15.0); // Move 0.5 Units Left And 15.0 units Into The Screen glRotatef(rquad, 0.0, 1.0, 1.0); // Rotate The Quad On The Y and Z axis ( NEW ) glBegin(GL_QUADS); // We are going to draw a cube, so let's use QUADS glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.5, -0.5); // Top Left glVertex3f(-0.5, 0.5, -0.5); // Top Right glVertex3f(-0.5, 0.5, 0.5); // Bottom Right glVertex3f(0.5, 0.5, 0.5); // Bottom Left glColor3f(1.0, 0.5, 0.0); glVertex3f(0.5, -0.5, -0.5); // Top Left glVertex3f(-0.5, -0.5, -0.5); // Top Right glVertex3f(-0.5, -0.5, 0.5); // Bottom Right glVertex3f(0.5, -0.5, 0.5); // Bottom Left glColor3f(1.0, 0.0, 0.0); glVertex3f(0.5, 0.5, 0.5); // Top Left glVertex3f(-0.5, 0.5, 0.5); // Top Right glVertex3f(-0.5, -0.5, 0.5); // Bottom Right glVertex3f(0.5, -0.5, 0.5); // Bottom Left glColor3f(1.0, 1.0, 0.0); glVertex3f(0.5, -0.5, -0.5); // Top Left glVertex3f(-0.5, -0.5, -0.5); // Top Right glVertex3f(-0.5, 0.5, -0.5); // Bottom Right glVertex3f(0.5, 0.5, -0.5); // Bottom Left glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); // Top Left glVertex3f(-0.5, 0.5, -0.5); // Top Right glVertex3f(-0.5, -0.5, -0.5); // Bottom Right glVertex3f(-0.5, -0.5, 0.5); // Bottom Left glColor3f(1.0, 0.0, 1.0); glVertex3f(0.5, 0.5, -0.5); // Top Left glVertex3f(0.5, 0.5, 0.5); // Top Right glVertex3f(0.5, -0.5, 0.5); // Bottom Right glVertex3f(0.5, -0.5, -0.5); // Bottom Left glEnd(); //Notice we don't use glLoadIdentity here, which means we are at whatever position we drew the quad glRotatef(-rquad, 0.0, 1.0, 1.0); // Cancel the previous rotation!!! glRotatef(rtri, 0.0, 1.0, 0.0); // Rotate The Triangle On The Y axis (around the quad) glTranslatef(0.0, 0.0, 3.0); // Move 3.0 Units Into The screen glRotatef(rtri, 0.0, 0.0, 1.0); // Let's rotate the pyramid, while we rotate around the quad glBegin(GL_TRIANGLES); // We're gonna draw a pyramid, so let's use TRIANGLES glColor3f(1.0, 0.0, 0.0); // Red glVertex3f(0.0, 0.5, 0.0); // Top Of Triangle (Front) glColor3f(0.0, 1.0, 0.0); // Green glVertex3f(-0.5, -0.5, 0.5); // Left Of Triangle (Front) glColor3f(0.0, 0.0, 1.0); // Blue glVertex3f(0.5, -0.5, 0.5); // Right Of Triangle (Front) glColor3f(1.0, 0.0, 0.0); // Red glVertex3f(0.0, 0.5, 0.0); // Top Of Triangle (Right) glColor3f(0.0, 0.0, 1.0); // Blue glVertex3f(0.5, -0.5, 0.5); // Left Of Triangle (Right) glColor3f(0.0, 1.0, 0.0); // Green glVertex3f(0.5, -0.5, -0.5); // Right Of Triangle (Right) glColor3f(1.0, 0.0, 0.0); // Red glVertex3f(0.0, 0.5, 0.0); // Top Of Triangle (Back) glColor3f(0.0, 1.0, 0.0); // Green glVertex3f(0.5, -0.5, -0.5); // Left Of Triangle (Back) glColor3f(0.0, 0.0, 1.0); // Blue glVertex3f(-0.5, -0.5, -0.5); // Right Of Triangle (Back) glColor3f(1.0, 0.0, 0.0); // Red glVertex3f(0.0, 0.5, 0.0); // Top Of Triangle (Left) glColor3f(0.0, 0.0, 1.0); // Blue glVertex3f(-0.5, -0.5, -0.5); // Left Of Triangle (Left) glColor3f(0.0, 1.0, 0.0); // Green glVertex3f(-0.5, -0.5, 0.5); // Right Of Triangle (Left) glEnd(); glLoadIdentity(); // Move to (0, 0, 0) glTranslatef(1.5, 0.0, -6.0); // Move 1.5 Right and -6.0 intro screen glRotatef(rpol, 0.0, 0.0, 1.0); // rotate on Z axis glColor3f(0.0, 0.0, 1.0); // Add some color glBegin(GL_POLYGON); // Draw A Polygon (I can put many points in here) glVertex3f(-0.5, 0.5, 0.0); // Top Left glVertex3f(0.0, 0.75, 0.0); // Upper point glVertex3f(0.5, 0.5, 0.0); // Top Right glVertex3f(0.5, -0.5, 0.0); // Bottom Right glVertex3f(0.0, -0.75, 0.0); // Lower point glVertex3f(-0.5, -0.5, 0.0); // Bottom Left glEnd(); rtri := rtri + 2.0; rquad := rquad + 1.0; rpol := rpol + 1.0; Result := True end; That's it, I hope it wasn't too confusing, play with the code, see what happens when you comment this or that line. |