outdated: 5.3D Shapes

图形是旋转的。

修改部分在双行星号内。

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

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

posted @ 2016-07-02 12:23  clairvoyant  阅读(221)  评论(0编辑  收藏  举报