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

 wc.lpszClassName = "OpenGL"; // Set The Class Name

 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DMsaved); // Save The Current Display State ( NEW )

 if (fullscreen) // Attempt Fullscreen Mode?

 {

  DEVMODE dmScreenSettings; // Device Mode

  memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared

  dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of The Devmode Structure

  dmScreenSettings.dmPelsWidth = width; // Selected Screen Width

  dmScreenSettings.dmPelsHeight = height; // Selected Screen Height

  dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel

  dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

 … Code Cut To Save Space (No Further Changes To This Function) …

 return TRUE; // Success

}

All I did here was add commands to rotate the patch, raise/lower the resolution, and toggle the control lines.

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("NeHe's Solid Object Tutorial", 640, 480, 16, 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

   }

  } else // If There Are No Messages

  {

   // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()

   if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received?

   {

    done=TRUE; // ESC or DrawGLScene Signalled A Quit

   } else // Not Time To Quit, Update Screen

   {

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

   }

   if (keys[VK_LEFT]) rotz –= 0.8f; // Rotate Left ( NEW )

   if (keys[VK_RIGHT]) rotz += 0.8f; // Rotate Right ( NEW )

   if (keys[VK_UP]) { // Resolution Up ( NEW )

    divs++;

    mybezier.dlBPatch = genBezier(mybezier, divs); // Update The Patch

    keys[VK_UP] = FALSE;

   }

   if (keys[VK_DOWN] && divs> 1) { // Resolution Down ( NEW )

    divs--;

    mybezier.dlBPatch = genBezier(mybezier, divs); // Update The Patch

    keys[VK_DOWN] = FALSE;

   }

   if (keys[VK_SPACE]) { // SPACE Toggles showCPoints ( NEW )

    showCPoints = !showCPoints;

    keys[VK_SPACE] = FALSE;

   }

   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("NeHe's Solid Object Tutorial", 640, 480, 16, fullscreen)) {

     return 0; // Quit If Window Was Not Created

    }

   }

  }

 }

 // Shutdown

 KillGLWindow(); // Kill The Window

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

}

Well, I hope this tutorial has been enlightening and you all now love Bezier curves as much as I do ;-). If you like this tutorial I may write another one on NURBS curves if anyone's interested. Please e-mail me and let me know what you thought of this tutorial.

About The Author: David Nikdel is currently 18 and a senior at Bartow Senior High School. His current projects include a research paper on curved surfaces in 3D graphics, an OpenGL based game called Blazing Sands and being lazy. His hobbies include programming, football, and paintballing. He will (hopefully) be a freshman at Georgia Tech next year.

David Nikdel
Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

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

Lesson 29

This tutorial was originally written by Andreas Löffler. He also wrote all of the original HTML for the tutorial. A few days later Rob Fletcher emailed me an Irix version of lesson 29. In his version he rewrote most of the code. So I ported Rob's Irix/GLUT code to Visual C++/Win32. I then modified the message loop code, and the fullscreen code. When the program is minimized it should use 0% of the CPU (or close to). When switching to and from fullscreen mode, most of the problems should be gone (screen not restoring properly, messed up display, etc).

Andreas tutorial is now better than ever. Unfortunately, the code has been modifed quite a bit, so all of the HTML has been rewritten by myself. Huge Thanks to Andreas for getting the ball rolling, and working his butt off to make a killer tutorial. Thanks to Rob for the modifications!

Lets begin… We create a device mode structure called DMsaved. We will use this structure to store information about the users default desktop resolution, color depth, etc., before we switch to fullscreen mode. More on this later! Notice we only allocate enough storage space for one texture (texture[1]).

#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 <stdio.h> // Header File For File Operation Needed

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