zoukankan      html  css  js  c++  java
  • outdated: 8.Blending

    大多数人认为GL_RGBA中的alpha通道是透明与不透明程度的,即0为完全透明,1为不透明。

    The Blending equation:(Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)

    sd为下标,指定的是资源和目标像素。SD是混合因子,可以表示怎样混合像素。S(As,As,As,As)(AKA source alpha)而D(1,1,1,1)-(As,As,As,As)(AKA one minus src alpha)。

    即方程式又可表示为:(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bd (1 - As), As As + Ad (1 - As))

    在OpenGL中正确绘制混合色彩的方式是在绘制其余部分后,再来绘制所有透明部分的多边形(alpha<1.0)。

    首先应该绘制反向的多边形(背面的),使用透明功能时应关闭深度测试功能。

    B控制透明效果的开启。

    修改部分位于双行星号内。

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

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

  • 相关阅读:
    java fx example
    JavaFX 2.0+ WebView /WebEngine render web page to an image
    剑指Offer面试题41(Java版):和为s的两个数字VS和为s的连续正数序列
    时间类(时间戳的各种转换成)
    Android系统各种类型的service刨根解读
    二叉树的建立基本操作(链表方式)(一)
    从头认识java-13.2 利用元组的方式返回多类型对象
    EA初步使用
    inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移
    下拉框与列表框
  • 原文地址:https://www.cnblogs.com/clairvoyant/p/5642403.html
Copyright © 2011-2022 走看看