outdated: 20.Masking

某物体隐藏于某物体后,隐约可以看出大概。

在DrawGLScene()函数中,先画出位于后面的物体,当然具有较深深度。

在绘制前面物体时,为了可以隐藏(即和后面物体混合)开启混合模式且关闭深度测试。贴图纹理的位置坐标可以变换,即可以使前面的贴图图实现上下、左右、远近移动、波动等。

在开启GL_BLEND后,glBlendFunc()函数指定像素算法。

void glBlendFunc(GLenum sfactor,  GLenum dfactor);

sfactor:
                    GL_ZERO,
                    GL_ONE,
                    GL_SRC_COLOR,
                    GL_ONE_MINUS_SRC_COLOR,
                    GL_DST_COLOR,
                    GL_ONE_MINUS_DST_COLOR,
                    GL_SRC_ALPHA,
                    GL_ONE_MINUS_SRC_ALPHA,
                    GL_DST_ALPHA,
                    GL_ONE_MINUS_DST_ALPHA,
                    GL_CONSTANT_COLOR,
                    GL_ONE_MINUS_CONSTANT_COLOR,
                    GL_CONSTANT_ALPHA,
                    GL_ONE_MINUS_CONSTANT_ALPHA, and
                    GL_SRC_ALPHA_SATURATE.
                    默认为GL_ONE.

dfactor:
                    GL_ZERO,
                    GL_ONE,
                    GL_SRC_COLOR,
                    GL_ONE_MINUS_SRC_COLOR,
                    GL_DST_COLOR,
                    GL_ONE_MINUS_DST_COLOR,
                    GL_SRC_ALPHA,
                    GL_ONE_MINUS_SRC_ALPHA,
                    GL_DST_ALPHA,
                    GL_ONE_MINUS_DST_ALPHA.
                    GL_CONSTANT_COLOR,
                    GL_ONE_MINUS_CONSTANT_COLOR,
                    GL_CONSTANT_ALPHA, and
                    GL_ONE_MINUS_CONSTANT_ALPHA.
                    默认为GL_ZERO.

代码如下,同样修改部分位于双行星号内,空格键切换贴图纹理,M键实现隐藏效果。

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

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

posted @ 2016-07-18 13:45  clairvoyant  阅读(192)  评论(0编辑  收藏  举报