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

     // Recreate Our OpenGL Window

     if (!CreateGLWindow("Piotr Cieslak & NeHe's Morphing Points Tutorial", 640, 480, 16, fullscreen)) {

      return 0; // Quit If Window Was Not Created

     }

    }

   }

  }

 }

 // Shutdown

 KillGLWindow(); // Kill The Window

 return (msg.wParam); // Exit The Program

}

I hope you have enjoyed this tutorial. Although it's not an incredibly complex tutorial, you can learn alot from the code! The animation in my dolphin demo is done in a similar way to the morphing in this demo. By playing around with the code you can come up with some really cool effects. Dots turning into words. Faked animation, and more! You may even want to try using solid polygons or lines instead of dots. The effect can be quite impressive!

Piotr's code is new and refreshing. I hope that after reading through this tutorial you have a better understanding on how to store and load object data from a file, and how to manipulate the data to create cool GL effects in your own programs! The .html for this tutorial took 3 days to write. If you notice any mistakes please let me know. Alot of it was written late at night, meaning a few mistakes may have crept in. I want these tutorials to be the best they can be. Feedback is appreciated!

RabidHaMsTeR released a demo called "Morph" before this tutorial was written that shows off a more advanced version of this effect. You can check it out yourself at http://homepage.ntlworld.com/fj.williams/PgSoftware.html.

Piotr Cieslak
Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

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

* DOWNLOAD Mac OS X/Cocoa Code For This Lesson. (Conversion by Bryan Blackburn

Lesson 26

Welcome to another exciting tutorial. The code for this tutorial was written by Banu Cosmin. The tutorial was of course written by myself (NeHe). In this tutorial you will learn how to create EXTREMELY realistic reflections. Nothing fake here! The objects being reflected will not show up underneath the floor or on the other side of a wall. True reflections!

A very important thing to note about this tutoriaclass="underline" Because the Voodoo 1, 2 and some other cards do not support the stencil buffer, this demo will NOT run on those cards. It will ONLY run on cards that support the stencil buffer. If you're not sure if your card supports the stencil buffer, download the code, and try running the demo. Also, this demo requires a fairly decent processor and graphics card. Even on my GeForce I notice there is a little slow down at times. This demo runs best in 32 bit color mode!

As video cards get better, and processors get faster, I can see the stencil buffer becoming more popular. If you have the hardware and you're ready to reflect, read on!

The first part of the code is fairly standard. We include all necessary header files, and set up our Device Context, Rendering Context, etc.

#include <windows.h> // Header File For Windows

#include <gl\gl.h> // Header File For The OpenGL32 Library

#include <gl\glu.h> // Header File For The GLu32 Library

#include <gl\glaux.h> // Header File For The Glaux Library

#include <stdio.h> // Header File For Standard Input / Output

HDC hDC=NULL; // Private GDI Device Context

HGLRC hRC=NULL; // Permanent Rendering Context

HWND hWnd=NULL; // Holds Our Window Handle

HINSTANCE hInstance = NULL; // Holds The Instance Of The Application

Next we have the standard variables to keep track of key presses (keys[ ]), whether or not the program is active (active), and if we should use fullscreen mode or windowed mode (fullscreen).

bool keys[256]; // Array Used For The Keyboard Routine

bool active=TRUE; // Window Active Flag Set To TRUE By Default

bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default

Next we set up our lighting variables. LightAmb[ ] will set our ambient light. We will use 70% red, 70% green and 70% blue, creating a light that is 70% bright white. LightDif[ ] will set the diffuse lighting (the amount of light evenly reflected off the surface of our object). In this case we want to reflect full intensity light. Lastly we have LightPos[ ] which will be used to position our light. In this case we want the light 4 units to the right, 4 units up, and 6 units towards the viewer. If we could actually see the light, it would be floating in front of the top right corner of our screen.

// Light Parameters

static GLfloat LightAmb[] = {0.7f, 0.7f, 0.7f, 1.0f}; // Ambient Light

static GLfloat LightDif[] = {1.0f, 1.0f, 1.0f, 1.0f}; // Diffuse Light

static GLfloat LightPos[] = {4.0f, 4.0f, 6.0f, 1.0f}; // Light Position

We set up a variable called q for our quadratic object, xrot and yrot to keep track of rotation. xrotspeed and yrotspeed control the speed our object rotates at. zoom is used to zoom in and out of the scene (we start at –7 which shows us the entire scene) and height is the height of the ball above the floor.

We then make room for our 3 textures with texture[3], and define WndProc().

GLUquadricObj *q; // Quadratic For Drawing A Sphere

GLfloat xrot = 0.0f; // X Rotation

GLfloat yrot = 0.0f; // Y Rotation

GLfloat xrotspeed = 0.0f; // X Rotation Speed

GLfloat yrotspeed = 0.0f; // Y Rotation Speed

GLfloat zoom = –7.0f; // Depth Into The Screen

GLfloat height = 2.0f; // Height Of Ball From Floor

GLuint texture[3]; // 3 Textures

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc

The ReSizeGLScene() and LoadBMP() code has not changed so I will skip over both sections of code.

GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image

The load texture code is pretty standard. You've used it many times before in the previous tutorials. We make room for 3 textures, then we load the three images, and create linear filtered textures from the image data. The bitmap files we use are located in the DATA directory.

int LoadGLTextures() // Load Bitmaps And Convert To Textures

{

 int Status=FALSE; // Status Indicator

 AUX_RGBImageRec *TextureImage[3]; // Create Storage Space For The Textures

 memset(TextureImage,0,sizeof(void *)*3); // Set The Pointer To NULL

 if ((TextureImage[0]=LoadBMP("Data/EnvWall.bmp")) && // Load The Floor Texture

  (TextureImage[1]=LoadBMP("Data/Ball.bmp")) && // Load the Light Texture

  (TextureImage[2]=LoadBMP("Data/EnvRoll.bmp"))) // Load the Wall Texture