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