outdated: 12.Display Lists

若同样的物体需要创建多次时,并在不同的位置,且需要不同的着色etc,同时不能太麻烦......该怎么弄?

显示列表,它不仅会加快速度,而且会减少代码量。通过显示列表,一个物体只被创建一次,且可以纹理贴图,着色etc。需要用到这个物体时,只需要glCallList()就可以了。

下面这段代码不仅可以创建棱锥,也可以画了一个心形,公式来源。代码的238行给出了心形的绘制法,不过放在注释里,只需把紧挨上面那块代码,即221行至234行替换掉即可,有任何好的画法请留言。

棱锥:

心形:

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

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

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

posted @ 2016-07-08 20:18  clairvoyant  阅读(203)  评论(0编辑  收藏  举报