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

int WINAPI WinMain(HINSTANCE hInstance, // Instance

 HINSTANCE hPrevInstance, // Previous Instance

 LPSTR lpCmdLine, // Command Line Parameters

 int nCmdShow) // Window Show State {

MSG msg; // Windows Message Structure

 BOOL done=FALSE; // Bool Variable To Exit Loop

 // Ask The User Which Screen Mode They Prefer

 if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start FullScreen?", MB_YESNO|MB_ICONQUESTION) == IDNO) {

  fullscreen=FALSE; // Windowed Mode

 }

 // Create Our OpenGL Window

 if (!CreateGLWindow("Andreas Löffler, Rob Fletcher & NeHe's Blitter & Raw Image Loading Tutorial", 640, 480, 32, fullscreen)) {

  return 0; // Quit If Window Was Not Created

 }

 while(!done) // Loop That Runs While done=FALSE

 {

  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Is There A Message Waiting?

  {

   if (msg.message == WM_QUIT) // Have We Received A Quit Message?

   {

    done=TRUE; // If So done=TRUE

   } else // If Not, Deal With Window Messages

   {

    TranslateMessage(&msg); // Translate The Message

    DispatchMessage(&msg); // Dispatch The Message

   }

  }

I have made some changes to the code below. If the program is not active (minimized) we wait for a message with the command WaitMessage(). Everything stops until the program receives a message (usually maximizing the window). What this means is that the program no longer hogs the processor while it's minimized. Thanks to Jim Strong for the suggestion.

  if (!active) // Program Inactive?

  {

   WaitMessage(); // Wait For A Message / Do Nothing (NEW … Thanks Jim Strong)

  }

  if (keys[VK_ESCAPE]) // Was Escape Pressed?

  {

   done=TRUE; // ESC Signalled A Quit

  }

  if (keys[VK_F1]) // Is F1 Being Pressed?

  {

   keys[VK_F1]=FALSE; // If So Make Key FALSE

   KillGLWindow(); // Kill Our Current Window

   fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode

   // Recreate Our OpenGL Window

   if (!CreateGLWindow("Andreas Löffler, Rob Fletcher & NeHe's Blitter & Raw Image Loading Tutorial", 640, 480, 16, fullscreen)) {

    return 0; // Quit If Window Was Not Created

   }

  }

  DrawGLScene(); // Draw The Scene

  SwapBuffers(hDC); // Swap Buffers (Double Buffering)

 }

 // Shutdown

 KillGLWindow(); // Kill The Window

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

}

Well, that_s it! Now the doors are open for creating some very cool blending effects for your games, engines or even applications. With texture buffers we used in this tutorial you could do more cool effects like real-time plasma or water. When combining these effects all together you_re able to do nearly photo-realistic terrain. If something doesn_t work in this tutorial or you have suggestions how to do it better, then please don_t hesitate to E-Mail me. Thank you for reading and good luck in creating your own special effects!

Some information about Andreas: I'm an 18 years old pupil who is currently studying to be a software engineer. I_ve been programming for nearly 10 years now. I've been programming in OpenGL for about 1.5 years.

Andreas Löffler & Rob Fletcher
Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD Linux/GLX Code For This Lesson. (Conversion by Rodolphe Suescun

Lesson 30

Collision Detection and Physically Based Modeling Tutorial by Dimitrios Christopoulos (christop@fhw.gr).

The source code upon which this tutorial is based, is from an older contest entry of mine (at OGLchallenge.dhs.org). The theme was Collision Crazy and my entry (which by the way took the 1st place :)) was called Magic Room. It features collision detection, physically based modeling and effects.

Collision Detection

A difficult subject and to be honest as far as I have seen up until now, there has been no easy solution for it. For every application there is a different way of finding and testing for collisions. Of course there are brute force algorithms which are very general and would work with any kind of objects, but they are expensive.

We are going to investigate algorithms which are very fast, easy to understand and to some extent quite flexible. Furthermore importance must be given on what to do once a collision is detected and how to move the objects, in accordance to the laws of physics. We have a lot stuff to cover. Lets review what we are going to learn:

1) Collision Detection

• Moving Sphere — Plane

• Moving Sphere — Cylinder

• Moving Sphere — Moving Sphere

2) Physically Based Modeling

• Collision Response

• Moving Under Gravity Using Euler Equations

3) Special Effects

• Explosion Modeling Using A Fin-Tree Billboard Method

• Sounds Using The Windows Multimedia Library (Windows Only)

4) Explanation Of The Code

• The Code Is Divided Into 5 Files

Lesson30.cpp: Main Code For This Tutorial

Image.cpp, Image.h: Code To Load Bitmaps

Tmatrix.cpp, Tmatrix.h: Classes To Handle Rotations

Tray.cpp, Tray.h: Classes To Handle Ray Operations

Tvector.cpp, Tvector.h: Classes To Handle Vector Operations

A lot of handy code! The Vector, Ray and Matrix classes are very useful. I used them until now for personal projects of my own.

1) Collision Detection

For the collision detection we are going to use algorithms which are mostly used in ray tracing. Lets first define a ray.

A ray using vector representation is represented using a vector which denotes the start and a vector (usually normalized) which is the direction in which the ray travels. Essentially a ray starts from the start point and travels in the direction of the direction vector. So our ray equation is:

PointOnRay = Raystart + t * Raydirection

t is a float which takes values from [0, infinity).

With 0 we get the start point and substituting other values we get the corresponding points along the ray. PointOnRay, Raystart, Raydirection, are 3D Vectors with values (x,y,z). Now we can use this ray representation and calculate the intersections with plane or cylinders.

Ray — Plane Intersection Detection

A plane is represented using its Vector representation as:

Xn dot X = d

Xn, X are vectors and d is a floating point value.

Xn is its normal.

X is a point on its surface.

d is a float representing the distance of the plane along the normal, from the center of the coordinate system.