• outdated: 1.Setting Up An OpenGL Window


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

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

  • 相关阅读:
    vue报错 error: data.push is not a function
    vue elment.style样式修改(第三方组件自生成元素)
    按元素标签查询多个
    按css查询多个元素
    按CSS查询一个元素
    查询单个元素
    JavaScript 查找元素
    Spring 商品分类
    Spring 使用日志
    Spring 使用日期类型
  • 原文地址:https://www.cnblogs.com/clairvoyant/p/5515267.html
Copyright © 2020-2023  润新知