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

  hInstance, // Instance

  NULL))) // Dont Pass Anything To WM_CREATE

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be

 {

  sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor

  1, // Version Number

  PFD_DRAW_TO_WINDOW | // Format Must Support Window

  PFD_SUPPORT_OPENGL | // Format Must Support OpenGL

  PFD_DOUBLEBUFFER, // Must Support Double Buffering

  PFD_TYPE_RGBA, // Request An RGBA Format

  bits, // Select Our Color Depth

  0, 0, 0, 0, 0, 0, // Color Bits Ignored

  0, // No Alpha Buffer

  0, // Shift Bit Ignored

  0, // No Accumulation Buffer

  0, 0, 0, 0, // Accumulation Bits Ignored

  16, // 16Bit Z-Buffer (Depth Buffer)

 The only change in this section of code is the line below. It is *VERY IMPORTANT* you change the value from 0 to 1 or some other non zero value. In all of the previous tutorials the value of the line below was 0. In order to use Stencil Buffering this value HAS to be greater than or equal to 1. This value is the number of bits you want to use for the stencil buffer.

  1, // Use Stencil Buffer ( * Important * )

  0, // No Auxiliary Buffer

  PFD_MAIN_PLANE, // Main Drawing Layer

  0, // Reserved

  0, 0, 0 // Layer Masks Ignored

 };

 if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // Are We Able To Set The Pixel Format?

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 ShowWindow(hWnd, SW_SHOW); // Show The Window

 SetForegroundWindow(hWnd); // Slightly Higher Priority

 SetFocus(hWnd); // Sets Keyboard Focus To The Window

 ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen

 if (!InitGL()) // Initialize Our Newly Created GL Window

 {

  KillGLWindow(); // Reset The Display

  MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK|MB_ICONEXCLAMATION);

  return FALSE; // Return FALSE

 }

 return TRUE; // Success

}

WndProc() has not changed, so we will skip over it.

LRESULT CALLBACK WndProc(HWND hWnd, // Handle For This Window

 UINT uMsg, // Message For This Window

 WPARAM wParam, // Additional Message Information

 LPARAM lParam) // Additional Message Information

Nothing new here. Typical start to WinMain().

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

 }

The only real big change in this section of the code is the new window title to let everyone know the tutorial is about reflections using the stencil buffer. Also notice that we pass the resx, resy and resbpp variables to our window creation procedure instead of the usual 640, 480 and 16.

 // Create Our OpenGL Window

 if (!CreateGLWindow("Banu Octavian & NeHe's Stencil & Reflection Tutorial", resx, resy, resbpp, 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) // Program Active?

   {

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

    {

     done=TRUE; // ESC Signalled A Quit

    } else // Not Time To Quit, Update Screen

    {

     DrawGLScene(); // Draw The Scene

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

Instead of checking for key presses in WinMain(), we jump to our keyboard handling routine called ProcessKeyboard(). Notice the ProcessKeyboard() routine is only called if the program is active!

     ProcessKeyboard(); // Processed Keyboard Presses

    }

   }

  }

 }

 // Shutdown

 KillGLWindow(); // Kill The Window