• outdated: 13.Bitmap Fonts


    如何在屏幕上显示字体,同时颜色变换且是动态移动的?

    CreateFont()是建立字体主要的函数,在MSDN中有详细的解释。同时的glGenLists()函数创建空的显示列表,主要是为了表示26个字母。SelectObject()函数以及DeleteObject()函数是对具体字体对象的操作。

    wglUseFontBitmaps()函数批量的产生显示字符用的显示列表在当前句柄中。

    在原作者编写的glPrint()函数中,使用到了va_start()、va_end()函数,那是为了访问变量参数列表。vsprintf()函数和sprintf()函数前两个参数一样,后一个参数为指向参数列表的指针。

    glPushAttrib()、glPopAttrib()函数操作于显示列表。glListBase()函数设置显示列表作用于glCallLists()函数。

    glRasterPos2f()函数指定像素操作光栅化位置。

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

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

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

  • 相关阅读:
    扩展中国剩余定理
    bzoj 3816&&uoj #41. [清华集训2014]矩阵变换
    THUSC2017
    bzoj 4521: [Cqoi2016]手机号码
    bzoj 4871: [Shoi2017]摧毁“树状图”
    bzoj 2300 : [HAOI2011]防线修建
    bzoj 3853 : GCD Array
    HEOI 2017 游记
    bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机模板
    bzoj 4310 跳蚤
  • 原文地址:https://www.cnblogs.com/clairvoyant/p/5657884.html
Copyright © 2020-2023  润新知