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

  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)

  0, // No Stencil Buffer

  0, // No Auxiliary Buffer

  PFD_MAIN_PLANE, // Main Drawing Layer

  0, // Reserved

  0, 0, 0 // Layer Masks Ignored

 };

If there were no errors while creating the window, we'll attempt to get an OpenGL Device Context. If we can't get a DC an error message will pop onto the screen, and the program will quit (return FALSE).

 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 we managed to get a Device Context for our OpenGL window we'll try to find a pixel format that matches the one we described above. If Windows can't find a matching pixel format, an error message will pop onto the screen and the program will quit (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 windows found a matching pixel format we'll try setting the pixel format. If the pixel format cannot be set, an error message will pop up on the screen and the program will quit (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 the pixel format was set properly we'll try to get a Rendering Context. If we can't get a Rendering Context an error message will be displayed on the screen and the program will quit (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 there have been no errors so far, and we've managed to create both a Device Context and a Rendering Context all we have to do now is make the Rendering Context active. If we can't make the Rendering Context active an error message will pop up on the screen and the program will quit (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

 }

If everything went smoothly, and our OpenGL window was created we'll show the window, set it to be the foreground window (giving it more priority) and then set the focus to that window. Then we'll call ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.

 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

Finally we jump to InitGL() where we can set up lighting, textures, and anything else that needs to be setup. You can do your own error checking in InitGL(), and pass back TRUE (everythings OK) or FALSE (somethings not right). For example, if you were loading textures in InitGL() and had an error, you may want the program to stop. If you send back FALSE from InitGL() the lines of code below will see the FALSE as an error message and the program will quit.

 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

 }

If we've made it this far, it's safe to assume the window creation was successful. We return TRUE to WinMain() telling WinMain() there were no errors. This prevents the program from quitting.

 return TRUE; // Success

}

This is where all the window messages are dealt with. When we registred the Window Class we told it to jump to this section of code to deal with window messages.

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

{

The code below sets uMsg as the value that all the case statements will be compared to. uMsg will hold the name of the message we want to deal with.

 switch (uMsg) // Check For Windows Messages

 {

if uMsg is WM_ACTIVE we check to see if our window is still active. If our window has been minimized the variable active will be FALSE. If our window is active, the variable active will be TRUE.

 case WM_ACTIVATE: // Watch For Window Activate Message

  {

   if (!HIWORD(wParam)) // Check Minimization State

   {

    active=TRUE; // Program Is Active

   } else {

    active=FALSE; // Program Is No Longer Active

   }

   return 0; // Return To The Message Loop

  }

If the message is WM_SYSCOMMAND (system command) we'll compare wParam against the case statements. If wParam is SC_SCREENSAVE or SC_MONITORPOWER either a screensaver is trying to start or the monitor is trying to enter power saving mode. By returning 0 we prevent both those things from happening.

 case WM_SYSCOMMAND: // Intercept System Commands

  {

   switch (wParam) // Check System Calls

   {

   case SC_SCREENSAVE: // Screensaver Trying To Start?

   case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?

    return 0; // Prevent From Happening

   }

   break; // Exit

  }

If uMsg is WM_CLOSE the window has been closed. We send out a quit message that the main loop will intercept. The variable done will be set to TRUE, the main loop in WinMain() will stop, and the program will close.