outdated: 7.Texture Filters, Lighting & Keyboard Control

这一篇主要是对键盘和灯光的控制。

up、down、right和left控制图形的旋转方向。L控制灯光的开关,F控制灯光模糊化程度。小键盘的+和-控制图形接近屏幕还是远离屏幕。在程序的最后会有演示。

代码如下,修改部分位于双行星号内:

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

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

对于vc++中对应的VK键。如下:

VK_LBUTTON

1

鼠标左键

VK_RBUTTON

2

鼠标右键

VK_CANCEL

3

Cancel

VK_MBUTTON

4

鼠标中键

VK_XBUTTON1

5

X1鼠标按钮

VK_XBUTTON2

6

X2鼠标按钮

VK_BACK

8

Backspace

VK_TAB

9

Tab

VK_CLEAR

12

Clear

VK_RETURN

13

Enter

VK_SHIFT

16

Shift

VK_CONTROL

17

Ctrl

VK_MENU

18

Alt

VK_PAUSE

19

Pause

VK_CAPITAL

20

Caps Lock

VK_KANA

21

IME假名模式

VK_HANGUL

21

IME Hanguel模式

VK_JUNJA

23

IME Junja模式

VK_FINAL

24

 

VK_HANJA

25

 

VK_KANJI

25*

 

VK_ESCAPE

27

Esc

VK_CONVERT

28

 

VK_NONCONVERT

29

 

VK_ACCEPT

30

 

VK_MODECHANGE

31

 

VK_SPACE

32

Space

VK_PRIOR

33

Page Up

VK_NEXT

34

Page Down

VK_END

35

End

VK_HOME

36

Home

VK_LEFT

37

Left Arrow

VK_UP

38

Up Arrow

VK_RIGHT

39

Right Arrow

VK_DOWN

40

Down Arrow

VK_SELECT

41

Select

VK_PRINT

42

Print

VK_EXECUTE

43

Execute

VK_SNAPSHOT

44

Snapshot

VK_INSERT

45

Insert

VK_DELETE

46

Delete

VK_HELP

47

Help

 

48

0

 

49

1

 

50

2

 

51

3

 

52

4

 

53

5

 

54

6

 

55

7

 

56

8

 

57

9

 

65

A

 

66

B

 

67

C

 

68

D

 

69

E

 

70

F

 

71

G

 

72

H

 

73

I

 

74

J

 

75

K

 

76

L

 

77

M

 

78

N

 

79

O

 

80

P

 

81

Q

 

82

R

 

83

S

 

84

T

 

85

U

 

86

V

 

87

W

 

88

X

 

89

Y

 

90

Z

VK_LWIN

91

 

VK_RWIN

92

 

VK_APPS

93

 

VK_SLEEP

95

 

VK_NUMPAD0

96

小键盘 0

VK_NUMPAD1

97

小键盘 1

VK_NUMPAD2

98

小键盘 2

VK_NUMPAD3

99

小键盘 3

VK_NUMPAD4

100

小键盘 4

VK_NUMPAD5

101

小键盘 5

VK_NUMPAD6

102

小键盘 6

VK_NUMPAD7

103

小键盘 7

VK_NUMPAD8

104

小键盘 8

VK_NUMPAD9

105

小键盘 9

VK_MULTIPLY

106

小键盘 *

VK_ADD

107

小键盘 +

VK_SEPARATOR

108

小键盘 Enter

VK_SUBTRACT

109

小键盘 -

VK_DECIMAL

110

小键盘 .

VK_DIVIDE

111

小键盘 /

VK_F1

112

F1

VK_F2

113

F2

VK_F3

114

F3

VK_F4

115

F4

VK_F5

116

F5

VK_F6

117

F6

VK_F7

118

F7

VK_F8

119

F8

VK_F9

120

F9

VK_F10

121

F10

VK_F11

122

F11

VK_F12

123

F12

VK_F13

124

 

VK_F14

125

 

VK_F15

126

 

VK_F16

127

 

VK_F17

128

 

VK_F18

129

 

VK_F19

130

 

VK_F20

131

 

VK_F21

132

 

VK_F22

133

 

VK_F23

134

 

VK_F24

135

 

VK_NUMLOCK

144

Num Lock

VK_SCROLL

145

Scroll

VK_LSHIFT

160

 

VK_RSHIFT

161

 

VK_LCONTROL

162

 

VK_RCONTROL

163

 

VK_LMENU

164

 

VK_RMENU

165

 

VK_BROWSER_BACK

166

 

VK_BROWSER_FORWARD

167

 

VK_BROWSER_REFRESH

168

 

VK_BROWSER_STOP

169

 

VK_BROWSER_SEARCH

170

 

VK_BROWSER_FAVORITES

171

 

VK_BROWSER_HOME

172

 

VK_VOLUME_MUTE

173

VolumeMute

VK_VOLUME_DOWN

174

VolumeDown

VK_VOLUME_UP

175

VolumeUp

VK_MEDIA_NEXT_TRACK

176

 

VK_MEDIA_PREV_TRACK

177

 

VK_MEDIA_STOP

178

 

VK_MEDIA_PLAY_PAUSE

179

 

VK_LAUNCH_MAIL

180

 

VK_LAUNCH_MEDIA_SELECT

181

 

VK_LAUNCH_APP1

182

 

VK_LAUNCH_APP2

183

 

VK_OEM_1

186

; :

VK_OEM_PLUS

187

= +

VK_OEM_COMMA

188

 

VK_OEM_MINUS

189

- _

VK_OEM_PERIOD

190

 

VK_OEM_2

191

/ ?

VK_OEM_3

192

` ~

VK_OEM_4

219

[ {

VK_OEM_5

220

\ |

VK_OEM_6

221

] }

VK_OEM_7

222

' "

VK_OEM_8

223

 

VK_OEM_102

226

 

VK_PACKET

231

 

VK_PROCESSKEY

229

 

VK_ATTN

246

 

VK_CRSEL

247

 

VK_EXSEL

248

 

VK_EREOF

249

 

VK_PLAY

250

 

VK_ZOOM

251

 

VK_NONAME

252

 

VK_PA1

253

 

VK_OEM_CLEAR

254

 
posted @ 2016-07-03 19:49  clairvoyant  阅读(215)  评论(0编辑  收藏  举报