标签:
这一章主要是位图的旋转以及灯光的问题,主要的效果为旋转加闪烁(在代码后面会有截图),色彩在代码中为随机生成的,所以看起来是五彩的,不过在旋转过快时会产生亮白效果。闪烁效果按键为T。同以前一样,小键盘的+和-为接近屏幕和远离屏幕。UP键和DOWN为每次增加一定的角度来翻转整个图形。
同样修改位于双行星号内。
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 BOOL light; // Lighting ON/OFF 30 BOOL blend; // Blend ON/OFF 31 BOOL twinkle; // Twinkling stars (new) 32 BOOL tp; // T pressed (new) 33 BOOL lp; // L pressed 34 BOOL fp; // P pressed 35 BOOL bp; // B pressed 36 GLfloat z = -5.0f; // Depth into the screen 37 38 GLfloat LightAmbient[] = {0.5f, 0.5f, 0.5f, 1.0f}; // Ambient light values 39 40 GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; // Diffuse light values 41 42 GLfloat LightPosition[] = {0.0f, 0.0f, 2.0f, 1.0f}; // Light position 43 44 GLuint filter; 45 46 const int num = 50; // (new) 47 typedef struct Start starts; 48 struct Start{ 49 int r, g, b; 50 GLfloat dist; 51 GLfloat angle; 52 }; 53 starts star[num]; 54 55 GLfloat zoom = -15.0f; // Viewing distance away from stars 56 GLfloat tilt = 90.0f; // Tilt view 57 GLfloat spin; // Spin twinkling starts 58 59 GLuint loop; // General loop variable 60 GLuint texture[1]; 61 /******************************************************************************************************************************************/ 62 /******************************************************************************************************************************************/ 63 64 /* 65 * CreateGLWindow() has a reference to WndProc() but WndProc() comes after CreateGLWindow(). 66 */ 67 68 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc 69 70 /* 71 * The job of the next section of code is to resize the OpenGL scene 72 * whenever the window (assuming you are using a Window rather than fullscreen mode) has been resized. 73 */ 74 75 AUX_RGBImageRec* LoadBMP(char* Filename) // Loads a bitmap image 76 { 77 FILE* File = NULL; // File handle 78 79 if (!Filename) { // Make sure a filename was given 80 return NULL; // If not return NULL 81 } 82 83 File = fopen(Filename, "r"); // Check to see of the file exists 84 if (File) { 85 fclose(File); 86 return auxDIBImageLoad(Filename); // Load the bitmap and return a pointer 87 } 88 89 return NULL; 90 } 91 92 int LoadGLTextures() // Load bitmap and convert to texture 93 { 94 int Status = FALSE; // Status indicator 95 96 AUX_RGBImageRec* TextureImage[1]; // Create storage space for the texture 97 98 memset(TextureImage, 0, sizeof(void*)*1); // Set the pointer to NULL 99 100 // Load the bitmap, check for error, if bitmap‘s not found quit 101 if (TextureImage[0] = LoadBMP("1.bmp")) { 102 Status = TRUE; 103 104 glGenTextures(1, &texture[0]); // Create the texture 105 /******************************************************************************************************************************************/ 106 /******************************************************************************************************************************************/ 107 glBindTexture(GL_TEXTURE_2D, texture[0]); 108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear filtering 109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear filtering 110 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, 111 GL_UNSIGNED_BYTE, TextureImage[0]->data); 112 } 113 /******************************************************************************************************************************************/ 114 /******************************************************************************************************************************************/ 115 if (TextureImage[0]) { 116 if (TextureImage[0]->data) { 117 free(TextureImage[0]->data); 118 } 119 free(TextureImage[0]); 120 } 121 return Status; 122 } 123 124 125 GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window 126 { 127 if (height == 0) { // Prevent a divide by zero by 128 height = 1; // Making height equal one 129 } 130 131 glViewport(0, 0, width, height); // Reset the current viewport 132 133 /* 134 * The following lines set the screen up for a perspective view. 135 * Meaning things in the distance get smaller. This creates a realistic looking scene. 136 * The perspective is calculated with a 45 degree viewing angle based on 137 * the windows width and height. The 0.1f, 100.0f is the starting point and 138 * ending point for how deep we can draw into the screen. 139 * 140 * The projection matrix is responsible for adding perspective to our scene. 141 * glLoadIdentity() restores the selected matrix to it‘s original state. 142 * The modelview matrix is where our object information is stored. 143 * Lastly we reset the modelview matrix. 144 */ 145 146 glMatrixMode(GL_PROJECTION); // Select the projection matrix 147 glLoadIdentity(); // Reset the projection matrix 148 149 // Calculate the aspect ratio of the window 150 gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); 151 152 glMatrixMode(GL_MODELVIEW); // Seclet the modelview matrix 153 glLoadIdentity(); // Reset the modelview matrix 154 } 155 156 int InitGL(GLvoid) // All setup for OpenGL goes here 157 { 158 if (!LoadGLTextures()) { // Jump to texture loading routine 159 return FALSE; // If texture didn‘t load return false 160 } 161 glEnable(GL_TEXTURE_2D); // Enable texture mapping 162 /* 163 * Smooth shading blends colors nicely across a polygon, and smoothes out lighting. 164 */ 165 166 glShadeModel(GL_SMOOTH); // Enables smooth shading 167 168 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background 169 /******************************************************************************************************************************************/ 170 /******************************************************************************************************************************************/ 171 /* 172 * Think of the depth buffer as layers into the screen. 173 * The depth buffer keeps track of how deep objects are into the screen. 174 */ 175 176 glClearDepth(1.0f); // Depth buffer setup 177 /* 178 * Next we tell OpenGL we want the best perspective correction to be done. 179 * This causes a very tiny performance hit, but makes the perspective view look a bit better. 180 */ 181 182 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations 183 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 184 glEnable(GL_BLEND); // Enable blend 185 186 for (loop = 0; loop < num; loop++) { 187 star[loop].angle = 0.0f; // Start all the starts at angle zero 188 star[loop].dist = (float(loop) / num)*5.0f; // Calculate distance from the center 189 star[loop].r = rand() % 256; 190 star[loop].g = rand() % 256; 191 star[loop].b = rand() % 256; 192 } 193 return TRUE; 194 } 195 196 /* 197 * For now all we will do is clear the screen to the color we previously decided on, 198 * clear the depth buffer and reset the scene. We wont draw anything yet. 199 */ 200 int DrawGLScene(GLvoid) // Here‘s where we do all the drawing 201 { 202 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer 203 glBindTexture(GL_TEXTURE_2D, texture[0]); 204 205 for (loop = 0; loop < num; ++loop) { 206 glLoadIdentity(); // Reset the current modelview matrix 207 glTranslatef(0.0f, 0.0f, zoom); // Zoom into the screen 208 glRotatef(tilt, 1.0f, 0.0f, 0.0f); // Tilt the view 209 210 glRotatef(star[loop].angle, 0.0f, 1.0f, 0.0f); // Rotate to the current stars angle 211 glTranslatef(star[loop].dist, 0.0f, 0.0f); // Move forward on the X plane 212 213 glRotatef(-star[loop].angle, 0.0f, 1.0f, 0.0f); // Cancel the current stars angle 214 glRotatef(-tilt, 1.0f, 0.0f, 0.0f); // Cancel the screen tilt 215 216 if (twinkle) { // Twinkling stars enable 217 //Assign a color using bytes 218 glColor4ub(star[(num - loop) - 1].r, star[(num - loop) - 1].g, star[(num - loop) - 1].b, 255); 219 glBegin(GL_QUADS); 220 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f); 221 glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); 222 glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); 223 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); 224 glEnd(); 225 } 226 glRotatef(spin, 0.0f, 0.0f, 1.0f); // Rotate the star on the Z axis 227 // Assign a color using bytes 228 glColor4ub(star[loop].r, star[loop].g, star[loop].b, 255); 229 glBegin(GL_QUADS); 230 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f); 231 glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); 232 glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); 233 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); 234 glEnd(); 235 236 spin += 0.01f; // Used to spin the stars 237 star[loop].angle += float(loop) / num; // Changes the angle of a star 238 star[loop].dist -= 0.01f; // Changes the distance of a star 239 240 if (star[loop].dist < 0.0f) { 241 star[loop].dist += 5.0f; 242 star[loop].r = rand() % 256; 243 star[loop].g = rand() % 256; 244 star[loop].b = rand() % 256; 245 } 246 } 247 return TRUE; // everthing went OK 248 } 249 /******************************************************************************************************************************************/ 250 /******************************************************************************************************************************************/ 251 /* 252 * The job of KillGLWindow() is to release the Rendering Context, 253 * the Device Context and finally the Window Handle. 254 */ 255 256 GLvoid KillGLWindow(GLvoid) // Properly kill the window 257 { 258 if (fullscreen) { // Are we in fullscreen mode 259 260 /* 261 * We use ChangeDisplaySettings(NULL,0) to return us to our original desktop. 262 * After we‘ve switched back to the desktop we make the cursor visible again. 263 */ 264 265 ChangeDisplaySettings(NULL, 0); // if so switch back to the desktop 266 ShowCursor(TRUE); // Show mouse pointer 267 } 268 269 if (hRC) { // Do we have a rendering context 270 if (!wglMakeCurrent(NULL, NULL)) { // Are we able to release the DC and RC contexts 271 MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 272 } 273 274 if (!wglDeleteContext(hRC)) { // Are we able to delete the RC 275 MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 276 hRC = NULL; // Set RC to NULL 277 } 278 279 if (hDC && !ReleaseDC(hWnd, hDC)) { // Are we able to release the DC 280 MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 281 hDC = NULL; // Set DC to NULL 282 } 283 if (hWnd && !DestroyWindow(hWnd)) { // Are we able to destroy the window 284 MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 285 hWnd = NULL; // Set hWnd to NULL 286 } 287 288 if (!UnregisterClass("OpenGL", hInstance)) { // Are we able to unregister class 289 MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 290 hInstance = NULL; // Set hInstance to NULL 291 } 292 } 293 } 294 295 /* 296 * The next section of code creates our OpenGL Window. 297 */ 298 299 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) 300 { 301 /* 302 * Find a pixel format that matches the one we want 303 */ 304 GLuint PixelFormat; // Holds the result after serching for a match 305 306 /* 307 * Before you create a window, you MUST register a Class for the window 308 */ 309 WNDCLASS wc; // Windows class structure 310 311 /* 312 * dwExStyle and dwStyle will store the Extended and normal Window Style Information. 313 */ 314 DWORD dwExStyle; // Window extend style 315 DWORD dwStyle; // Window style 316 317 RECT WindowRect; // Grabs rectangle upper left/lower right values 318 WindowRect.left = (long)0; // Set left value to 0 319 WindowRect.right = (long)width; // Set right value to requested width 320 WindowRect.top = (long)0; // Set top value to 0 321 WindowRect.bottom = (long)height; // Set bottom value to requested height 322 323 fullscreen = fullscreenflag; // Set the global fullscreen flag 324 325 /* 326 * The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized. 327 * CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications. 328 * WndProc is the procedure that watches for messages in our program. 329 * No extra Window data is used so we zero the two fields. Then we set the instance. 330 * Next we set hIcon to NULL meaning we don‘t want an ICON in the Window, 331 * and for a mouse pointer we use the standard arrow. The background color doesn‘t matter 332 * (we set that in GL). We don‘t want a menu in this Window so we set it to NULL, 333 * and the class name can be any name you want. I‘ll use "OpenGL" for simplicity. 334 */ 335 hInstance = GetModuleHandle(NULL); // Grab an instance for our window 336 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on move, and own DC for window 337 wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc handles message 338 wc.cbClsExtra = 0; // No extra window date 339 wc.cbWndExtra = 0; // No extra window date 340 wc.hInstance = hInstance; // set the instance 341 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon 342 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer 343 wc.hbrBackground = NULL; // No background requried for GL 344 wc.lpszMenuName = NULL; // We don‘t want a menu 345 wc.lpszClassName = "OpenGL"; // set the class name 346 347 if (!RegisterClass(&wc)) { // Attempt to register the window class 348 MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 349 return FALSE; // Exit and return false 350 } 351 352 if (fullscreen) { // attempt fullsreen model 353 354 /* 355 T* here are a few very important things you should keep in mind when switching to full screen mode. 356 * Make sure the width and height that you use in fullscreen mode is the same as 357 * the width and height you plan to use for your window, and most importantly, 358 * set fullscreen mode BEFORE you create your window. 359 */ 360 DEVMODE dmScreenSettings; // Device mode 361 memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory‘s cleared 362 dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of devmode structure 363 dmScreenSettings.dmPelsWidth = width; // Select window width 364 dmScreenSettings.dmPelsHeight = height; // Select window height 365 dmScreenSettings.dmBitsPerPel = bits; // Select bits per pixel 366 dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 367 368 /* 369 * In the line below ChangeDisplaySettings tries to switch to a mode that matches 370 * what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes, 371 * because it‘s supposed to remove the start bar at the bottom of the screen, 372 * plus it doesn‘t move or resize the windows on your desktop when you switch to 373 * fullscreen mode and back. 374 */ 375 //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar 376 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { 377 //If the mode fails, offer two options. Quit or run in a window 378 if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use" 379 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) 380 { 381 fullscreen = FALSE; // Select windowed mode (fullscreen=FLASE) 382 } 383 else { 384 // Pop up a message box letting user know the programe is closing. 385 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP); 386 return FALSE; // Exit and return FALSE 387 } 388 } 389 } 390 391 if (fullscreen) { // Are we still in fullscreen mode 392 393 /* 394 * If we are still in fullscreen mode we‘ll set the extended style to WS_EX_APPWINDOW, 395 * which force a top level window down to the taskbar once our window is visible. 396 * For the window style we‘ll create a WS_POPUP window. 397 * This type of window has no border around it, making it perfect for fullscreen mode. 398 399 * Finally, we disable the mouse pointer. If your program is not interactive, 400 * it‘s usually nice to disable the mouse pointer when in fullscreen mode. It‘s up to you though. 401 */ 402 dwExStyle = WS_EX_APPWINDOW; // Window extended style 403 dwStyle = WS_POPUP; // Window style 404 ShowCursor(FALSE); // Hide mosue pointer 405 } 406 else { 407 408 /* 409 * If we‘re using a window instead of fullscreen mode, 410 * we‘ll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look. 411 * For style we‘ll use WS_OVERLAPPEDWINDOW instead of WS_POPUP. 412 * WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border, 413 * window menu, and minimize / maximize buttons. 414 */ 415 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style 416 dwStyle = WS_OVERLAPPEDWINDOW; // Window style 417 } 418 419 /* 420 * By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders, 421 * instead, the window will be made larger to account for the pixels needed to draw the window border. 422 * In fullscreen mode, this command has no effect. 423 */ 424 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust window to true resqusted 425 426 /* 427 * WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly. 428 * These styles prevent other windows from drawing over or into our OpenGL Window. 429 */ 430 if (!(hWnd = CreateWindowEx(dwExStyle, // Extended style for the window 431 "OpenGL", // Class name 432 title, // Window title 433 WS_CLIPSIBLINGS | // Requried window style 434 WS_CLIPCHILDREN | // Requried window style 435 dwStyle, // Select window style 436 0, 0, // Window position 437 WindowRect.right - WindowRect.left, // Calculate adjusted window width 438 WindowRect.bottom - WindowRect.top, // Calculate adjusted window height 439 NULL, // No parent window 440 NULL, // No menu 441 hInstance, // Instance 442 NULL))) // Don‘t pass anything to WM_CREATE 443 { 444 KillGLWindow(); //Reset the display 445 MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 446 return FALSE; // Retrurn FALSE; 447 } 448 449 /* 450 * aside from the stencil buffer and the (slow) accumulation buffer 451 */ 452 static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be 453 { 454 sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor 455 1, // Version number 456 PFD_DRAW_TO_WINDOW | // Format must support window 457 PFD_SUPPORT_OPENGL | // Format must support OpenGL 458 PFD_DOUBLEBUFFER, // Must support double buffer 459 PFD_TYPE_RGBA, // Request an RGBA format 460 bits, // Select our color depth 461 0, 0, 0, 0, 0, 0, // Color bits ignored 462 0, // No alpha buffer 463 0, // shift bit ignored 464 0, // No accumulation buffer 465 0, 0, 0, 0, // Accumulation bits ignored 466 16, // 16Bits Z_Buffer (depth buffer) 467 0, // No stencil buffer 468 0, // No auxiliary buffer 469 PFD_MAIN_PLANE, // Main drawing layer 470 0, // Reserved 471 0, 0, 0 // Layer makes ignored 472 }; 473 474 if (!(hDC = GetDC(hWnd))) { // Did we get a device context 475 KillGLWindow(); // Reset the display 476 MessageBox(NULL, "Can‘t create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 477 return FALSE; // Return FALSE 478 } 479 480 if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { // Did window find a matching pixel format 481 KillGLWindow(); // Reset the display 482 MessageBox(NULL, "Can‘t find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 483 return FALSE; // Return FALSE; 484 } 485 486 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) { // Are we able to set the pixel format 487 KillGLWindow(); // Reset the display 488 MessageBox(NULL, "Can‘t set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 489 return FALSE; // Return FALSE; 490 } 491 492 if (!(hRC = wglCreateContext(hDC))) { // Are we able to rendering context 493 KillGLWindow(); // Reset the display 494 MessageBox(NULL, "Can‘t create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 495 return FALSE; // Return FASLE; 496 } 497 498 if (!wglMakeCurrent(hDC, hRC)) { // Try to activate the rendering context 499 KillGLWindow(); // Reset the display 500 MessageBox(NULL, "Can‘t activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 501 return FALSE; // Return FALSE 502 } 503 504 /* 505 * ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen. 506 */ 507 ShowWindow(hWnd, SW_SHOW); // Show the window 508 SetForegroundWindow(hWnd); // slightly higher priority 509 SetFocus(hWnd); // Sets keyboard focus to the window 510 ReSizeGLScene(width, height); // Set up our perspective GL screen 511 512 /* 513 * we can set up lighting, textures, and anything else that needs to be setup in InitGL(). 514 */ 515 if (!InitGL()) { // Initialize our newly created GL window 516 KillGLWindow(); // Reset the display 517 MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 518 return FALSE; // Return FALSE 519 } 520 return TRUE; 521 } 522 523 LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window 524 UINT uMsg, // Message for this window 525 WPARAM wParam, // Additional message information 526 LPARAM lParam) // Additional message information 527 { 528 switch (uMsg) { // Check for window message 529 case WM_ACTIVATE: { // Check minimization state 530 if (!HIWORD(wParam)) { 531 active = TRUE; // Program is active 532 } 533 else { 534 active = FALSE; // Program is no longer active 535 } 536 return 0; // Return to the message loop 537 } 538 case WM_SYSCOMMAND: { // Intercept system commands 539 switch (wParam) { // Check system calls 540 case SC_SCREENSAVE: // Screensaver trying to start 541 case SC_MONITORPOWER: // Monitor trying to enter powersave 542 return 0; // Prevent form happening 543 } 544 break; // Exit 545 } 546 case WM_CLOSE: { // Did we receive a close message 547 PostQuitMessage(0); // Send a quit message 548 return 0; 549 } 550 case WM_KEYDOWN: { // Is a key being held down 551 keys[wParam] = TRUE; // if so, mark it as TRUE 552 return 0; // Jump back 553 } 554 case WM_KEYUP: { // Has a key been released 555 keys[wParam] = FALSE; // if so, mark it as FALSE 556 return 0; // Jump back 557 } 558 case WM_SIZE: { // Resize the OpenGL window 559 ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord = width HiWord = height 560 return 0; // Jump back 561 } 562 } 563 return DefWindowProc(hWnd, uMsg, wParam, lParam); // Pass all unhandled message to DefWindwProc 564 } 565 566 int WINAPI WinMain(HINSTANCE hInstance, // Instance 567 HINSTANCE hPrevInstance, // Previous instance 568 LPSTR lpCmdLine, // Command line parameters 569 int nCmdShow) // Window show state 570 { 571 MSG msg; // Window message structure 572 BOOL done = FALSE; // Bool variable to exit loop 573 // Ask the user which screen mode they prefer 574 if (MessageBox(NULL, "Would you like to run in fullscreen mode?", 575 "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO) 576 { 577 fullscreen = FALSE; // Window mode 578 } 579 // Create our OpenGL window 580 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { // (Modified) 581 return 0; // Quit if window was not create 582 } 583 584 while (!done) { // Loop that runs until donw = TRUE 585 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Is there a message wating 586 if (msg.message == WM_QUIT) { // Havw we received a quit message 587 done = TRUE; // if so done = TRUE 588 } 589 else { // If not, deal with window message 590 TranslateMessage(&msg); // Translate message 591 DispatchMessage(&msg); // Dispatch message 592 } 593 } 594 else { 595 // Draw the scene. Watch for ESC key and quit message from DrawGLScene() 596 if (active) { // Program active 597 if (keys[VK_ESCAPE]) { // Was ESC pressed 598 done = TRUE; // ESC signalled a quit 599 } 600 else { // Not time to quit, update screen 601 DrawGLScene(); // Draw scene 602 SwapBuffers(hDC); // Swap buffers (double buffering) 603 } 604 } 605 606 /* 607 * It allows us to press the F1 key to switch from fullscreen mode to 608 * windowed mode or windowed mode to fullscreen mode. 609 */ 610 611 if (keys[‘L‘] && !lp) { // L key being pressed not held 612 lp = TRUE; // lp become TRUE 613 light = !light; // Toggle light TRUE/FALSE 614 615 if (!light) { 616 glDisable(GL_LIGHTING); // Disable light 617 } 618 else { 619 glEnable(GL_LIGHTING); // Enable light 620 } 621 } 622 623 if (!keys[‘L‘]) { 624 lp = FALSE; 625 } 626 if (keys[‘F‘] && !fp) { 627 fp = TRUE; 628 filter += 1; 629 if (filter > 2) { 630 filter = 0; 631 } 632 } 633 if (!keys[‘F‘]) { 634 fp = FALSE; 635 } 636 /******************************************************************************************************************************************/ 637 /******************************************************************************************************************************************/ 638 if (keys[VK_SUBTRACT]) { //VK_PRIOR 639 zoom -= 0.02f; 640 } 641 if (keys[VK_ADD]) { // VK_NEXT 642 zoom += 0.02f; 643 } 644 if (keys[‘T‘] && !tp) { 645 tp = TRUE; 646 twinkle = !twinkle; 647 } 648 if (!keys[‘T‘]) { 649 tp = FALSE; 650 } 651 if (keys[VK_UP]) { 652 tilt -= 0.1f; 653 } 654 if (keys[VK_DOWN]) { 655 tilt += 0.1f; 656 } 657 /******************************************************************************************************************************************/ 658 /******************************************************************************************************************************************/ 659 if (keys[‘B‘] && !bp) { 660 bp = TRUE; 661 blend = !blend; 662 if (blend) { 663 glEnable(GL_BLEND); 664 glDisable(GL_DEPTH_TEST); 665 } 666 else { 667 glDisable(GL_BLEND); 668 glEnable(GL_DEPTH_TEST); 669 } 670 } 671 if (keys[‘B‘]) { 672 bp = FALSE; 673 } 674 if (keys[VK_F1]) { // Is F1 being pressed 675 keys[VK_F1] = FALSE; // If so make key FASLE 676 KillGLWindow(); // Kill our current window 677 fullscreen = !fullscreen; // Toggle fullscreen / window mode 678 //Recreate our OpenGL window(modified) 679 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { 680 return 0; // Quit if window was not create 681 } 682 } 683 } 684 } 685 // Shutdown 686 KillGLWindow(); // Kill the window 687 return (msg.wParam); // Exit the program 688 }
这是没有开闪烁效果的截图:
这是按下T之后的截图:
很明显的增亮了许多。
当然在数量(num)增加到200时(不能更多了。。。),画方块的话,到最后就是个纯白的圆,和和面一样。换成线条或者点看起来还是不错的。
这是num为200时的点图。
num为200时的线图,因为每秒帧数太高,看起来漂亮,但截图截的只是一团子线了,想要看得可以自己亲手试试。
为了能细细观察它是怎么变化的,我就在循环中写了个延迟。下图为num为200时的线图:
outdated: 9.Moving Bitmaps In 3D Space
标签:
原文地址:http://www.cnblogs.com/clairvoyant/p/5644719.html