outdated: 6.Texture Mapping

第六节有几个坑。

第一个,在VS中有很多函数会报错,因为微软觉得不安全(事实如此)所以替换掉原来的函数让用他们自己的。比如在接下来的这段代码中,用到了fopen(),VS给出了fopen_s(),当然也可以继续使用原生函数,只需要在项目属性中->C/C++->预处理器->预处理定义,添加_CRT_SECURE_NO_WARNINGS即可。

第二个,NeHe的教程我在前面已经说了很老了,所以可能存在编译器版本冲突,需要在开头添加#pragma comment(lib, "legacy_stdio_definitions.lib"),这是stdio.h。

第三个,读bmp图片时,可以拿windows自带的画图工具转换,且不用裁剪大小,转换像素什么的。在添加材质即LoadGLTextures()函数中有

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

即可。

修改的部分在双行星号内。

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

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

posted @ 2016-07-03 13:48  clairvoyant  阅读(185)  评论(0编辑  收藏  举报