Выбрать главу

 gluSphere(q, 0.2f, 16, 8); // Draw A Little Yellow Sphere (Represents Light)

 glEnable(GL_LIGHTING); // Enable Lighting

 glDepthMask(GL_TRUE); // Enable Depth Mask

The last part updates the object's position and returns.

 xrot += xspeed; // Increase xrot By xspeed

 yrot += yspeed; // Increase yrot By yspeed

 glFlush(); // Flush The OpenGL Pipeline

 return TRUE; // Everything Went OK

}

We did specify a DrawGLRoom function, and here it is — a bunch of rectangles to cast shadows against:

void DrawGLRoom() // Draw The Room (Box)

{

 glBegin(GL_QUADS); // Begin Drawing Quads

  // Floor

  glNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up

  glVertex3f(-10.0f,-10.0f,-20.0f); // Back Left

  glVertex3f(-10.0f,-10.0f, 20.0f); // Front Left

  glVertex3f( 10.0f,-10.0f, 20.0f); // Front Right

  glVertex3f( 10.0f,-10.0f,-20.0f); // Back Right

  // Ceiling

  glNormal3f(0.0f,-1.0f, 0.0f); // Normal Point Down

  glVertex3f(-10.0f, 10.0f, 20.0f); // Front Left

  glVertex3f(-10.0f, 10.0f,-20.0f); // Back Left

  glVertex3f( 10.0f, 10.0f,-20.0f); // Back Right

  glVertex3f( 10.0f, 10.0f, 20.0f); // Front Right

  // Front Wall

  glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Away From Viewer

  glVertex3f(-10.0f, 10.0f,-20.0f); // Top Left

  glVertex3f(-10.0f,-10.0f,-20.0f); // Bottom Left

  glVertex3f( 10.0f,-10.0f,-20.0f); // Bottom Right

  glVertex3f( 10.0f, 10.0f,-20.0f); // Top Right

  // Back Wall

  glNormal3f(0.0f, 0.0f,-1.0f); // Normal Pointing Towards Viewer

  glVertex3f( 10.0f, 10.0f, 20.0f); // Top Right

  glVertex3f( 10.0f,-10.0f, 20.0f); // Bottom Right

  glVertex3f(-10.0f,-10.0f, 20.0f); // Bottom Left

  glVertex3f(-10.0f, 10.0f, 20.0f); // Top Left

  // Left Wall

  glNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right

  glVertex3f(-10.0f, 10.0f, 20.0f); // Top Front

  glVertex3f(-10.0f,-10.0f, 20.0f); // Bottom Front

  glVertex3f(-10.0f,-10.0f,-20.0f); // Bottom Back

  glVertex3f(-10.0f, 10.0f,-20.0f); // Top Back

  // Right Wall

  glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left

  glVertex3f( 10.0f, 10.0f,-20.0f); // Top Back

  glVertex3f( 10.0f,-10.0f,-20.0f); // Bottom Back

  glVertex3f( 10.0f,-10.0f, 20.0f); // Bottom Front

  glVertex3f( 10.0f, 10.0f, 20.0f); // Top Front

 glEnd(); // Done Drawing Quads

}

And before I forget, here is the VMatMult function which multiplies a vector by a matrix (get that Math textbook out again!):

void VMatMult(GLmatrix16f M, GLvector4f v) {

 GLfloat res[4]; // Hold Calculated Results

 res[0]=M[ 0]*v[0]+M[ 4]*v[1]+M[ 8]*v[2]+M[12]*v[3];

 res[1]=M[ 1]*v[0]+M[ 5]*v[1]+M[ 9]*v[2]+M[13]*v[3];

 res[2]=M[ 2]*v[0]+M[ 6]*v[1]+M[10]*v[2]+M[14]*v[3];

 res[3]=M[ 3]*v[0]+M[ 7]*v[1]+M[11]*v[2]+M[15]*v[3];

 v[0]=res[0]; // Results Are Stored Back In v[]

 v[1]=res[1];

 v[2]=res[2];

 v[3]=res[3]; // Homogenous Coordinate

}

The function to load the object is simple, just calling readObject, and then setting up the connectivity and the plane equations for each face.

int InitGLObjects() // Initialize Objects

{

 if (!readObject("Data/Object2.txt", obj)) // Read Object2 Into obj

 {

  return FALSE; // If Failed Return False

 }

 setConnectivity(obj); // Set Face To Face Connectivity

 for (int i=0; i < obj.nFaces; i++) // Loop Through All Object Faces

  calculatePlane(obj, obj.pFaces[i]); // Compute Plane Equations For All Faces

 return TRUE; // Return True

}

Finally, KillGLObjects is a convenience function so that if you add more objects, you can add them in a central place.

void KillGLObjects() {

 killObject( obj );

}

All of the other functions don't require any further explanantion. I have left out the standard NeHe tutorial code, as well as all of the variable definitions and the keyboard processing function. The commenting alone explains these sufficiently.

Some things to note about the tutoriaclass="underline"

• The sphere doesn't stop shadows being projected on the wall. In reality, the sphere should also be casting a shadow, so seeing the one on the wall won't matter, it's hidden. It's just there to see what happens on curved surfaces :)

• If you are noticing extremely slow frame rates, try switching to fullscreen mode, or setting your desktop colour depth to 32bpp.

• Arseny L. writes: If you are having problems with a TNT2 in Windowed mode, make sure your desktop color depth is not set to 16bit. In 16bit color mode, the stencil buffer is emulated, resulting in sluggish performance. There are no problems in 32bit mode (I have a TNT2 Ultra and I checked it). I've got to admit this was a lengthy task to write out this tutorial. It gives you full appreciation for the work that Jeff puts in! I hope you enjoy it, and give a huge thanks to Banu who wrote the original code! IF there is anything that needs further explaining in here, you are welcome to contact me (Brett), at brettporter@yahoo.com.

Banu Cosmin (Choko) & Brett Porter
Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD Linux Code For This Lesson. (Conversion by Jay Groven

Lesson 28

Bezier Patches
Written by: David Nikdel (ogapo@ithink.net)

This tutorial is intended to introduce you to Bezier Surfaces in the hopes that someone more artistic than myself will do something really cool with them and show all of us. This is not intended as a complete Bezier patch library, but more as proof of concept code to get you familiar with how these curved surfaces actually work. Also, as this is a very informal piece, I may have occasional lapses in correct terminology in favor of comprehensability; I hope this sits well with everyone. Finally, to those of you already familiar with Beziers who are just reading this to see if I screw up, shame on you ;-), but if you find anything wrong by all means let me or NeHe know, after all no one's perfect, eh? Oh, and one more thing, none of this code is optimised beyond my normal programming technique, this is by design. I want everyone to be able to see exactly what is going on. Well, I guess that's enough of an intro. On with the show!

The Math — ::evil music:: (warning, kinda long section)