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