outdated: 23.Sphere Mapping Quadrics In OpenGL

这一章是在18章的基础上建立的,主要说的是镜面反射。

使用两张相同的图片,对scene和object实现贴图。

在InitGL()函数中,gluNewQuadric()创建一个曲面物体指针赋给quadratic。gluQuadricNormals()函数设置法线风格,默认为GLU_SMOOTH,对每个顶点都计算法线向量。gluQuadricTexture()函数设置纹理,默认为GL_FALSE。

转换灯源效果后:

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

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

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

posted @ 2016-07-29 13:17  clairvoyant  阅读(198)  评论(0编辑  收藏  举报