outdated: 9.Moving Bitmaps In 3D Space

这一章主要是位图的旋转以及灯光的问题,主要的效果为旋转加闪烁(在代码后面会有截图),色彩在代码中为随机生成的,所以看起来是五彩的,不过在旋转过快时会产生亮白效果。闪烁效果按键为T。同以前一样,小键盘的+-为接近屏幕和远离屏幕。UP键和DOWN为每次增加一定的角度来翻转整个图形。

这是没有开闪烁效果的截图:

这是按下T之后的截图:

很明显的增亮了许多。

当然在数量(num)增加到200时(不能更多了。。。),画方块的话,到最后就是个纯白的圆,和和面一样。换成线条或者点看起来还是不错的。

这是num为200时的点图。

num为200时的线图,因为每秒帧数太高,看起来漂亮,但截图截的只是一团子线了,想要看得可以自己亲手试试。

为了能细细观察它是怎么变化的,我就在循环中写了个延迟。下图为num为200时的线图:

 

同样修改位于双行星号内。

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

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

 

posted @ 2016-07-05 18:54  clairvoyant  阅读(268)  评论(0编辑  收藏  举报