outdated: 11.Flag Effect (Waving Texture)

这一节主要是贴图材质的波动,运用正弦函数控制像素点的深度,每次绘制完再进行少量转换。

代码中的glPolygonMode()函数为贴图材质的正反面显示形式的描述,可为线条即网格,点和填充即原图。

代码如下,同样修改内容在双行星号内。

  1 #include <windows.h>
  2 #include <stdio.h>
  3 #include <math.h>
  4 #include <gl/glew.h>
  5 #include <gl/glut.h>
  6 #include <GL/GLUAX.H>
  7 #pragma comment(lib, "legacy_stdio_definitions.lib")
  8 /*
  9  *  Every OpenGL program is linked to a Rendering Context.
 10  *  A Rendering Context is what links OpenGL calls to the Device Context.
 11  *  In order for your program to draw to a Window you need to create a Device Context.
 12  *  The DC connects the Window to the GDI (Graphics Device Interface).
 13  */
 14 
 15 HGLRC     hRC = NULL;         // Permanent rendering context
 16 HDC       hDC = NULL;         // Private GDI device context
 17 HWND      hWnd = NULL;        // Holds our window handle
 18 HINSTANCE hInstance;          // Holds the instance of the application
 19 
 20 /*
 21  *  It's important to make this global so that each procedure knows if 
 22  *  the program is running in fullscreen mode or not.
 23  */
 24 
 25 bool keys[256];         // Array used for the keyboard routine
 26 bool active = TRUE;     // Window active flag set to TRUE by default
 27 bool fullscreen = TRUE; // Fullscreen flag set to fullscreen mode by default
 28 
 29 GLuint texture[1];
 30 /******************************************************************************************************************************************/
 31 /******************************************************************************************************************************************/
 32 float points[45][45][3];                              // The array for the points on the grid of the wave
 33 int wiggle_count = 0;                                 // Counter used to control how fast flag  waves
 34 GLfloat hold;                                         // Temporarily holds a floating point value
 35 GLfloat xrot;
 36 GLfloat yrot;
 37 GLfloat zrot;
 38 /******************************************************************************************************************************************/
 39 /******************************************************************************************************************************************/
 40 /*
 41  *  CreateGLWindow() has a reference to WndProc() but WndProc() comes after CreateGLWindow().
 42  */
 43 
 44 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc
 45 
 46 /*
 47  *  The job of the next section of code is to resize the OpenGL scene 
 48  *  whenever the window (assuming you are using a Window rather than fullscreen mode) has been resized.
 49  */
 50 
 51 AUX_RGBImageRec* LoadBMP(char* Filename)              // Loads a bitmap image
 52 {
 53     FILE* File = NULL;                                // File handle
 54 
 55     if (!Filename) {                                  // Make sure a filename was given
 56         return NULL;                                  // If not return NULL
 57     }
 58 
 59     File = fopen(Filename, "r");                      // Check to see of the file exists
 60     if (File) {
 61         fclose(File);
 62         return auxDIBImageLoad(Filename);             // Load the bitmap and return a pointer
 63     }
 64 
 65     return NULL;
 66 }
 67 
 68 int LoadGLTextures()                                  // Load bitmap and convert to texture
 69 {
 70     int Status = FALSE;                               // Status indicator
 71 
 72     AUX_RGBImageRec* TextureImage[1];                 // Create    storage space for the texture
 73 
 74     memset(TextureImage, 0, sizeof(void*)*1);         // Set the pointer to NULL
 75 
 76     // Load the bitmap, check for error, if bitmap's not found quit
 77     if (TextureImage[0] = LoadBMP("1.bmp")) {
 78         Status = TRUE;
 79 
 80         glGenTextures(1, &texture[0]);                // Create the texture
 81 /******************************************************************************************************************************************/
 82 /******************************************************************************************************************************************/
 83         glBindTexture(GL_TEXTURE_2D, texture[0]);
 84         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear filtering
 85         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear filtering
 86         glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB,
 87             GL_UNSIGNED_BYTE, TextureImage[0]->data);
 88     }
 89 /******************************************************************************************************************************************/
 90 /******************************************************************************************************************************************/
 91     if (TextureImage[0]) {
 92         if (TextureImage[0]->data) {
 93             free(TextureImage[0]->data);
 94         }
 95         free(TextureImage[0]);
 96     }
 97     return Status;
 98 }
 99 
100 
101 GLvoid ReSizeGLScene(GLsizei width, GLsizei height)   // Resize and initialize the GL window
102 {
103     if (height == 0) {                                // Prevent a divide by zero by
104         height = 1;                                   // Making height equal one
105     }
106     
107     glViewport(0, 0, width, height);                  // Reset the current viewport
108 
109     /*
110      *  The following lines set the screen up for a perspective view. 
111      *  Meaning things in the distance get smaller. This creates a realistic looking scene. 
112      *  The perspective is calculated with a 45 degree viewing angle based on 
113      *  the windows width and height. The 0.1f, 100.0f is the starting point and 
114      *  ending point for how deep we can draw into the screen.
115      *
116      *  The projection matrix is responsible for adding perspective to our scene.
117      *  glLoadIdentity() restores the selected matrix to it's original state.
118      *  The modelview matrix is where our object information is stored.
119      *   Lastly we reset the modelview matrix.
120      */
121 
122     glMatrixMode(GL_PROJECTION);                      // Select the projection matrix
123     glLoadIdentity();                                 // Reset the projection matrix
124     
125                                                       // Calculate the aspect ratio of the window
126     gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
127 
128     glMatrixMode(GL_MODELVIEW);                       // Seclet the modelview matrix
129     glLoadIdentity();                                 // Reset the modelview matrix
130 }
131 
132 int InitGL(GLvoid)                                    // All setup for OpenGL goes here
133 {
134     if (!LoadGLTextures()) {                          // Jump to texture loading routine
135         return FALSE;                                 // If texture didn't load return false
136     }
137     glEnable(GL_TEXTURE_2D);                          // Enable texture mapping
138     /*
139      *  Smooth shading blends colors nicely across a polygon, and smoothes out lighting.
140      */
141     glClearColor(0.0f, 0.0f, 0.0f, 0.5f);             // Black background
142 
143     glClearDepth(1.0f);                               // Depth buffer setup
144 /******************************************************************************************************************************************/
145 /******************************************************************************************************************************************/
146 
147     glDepthFunc(GL_LEQUAL);
148     glEnable(GL_DEPTH_TEST);
149     glShadeModel(GL_SMOOTH);                          // Enables smooth shading
150     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   // Really nice perspective calculations
151 
152     glPolygonMode(GL_BACK, GL_FILL);                  // Back face is filled in
153     glPolygonMode(GL_FRONT, GL_LINE);                 // Front face is draw with lines
154 
155     for (int x = 0; x < 45; ++x) {
156         for (int y = 0; y < 45; ++y) {
157             points[x][y][0] = float((x / 5.0f) - 4.5f);
158             points[x][y][1] = float((y / 5.0f) - 4.5f);
159             points[x][y][2] = float(sin((((x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));
160         }
161     }
162     return TRUE;
163 }
164 
165 /*
166  *  For now all we will do is clear the screen to the color we previously decided on, 
167  *  clear the depth buffer and reset the scene. We wont draw anything yet.
168  */
169 int DrawGLScene(GLvoid)                                  // Here's where we do all the drawing
170 {
171     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear the screen and the depth buffer
172     glLoadIdentity();
173 
174     int x, y;
175     float float_x, float_y, float_xb, float_yb;
176     
177     glTranslatef(0.0f, 0.0f, -12.0f);
178 
179     glRotatef(xrot, 1.0f, 0.0f, 0.0f);
180     glRotatef(yrot, 0.0f, 1.0f, 0.0f);
181 //    glRotatef(zrot, 0.0f, 0.0f, 1.0f);
182     
183     glBindTexture( GL_TEXTURE_2D, texture[0]);
184 
185 
186     glBegin(GL_QUADS);
187     for (x = 0; x < 44; ++x) {
188         for (y = 0; y < 44; ++y) {
189             for (int i = 0; i < 1000; ++i) { i--; i++; }
190             float_x = float(x) / 44.0f;
191             float_y = float(y) / 44.0f;
192             float_xb = float(x + 1) / 44.0f;
193             float_yb = float(y + 1) / 44.0f;
194             glTexCoord2f(float_x, float_y);
195             glVertex3f(points[x][y][0], points[x][y][1], points[x][y][2]);
196             glTexCoord2f(float_x, float_yb);
197             glVertex3f(points[x][y+1][0], points[x][y+1][1], points[x][y+1][2]);
198             glTexCoord2f(float_xb, float_yb);
199             glVertex3f(points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2]);
200             glTexCoord2f(float_xb, float_y);
201             glVertex3f(points[x+1][y][0], points[x+1][y][1], points[x+1][y][2]);
202         }
203     }
204     glEnd();
205 
206     if (wiggle_count == 2) {
207         for (y = 0; y < 45; ++y) {
208             hold = points[0][y][2];
209             for (x = 0; x < 44; ++x) {
210                 points[x][y][2] = points[x + 1][y][2];
211             }
212             points[44][y][2] = hold;
213         }
214         wiggle_count = 0;
215     }
216     wiggle_count++;
217 
218     xrot += 0.3f;
219     yrot += 0.2f;
220     zrot += 0.4f;
221     return TRUE;                                         // everthing went OK
222 }
223 /******************************************************************************************************************************************/
224 /******************************************************************************************************************************************/
225 /*
226  *  The job of KillGLWindow() is to release the Rendering Context, 
227  *  the Device Context and finally the Window Handle. 
228  */
229 
230 GLvoid KillGLWindow(GLvoid)                              // Properly kill the window
231 {
232     if (fullscreen) {                                    // Are we in fullscreen mode
233         
234         /*
235          *  We use ChangeDisplaySettings(NULL,0) to return us to our original desktop.
236          *  After we've switched back to the desktop we make the cursor visible again.
237          */
238 
239         ChangeDisplaySettings(NULL, 0);                  // if so switch back to the desktop
240         ShowCursor(TRUE);                                // Show mouse pointer
241     }
242 
243     if (hRC) {                                           // Do we have a rendering context
244         if (!wglMakeCurrent(NULL, NULL)) {                // Are we able to release the DC and RC contexts
245             MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
246         }
247 
248         if (!wglDeleteContext(hRC)) {                     // Are we able to delete the RC
249             MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
250             hRC = NULL;                                  // Set RC to NULL
251         }
252 
253         if (hDC && !ReleaseDC(hWnd, hDC)) {              // Are we able to release the DC
254             MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
255             hDC = NULL;                                  // Set DC to NULL
256         }
257         if (hWnd && !DestroyWindow(hWnd)) {              // Are we able to destroy the window
258             MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
259             hWnd = NULL;                                 // Set hWnd to NULL
260         }
261 
262         if (!UnregisterClass("OpenGL", hInstance)) {     // Are we able to unregister class
263             MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
264             hInstance = NULL;                            // Set hInstance to NULL
265         }
266     }
267 }
268 
269 /*
270  * The next section of code creates our OpenGL Window.
271  */
272 
273 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
274 {
275     /*
276      * Find  a pixel format that matches the one we want
277      */
278     GLuint PixelFormat;                                  // Holds the result after serching for a match
279     
280     /*
281      * Before you create a window, you MUST register a Class for the window
282      */
283     WNDCLASS wc;                                         // Windows class structure
284 
285     /*
286      *  dwExStyle and dwStyle will store the Extended and normal Window Style Information.
287     */
288     DWORD dwExStyle;                                     // Window extend style
289     DWORD dwStyle;                                       // Window style
290 
291     RECT WindowRect;                                     // Grabs rectangle upper left/lower right values
292     WindowRect.left = (long)0;                           // Set left value to 0
293     WindowRect.right = (long)width;                      // Set right value to requested width
294     WindowRect.top = (long)0;                            // Set top value to 0
295     WindowRect.bottom = (long)height;                    // Set bottom value to requested height
296 
297     fullscreen = fullscreenflag;                         // Set the global fullscreen flag
298 
299     /*
300      *  The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized. 
301      *  CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications. 
302      *  WndProc is the procedure that watches for messages in our program. 
303      *  No extra Window data is used so we zero the two fields. Then we set the instance. 
304      *  Next we set hIcon to NULL meaning we don't want an ICON in the Window, 
305      *  and for a mouse pointer we use the standard arrow. The background color doesn't matter 
306      *  (we set that in GL). We don't want a menu in this Window so we set it to NULL, 
307      *  and the class name can be any name you want. I'll use "OpenGL" for simplicity.
308      */
309     hInstance = GetModuleHandle(NULL);                   // Grab an instance for our window
310     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;       // Redraw on move, and own DC for window
311     wc.lpfnWndProc = (WNDPROC)WndProc;                   // WndProc handles message
312     wc.cbClsExtra = 0;                                   // No extra window date
313     wc.cbWndExtra = 0;                                   // No extra window date
314     wc.hInstance = hInstance;                            // set the instance
315     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);              // Load the default icon
316     wc.hCursor = LoadCursor(NULL, IDC_ARROW);            // Load the arrow pointer
317     wc.hbrBackground = NULL;                             // No background requried for GL
318     wc.lpszMenuName = NULL;                              // We don't want a menu
319     wc.lpszClassName = "OpenGL";                         // set the class name
320 
321     if (!RegisterClass(&wc)) {                           // Attempt to register the window class
322         MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
323         return FALSE;                                    // Exit and return false
324     }
325 
326     if (fullscreen) {                                    // attempt fullsreen model
327         
328         /*
329         T*  here are a few very important things you should keep in mind when switching to full screen mode.
330          *  Make sure the width and height that you use in fullscreen mode is the same as 
331          *  the width and height you plan to use for your window, and most importantly,
332          *  set fullscreen mode BEFORE you create your window.
333          */
334         DEVMODE dmScreenSettings;                        // Device mode
335         memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory's cleared
336         dmScreenSettings.dmSize = sizeof(dmScreenSettings);     // Size of devmode structure
337         dmScreenSettings.dmPelsWidth = width;            // Select window width
338         dmScreenSettings.dmPelsHeight = height;          // Select window height
339         dmScreenSettings.dmBitsPerPel = bits;            // Select bits per pixel
340         dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
341         
342         /*
343          *  In the line below ChangeDisplaySettings tries to switch to a mode that matches 
344          *  what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes, 
345          *  because it's supposed to remove the start bar at the bottom of the screen, 
346          *  plus it doesn't move or resize the windows on your desktop when you switch to 
347          *  fullscreen mode and back.
348          */
349         //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar
350         if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
351             //If the mode fails, offer two options. Quit or run in a window
352             if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use"
353                 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
354             {
355                 fullscreen = FALSE;                       // Select windowed mode (fullscreen=FLASE)
356             }
357             else {
358                 // Pop up a message box letting user know the programe is closing.
359                 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP);
360                 return FALSE;                             // Exit and return FALSE
361             }
362         }
363     }
364 
365     if (fullscreen) {                                     // Are we still in fullscreen mode
366         
367         /*
368          *  If we are still in fullscreen mode we'll set the extended style to WS_EX_APPWINDOW, 
369          *  which force a top level window down to the taskbar once our window is visible. 
370          *  For the window style we'll create a WS_POPUP window. 
371          *  This type of window has no border around it, making it perfect for fullscreen mode.
372 
373          *  Finally, we disable the mouse pointer. If your program is not interactive, 
374          *  it's usually nice to disable the mouse pointer when in fullscreen mode. It's up to you though.
375          */
376         dwExStyle = WS_EX_APPWINDOW;                      // Window extended style
377         dwStyle = WS_POPUP;                               // Window style
378         ShowCursor(FALSE);                                // Hide mosue pointer 
379     }
380     else {
381 
382         /*
383          *  If we're using a window instead of fullscreen mode, 
384          *  we'll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look. 
385          *  For style we'll use WS_OVERLAPPEDWINDOW instead of WS_POPUP. 
386          *  WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border, 
387          *  window menu, and minimize / maximize buttons.
388          */
389         dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window extended style
390         dwStyle = WS_OVERLAPPEDWINDOW;                    // Window style
391     }
392 
393     /*
394      *  By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders, 
395      *  instead, the window will be made larger to account for the pixels needed to draw the window border. 
396      *  In fullscreen mode, this command has no effect.
397      */
398     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);  // Adjust window to true resqusted
399     
400     /*
401      *  WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly. 
402      *  These styles prevent other windows from drawing over or into our OpenGL Window.
403      */
404     if (!(hWnd = CreateWindowEx(dwExStyle,                // Extended style for the window
405         "OpenGL",                                         // Class name
406         title,                                            // Window title
407         WS_CLIPSIBLINGS |                                 // Requried window style
408         WS_CLIPCHILDREN |                                 // Requried window style
409         dwStyle,                                          // Select window style
410         0, 0,                                             // Window position
411         WindowRect.right - WindowRect.left,               // Calculate adjusted window width
412         WindowRect.bottom - WindowRect.top,               // Calculate adjusted window height
413         NULL,                                             // No parent window
414         NULL,                                             // No menu
415         hInstance,                                        // Instance
416         NULL)))                                           // Don't pass anything to WM_CREATE
417     {
418         KillGLWindow();                                   //Reset the display
419         MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
420         return FALSE;                                     // Retrurn FALSE;
421     }
422 
423     /*
424      *  aside from the stencil buffer and the (slow) accumulation buffer
425      */
426     static PIXELFORMATDESCRIPTOR pfd =                    // pfd tells windows how we want things to be 
427     {
428         sizeof(PIXELFORMATDESCRIPTOR),                    // Size of this pixel format descriptor
429         1,                                                // Version number
430         PFD_DRAW_TO_WINDOW |                              // Format must support window
431         PFD_SUPPORT_OPENGL |                              // Format must support OpenGL
432         PFD_DOUBLEBUFFER,                                 // Must support double buffer
433         PFD_TYPE_RGBA,                                    // Request an RGBA format
434         bits,                                             // Select our color depth
435         0, 0, 0, 0, 0, 0,                                 // Color bits ignored
436         0,                                                // No alpha buffer
437         0,                                                // shift bit ignored
438         0,                                                // No accumulation buffer
439         0, 0, 0, 0,                                       // Accumulation bits ignored
440         16,                                               // 16Bits Z_Buffer (depth buffer)
441         0,                                                // No stencil buffer
442         0,                                                // No auxiliary buffer
443         PFD_MAIN_PLANE,                                   // Main drawing layer
444         0,                                                // Reserved
445         0, 0, 0                                           // Layer makes ignored
446     };
447 
448     if (!(hDC = GetDC(hWnd))) {                           // Did we get a device context
449         KillGLWindow();                                   // Reset the display
450         MessageBox(NULL, "Can't create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
451         return FALSE;                                     // Return FALSE
452     }
453 
454     if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {  // Did window find a matching pixel format
455         KillGLWindow();                                   // Reset the display
456         MessageBox(NULL, "Can't find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
457         return FALSE;                                     // Return FALSE;
458     }
459 
460     if (!SetPixelFormat(hDC, PixelFormat, &pfd)) {        // Are we able to set the pixel format
461         KillGLWindow();                                   // Reset the display
462         MessageBox(NULL, "Can't set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
463         return FALSE;                                     // Return FALSE;
464     }
465 
466     if (!(hRC = wglCreateContext(hDC))) {                 // Are we able to rendering context
467         KillGLWindow();                                   // Reset the display
468         MessageBox(NULL, "Can't create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
469         return FALSE;                                     // Return FASLE;
470     }
471 
472     if (!wglMakeCurrent(hDC, hRC)) {                      // Try to activate the rendering context
473         KillGLWindow();                                   // Reset the display
474         MessageBox(NULL, "Can't activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
475         return FALSE;                                     // Return FALSE    
476     }
477 
478     /*
479      *  ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.
480      */
481     ShowWindow(hWnd, SW_SHOW);                            // Show the window
482     SetForegroundWindow(hWnd);                            // slightly higher priority
483     SetFocus(hWnd);                                       // Sets keyboard focus to the window
484     ReSizeGLScene(width, height);                         // Set up our perspective GL screen
485 
486 /*
487  *  we can set up lighting, textures, and anything else that needs to be setup in InitGL().
488  */
489 if (!InitGL()) {                                      // Initialize our newly created GL window
490     KillGLWindow();                                   // Reset the display
491     MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
492     return FALSE;                                     // Return FALSE
493 }
494 return TRUE;
495 }
496 
497 LRESULT CALLBACK WndProc(HWND hWnd,                       // Handle for this window
498     UINT uMsg,                                            // Message for this window
499     WPARAM wParam,                                        // Additional message information
500     LPARAM lParam)                                        // Additional message information
501 {
502     switch (uMsg) {                                       // Check for window message
503     case WM_ACTIVATE: {                               // Check minimization state
504         if (!HIWORD(wParam)) {
505             active = TRUE;                            // Program is active
506         }
507         else {
508             active = FALSE;                           // Program is no longer active
509         }
510         return 0;                                     // Return to the message loop
511     }
512     case WM_SYSCOMMAND: {                             // Intercept system commands
513         switch (wParam) {                             // Check system calls
514         case SC_SCREENSAVE:                       // Screensaver trying to start
515         case SC_MONITORPOWER:                     // Monitor trying to enter powersave
516             return 0;                                 // Prevent form happening
517         }
518         break;                                        // Exit
519     }
520     case WM_CLOSE: {                                  // Did we receive a close message
521         PostQuitMessage(0);                           // Send a quit message
522         return 0;
523     }
524     case WM_KEYDOWN: {                                // Is a key being held down
525         keys[wParam] = TRUE;                          // if so, mark it as TRUE
526         return 0;                                     // Jump back
527     }
528     case WM_KEYUP: {                                  // Has a key been released
529         keys[wParam] = FALSE;                         // if so, mark it as FALSE
530         return 0;                                     // Jump back
531     }
532     case WM_SIZE: {                                   // Resize the OpenGL window
533         ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));   // LoWord = width HiWord = height
534         return 0;                                     // Jump back
535     }
536     }
537     return DefWindowProc(hWnd, uMsg, wParam, lParam);     // Pass all unhandled message to DefWindwProc
538 }
539 
540 int WINAPI WinMain(HINSTANCE hInstance,                   // Instance
541     HINSTANCE hPrevInstance,                              // Previous instance
542     LPSTR lpCmdLine,                                      // Command line parameters
543     int nCmdShow)                                         // Window show state
544 {
545     MSG msg;                                              // Window message structure
546     BOOL done = FALSE;                                    // Bool variable to exit loop
547                                                           // Ask the user which screen mode they prefer
548     if (MessageBox(NULL, "Would you like to run in fullscreen mode?",
549         "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO)
550     {
551         fullscreen = FALSE;                               // Window mode
552     }
553     // Create our OpenGL window
554     if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {  // (Modified)
555         return 0;                                         // Quit if window was not create
556     }
557 
558     while (!done) {                                       // Loop that runs until donw = TRUE
559         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {   // Is there a message wating
560             if (msg.message == WM_QUIT) {                 // Havw we received a quit message
561                 done = TRUE;                              // if so done  = TRUE
562             }
563             else {                                        // If not, deal with window message
564                 TranslateMessage(&msg);                   // Translate message
565                 DispatchMessage(&msg);                    // Dispatch message
566             }
567         }
568         else {
569             // Draw the scene. Watch for ESC key and quit message from DrawGLScene()
570             if (active) {                                 // Program active
571                 if (keys[VK_ESCAPE]) {                    // Was ESC pressed
572                     done = TRUE;                          // ESC signalled a quit
573                 }
574                 else {                                    // Not time to quit, update screen
575                     DrawGLScene();                        // Draw scene
576                     SwapBuffers(hDC);                     // Swap buffers (double buffering)
577                 }
578             }
579 
580             /*
581              *  It allows us to press the F1 key to switch from fullscreen mode to
582              *  windowed mode or windowed mode to fullscreen mode.
583              */
584 /******************************************************************************************************************************************/
585 /******************************************************************************************************************************************/
586 /******************************************************************************************************************************************/
587 /******************************************************************************************************************************************/
588             if (keys[VK_F1]) {                            // Is F1 being pressed
589                 keys[VK_F1] = FALSE;                      // If so make key FASLE
590                 KillGLWindow();                           // Kill our current window
591                 fullscreen = !fullscreen;                 // Toggle fullscreen / window mode
592                 //Recreate our OpenGL window(modified)
593                 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {
594                     return 0;                             // Quit if window was not create
595                 }
596             }
597         }
598     }
599     // Shutdown
600     KillGLWindow();                                       // Kill the window
601     return (msg.wParam);                                  // Exit the program
602 }

Thanks for Nehe's tutorials, this is his home.

posted @ 2016-07-08 13:13  clairvoyant  阅读(166)  评论(0编辑  收藏  举报