outdated: 15.Texture Mapped Outline Fonts

glTexGeni()函数为控制纹理坐标的生成。

代码如下,同样修改的部分位于双行星号内。

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

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

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