outdated: 18.Quadrics

quadratic可以做许多有趣的事,在声明全局变量时,GLUquadricObj为quadratic(二次曲面)的指针。在InitGL()函数中,glLightfv()函数已经见过好多次了,镜面反射,光线追踪都需要用到。gluNewQuadric()函数创建一个quadratic。gluQuadricNormals()函数选择一个none/smooth/flat标准。gluQuadricTexture()函数为quadratic设置贴图纹理。

这次绘制了六种quadratic,Cube、Cylinder、Disk、Sphere、Cone和PartialDisk。都有对应的函数,gluCylinder()gluSphere()gluCylinder()gluDisk()gluPartialDisk()

gluDeleteQuadric()函数在KillGLWindow()函数时删除quadratic。

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

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

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

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