glTexGeni()函数为控制纹理坐标的生成。
代码如下,后面有截图,同样修改的部分位于双行星号内。
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 base; // Base display list for the font set 30 GLfloat rot; // Used to rotate the text 31 /******************************************************************************************************************************************/ 32 /******************************************************************************************************************************************/ 33 GLuint texture[1]; 34 35 GLYPHMETRICSFLOAT gmf[256]; // Address buffer for font storage 36 37 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc 38 39 GLvoid BuildFont(GLvoid) 40 { 41 HFONT font; // Windows font ID 42 43 base = glGenLists(256); // Storage for 256 characters 44 45 // The CreateFont function creates a logical font with the specified characteristics. 46 // The logical font can subsequently be selected as the font for any device. 47 font = CreateFont(-12, // Height of font 48 0, // Width of font 49 0, // Angle of escapement 50 0, // Orientation angle 51 FW_BOLD, // Font weight 52 FALSE, // Italic 53 FALSE, // Underline 54 FALSE, // Strikeout 55 SYMBOL_CHARSET, // Character set identifier 56 OUT_TT_PRECIS, // Output precision 57 CLIP_DEFAULT_PRECIS, // Clipping precision 58 ANTIALIASED_QUALITY, // Output quality 59 FF_DONTCARE | DEFAULT_PITCH, // Family and pitch 60 "Wingdings"); // Font name 61 62 // The SelectObject function selects an object into the specified device context (DC). 63 // The new object replaces the previous object of the same type. 64 SelectObject(hDC, font); 65 66 wglUseFontOutlines(hDC, // Select the current DC 67 0, // Starting character 68 255, // Number of display lists of build 69 base, // Starting display lists 70 0.1f, // Deviation from the true outlines 71 0.2f, // font thickness in the Z direction 72 WGL_FONT_POLYGONS, // Use polygons, not lines 73 gmf); // Address of buffer to recive data 74 } 75 76 GLvoid KillFont(GLvoid) 77 { 78 glDeleteLists(base, 256); // Delete all 96 characters 79 } 80 81 GLvoid glPrint(const char* fmt, ...) 82 { 83 float length = 0; // Used to find the length of the text 84 char text[256]; // Holds ours string 85 va_list ap; // Pointer to list of arguments 86 87 if (fmt == NULL) { 88 return; 89 } 90 va_start(ap, fmt); // Parses the string for variables 91 vsprintf(text, fmt, ap); // And converts symbols to actual numbers 92 va_end(ap); // Results are stored in text 93 94 for (unsigned int loop = 0; loop < strlen(text); ++loop) { 95 length += gmf[text[loop]].gmfCellIncX; // Increase length by each character width 96 } 97 glTranslatef(-length / 2, 0.0f, 0.0f); // Center our text on the screen 98 99 glPushAttrib(GL_LIST_BIT); // Pushes the display list bits 100 glListBase(base - 32); // Sets th base charcter to 32 101 102 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);// Draws the display list text 103 glPopAttrib(); // Pops the display list bits 104 } 105 106 107 AUX_RGBImageRec* LoadBMP(char* Filename) 108 { 109 FILE* File = NULL; 110 111 if (!Filename) { 112 return NULL; 113 } 114 115 File = fopen(Filename, "r"); 116 if (File) { 117 fclose(File); 118 return auxDIBImageLoad(Filename); 119 } 120 121 return NULL; 122 } 123 124 int LoadGLTextures() 125 { 126 int Status = FALSE; 127 128 AUX_RGBImageRec* TextureImage[1]; 129 130 memset(TextureImage, 0, sizeof(void*) * 1); 131 132 if (TextureImage[0] = LoadBMP("1.bmp")) { 133 Status = TRUE; 134 glGenTextures(1, &texture[0]); 135 glBindTexture(GL_TEXTURE_2D, texture[0]); 136 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 137 GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 140 // Texturing contour anchored to the object 141 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 142 // GL_S will cover mapping the texture left to right 143 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 144 // GL_T will cover mapping the texture up and down 145 glEnable(GL_TEXTURE_GEN_S); // Auto texture generation 146 glEnable(GL_TEXTURE_GEN_T); // Auto texture generation 147 } 148 149 if (TextureImage[0]) { 150 if (TextureImage[0]->data) { 151 free(TextureImage[0]->data); 152 } 153 free(TextureImage[0]); 154 } 155 return Status; 156 } 157 /******************************************************************************************************************************************/ 158 /******************************************************************************************************************************************/ 159 160 GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window 161 { 162 if (height == 0) { // Prevent a divide by zero by 163 height = 1; // Making height equal one 164 } 165 166 glViewport(0, 0, width, height); // Reset the current viewport 167 168 /* 169 * The following lines set the screen up for a perspective view. 170 * Meaning things in the distance get smaller. This creates a realistic looking scene. 171 * The perspective is calculated with a 45 degree viewing angle based on 172 * the windows width and height. The 0.1f, 100.0f is the starting point and 173 * ending point for how deep we can draw into the screen. 174 * 175 * The projection matrix is responsible for adding perspective to our scene. 176 * glLoadIdentity() restores the selected matrix to it‘s original state. 177 * The modelview matrix is where our object information is stored. 178 * Lastly we reset the modelview matrix. 179 */ 180 181 glMatrixMode(GL_PROJECTION); // Select the projection matrix 182 glLoadIdentity(); // Reset the projection matrix 183 184 // Calculate the aspect ratio of the window 185 gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); 186 187 glMatrixMode(GL_MODELVIEW); // Seclet the modelview matrix 188 glLoadIdentity(); // Reset the modelview matrix 189 } 190 /******************************************************************************************************************************************/ 191 /******************************************************************************************************************************************/ 192 int InitGL(GLvoid) // All setup for OpenGL goes here 193 { 194 /* 195 * Smooth shading blends colors nicely across a polygon, and smoothes out lighting. 196 */ 197 if (!LoadGLTextures()) { 198 return FALSE; 199 } 200 201 glShadeModel(GL_SMOOTH); // Enables smooth shading 202 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background 203 204 glClearDepth(1.0f); // Depth buffer setup 205 206 glDepthFunc(GL_LEQUAL); 207 glEnable(GL_DEPTH_TEST); 208 209 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations 210 211 glEnable(GL_LIGHT0); // Enable default light (quick and dirty) 212 glEnable(GL_LIGHTING); // Enable lighting 213 glEnable(GL_TEXTURE_2D); 214 glBindTexture(GL_TEXTURE_2D, texture[0]); 215 216 BuildFont(); 217 return TRUE; 218 } 219 /* 220 * For now all we will do is clear the screen to the color we previously decided on, 221 * clear the depth buffer and reset the scene. We wont draw anything yet. 222 */ 223 int DrawGLScene(GLvoid) // Here‘s where we do all the drawing 224 { 225 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer 226 glLoadIdentity(); 227 228 glTranslatef(1.1f * float(cos(rot / 116.0f)), 0.8f * float(sin(rot / 120.0f)), -3.0f); 229 230 glRotatef(rot, 1.0f, 0.0f, 0.0f); 231 glRotatef(rot * 1.2f, 0.0f, 1.0f, 0.0f); 232 glRotatef(rot * 1.4f, 0.0f, 0.0f, 1.0f); 233 glTranslatef(-0.35f, -0.35f, 0.1); 234 235 glPrint("n"); // Draw A skull and crossbones symbol 236 rot += 0.05f; 237 return TRUE; // everthing went OK 238 } 239 /******************************************************************************************************************************************/ 240 /******************************************************************************************************************************************/ 241 /* 242 * The job of KillGLWindow() is to release the Rendering Context, 243 * the Device Context and finally the Window Handle. 244 */ 245 246 GLvoid KillGLWindow(GLvoid) // Properly kill the window 247 { 248 if (fullscreen) { // Are we in fullscreen mode 249 250 /* 251 * We use ChangeDisplaySettings(NULL,0) to return us to our original desktop. 252 * After we‘ve switched back to the desktop we make the cursor visible again. 253 */ 254 255 ChangeDisplaySettings(NULL, 0); // if so switch back to the desktop 256 ShowCursor(TRUE); // Show mouse pointer 257 } 258 259 if (hRC) { // Do we have a rendering context 260 if (!wglMakeCurrent(NULL, NULL)) { // Are we able to release the DC and RC contexts 261 MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 262 } 263 264 if (!wglDeleteContext(hRC)) { // Are we able to delete the RC 265 MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 266 hRC = NULL; // Set RC to NULL 267 } 268 269 if (hDC && !ReleaseDC(hWnd, hDC)) { // Are we able to release the DC 270 MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 271 hDC = NULL; // Set DC to NULL 272 } 273 if (hWnd && !DestroyWindow(hWnd)) { // Are we able to destroy the window 274 MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 275 hWnd = NULL; // Set hWnd to NULL 276 } 277 278 if (!UnregisterClass("OpenGL", hInstance)) { // Are we able to unregister class 279 MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 280 hInstance = NULL; // Set hInstance to NULL 281 } 282 } 283 /******************************************************************************************************************************************/ 284 /******************************************************************************************************************************************/ 285 KillFont(); 286 /******************************************************************************************************************************************/ 287 /******************************************************************************************************************************************/ 288 } 289 290 /* 291 * The next section of code creates our OpenGL Window. 292 */ 293 294 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) 295 { 296 /* 297 * Find a pixel format that matches the one we want 298 */ 299 GLuint PixelFormat; // Holds the result after serching for a match 300 301 /* 302 * Before you create a window, you MUST register a Class for the window 303 */ 304 WNDCLASS wc; // Windows class structure 305 306 /* 307 * dwExStyle and dwStyle will store the Extended and normal Window Style Information. 308 */ 309 DWORD dwExStyle; // Window extend style 310 DWORD dwStyle; // Window style 311 312 RECT WindowRect; // Grabs rectangle upper left/lower right values 313 WindowRect.left = (long)0; // Set left value to 0 314 WindowRect.right = (long)width; // Set right value to requested width 315 WindowRect.top = (long)0; // Set top value to 0 316 WindowRect.bottom = (long)height; // Set bottom value to requested height 317 318 fullscreen = fullscreenflag; // Set the global fullscreen flag 319 320 /* 321 * The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized. 322 * CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications. 323 * WndProc is the procedure that watches for messages in our program. 324 * No extra Window data is used so we zero the two fields. Then we set the instance. 325 * Next we set hIcon to NULL meaning we don‘t want an ICON in the Window, 326 * and for a mouse pointer we use the standard arrow. The background color doesn‘t matter 327 * (we set that in GL). We don‘t want a menu in this Window so we set it to NULL, 328 * and the class name can be any name you want. I‘ll use "OpenGL" for simplicity. 329 */ 330 hInstance = GetModuleHandle(NULL); // Grab an instance for our window 331 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on move, and own DC for window 332 wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc handles message 333 wc.cbClsExtra = 0; // No extra window date 334 wc.cbWndExtra = 0; // No extra window date 335 wc.hInstance = hInstance; // set the instance 336 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon 337 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer 338 wc.hbrBackground = NULL; // No background requried for GL 339 wc.lpszMenuName = NULL; // We don‘t want a menu 340 wc.lpszClassName = "OpenGL"; // set the class name 341 342 if (!RegisterClass(&wc)) { // Attempt to register the window class 343 MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 344 return FALSE; // Exit and return false 345 } 346 347 if (fullscreen) { // attempt fullsreen model 348 349 /* 350 T* here are a few very important things you should keep in mind when switching to full screen mode. 351 * Make sure the width and height that you use in fullscreen mode is the same as 352 * the width and height you plan to use for your window, and most importantly, 353 * set fullscreen mode BEFORE you create your window. 354 */ 355 DEVMODE dmScreenSettings; // Device mode 356 memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory‘s cleared 357 dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of devmode structure 358 dmScreenSettings.dmPelsWidth = width; // Select window width 359 dmScreenSettings.dmPelsHeight = height; // Select window height 360 dmScreenSettings.dmBitsPerPel = bits; // Select bits per pixel 361 dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 362 363 /* 364 * In the line below ChangeDisplaySettings tries to switch to a mode that matches 365 * what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes, 366 * because it‘s supposed to remove the start bar at the bottom of the screen, 367 * plus it doesn‘t move or resize the windows on your desktop when you switch to 368 * fullscreen mode and back. 369 */ 370 //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar 371 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { 372 //If the mode fails, offer two options. Quit or run in a window 373 if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use" 374 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) 375 { 376 fullscreen = FALSE; // Select windowed mode (fullscreen=FLASE) 377 } 378 else { 379 // Pop up a message box letting user know the programe is closing. 380 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP); 381 return FALSE; // Exit and return FALSE 382 } 383 } 384 } 385 386 if (fullscreen) { // Are we still in fullscreen mode 387 388 /* 389 * If we are still in fullscreen mode we‘ll set the extended style to WS_EX_APPWINDOW, 390 * which force a top level window down to the taskbar once our window is visible. 391 * For the window style we‘ll create a WS_POPUP window. 392 * This type of window has no border around it, making it perfect for fullscreen mode. 393 394 * Finally, we disable the mouse pointer. If your program is not interactive, 395 * it‘s usually nice to disable the mouse pointer when in fullscreen mode. It‘s up to you though. 396 */ 397 dwExStyle = WS_EX_APPWINDOW; // Window extended style 398 dwStyle = WS_POPUP; // Window style 399 ShowCursor(FALSE); // Hide mosue pointer 400 } 401 else { 402 403 /* 404 * If we‘re using a window instead of fullscreen mode, 405 * we‘ll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look. 406 * For style we‘ll use WS_OVERLAPPEDWINDOW instead of WS_POPUP. 407 * WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border, 408 * window menu, and minimize / maximize buttons. 409 */ 410 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style 411 dwStyle = WS_OVERLAPPEDWINDOW; // Window style 412 } 413 414 /* 415 * By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders, 416 * instead, the window will be made larger to account for the pixels needed to draw the window border. 417 * In fullscreen mode, this command has no effect. 418 */ 419 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust window to true resqusted 420 421 /* 422 * WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly. 423 * These styles prevent other windows from drawing over or into our OpenGL Window. 424 */ 425 if (!(hWnd = CreateWindowEx(dwExStyle, // Extended style for the window 426 "OpenGL", // Class name 427 title, // Window title 428 WS_CLIPSIBLINGS | // Requried window style 429 WS_CLIPCHILDREN | // Requried window style 430 dwStyle, // Select window style 431 0, 0, // Window position 432 WindowRect.right - WindowRect.left, // Calculate adjusted window width 433 WindowRect.bottom - WindowRect.top, // Calculate adjusted window height 434 NULL, // No parent window 435 NULL, // No menu 436 hInstance, // Instance 437 NULL))) // Don‘t pass anything to WM_CREATE 438 { 439 KillGLWindow(); //Reset the display 440 MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 441 return FALSE; // Retrurn FALSE; 442 } 443 444 /* 445 * aside from the stencil buffer and the (slow) accumulation buffer 446 */ 447 static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be 448 { 449 sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor 450 1, // Version number 451 PFD_DRAW_TO_WINDOW | // Format must support window 452 PFD_SUPPORT_OPENGL | // Format must support OpenGL 453 PFD_DOUBLEBUFFER, // Must support double buffer 454 PFD_TYPE_RGBA, // Request an RGBA format 455 bits, // Select our color depth 456 0, 0, 0, 0, 0, 0, // Color bits ignored 457 0, // No alpha buffer 458 0, // shift bit ignored 459 0, // No accumulation buffer 460 0, 0, 0, 0, // Accumulation bits ignored 461 16, // 16Bits Z_Buffer (depth buffer) 462 0, // No stencil buffer 463 0, // No auxiliary buffer 464 PFD_MAIN_PLANE, // Main drawing layer 465 0, // Reserved 466 0, 0, 0 // Layer makes ignored 467 }; 468 469 if (!(hDC = GetDC(hWnd))) { // Did we get a device context 470 KillGLWindow(); // Reset the display 471 MessageBox(NULL, "Can‘t create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 472 return FALSE; // Return FALSE 473 } 474 475 if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { // Did window find a matching pixel format 476 KillGLWindow(); // Reset the display 477 MessageBox(NULL, "Can‘t find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 478 return FALSE; // Return FALSE; 479 } 480 481 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) { // Are we able to set the pixel format 482 KillGLWindow(); // Reset the display 483 MessageBox(NULL, "Can‘t set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 484 return FALSE; // Return FALSE; 485 } 486 487 if (!(hRC = wglCreateContext(hDC))) { // Are we able to rendering context 488 KillGLWindow(); // Reset the display 489 MessageBox(NULL, "Can‘t create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 490 return FALSE; // Return FASLE; 491 } 492 493 if (!wglMakeCurrent(hDC, hRC)) { // Try to activate the rendering context 494 KillGLWindow(); // Reset the display 495 MessageBox(NULL, "Can‘t activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 496 return FALSE; // Return FALSE 497 } 498 499 /* 500 * ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen. 501 */ 502 ShowWindow(hWnd, SW_SHOW); // Show the window 503 SetForegroundWindow(hWnd); // slightly higher priority 504 SetFocus(hWnd); // Sets keyboard focus to the window 505 ReSizeGLScene(width, height); // Set up our perspective GL screen 506 507 /* 508 * we can set up lighting, textures, and anything else that needs to be setup in InitGL(). 509 */ 510 if (!InitGL()) { // Initialize our newly created GL window 511 KillGLWindow(); // Reset the display 512 MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 513 return FALSE; // Return FALSE 514 } 515 return TRUE; 516 } 517 518 LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window 519 UINT uMsg, // Message for this window 520 WPARAM wParam, // Additional message information 521 LPARAM lParam) // Additional message information 522 { 523 switch (uMsg) { // Check for window message 524 case WM_ACTIVATE: { // Check minimization state 525 if (!HIWORD(wParam)) { 526 active = TRUE; // Program is active 527 } 528 else { 529 active = FALSE; // Program is no longer active 530 } 531 return 0; // Return to the message loop 532 } 533 case WM_SYSCOMMAND: { // Intercept system commands 534 switch (wParam) { // Check system calls 535 case SC_SCREENSAVE: // Screensaver trying to start 536 case SC_MONITORPOWER: // Monitor trying to enter powersave 537 return 0; // Prevent form happening 538 } 539 break; // Exit 540 } 541 case WM_CLOSE: { // Did we receive a close message 542 PostQuitMessage(0); // Send a quit message 543 return 0; 544 } 545 case WM_KEYDOWN: { // Is a key being held down 546 keys[wParam] = TRUE; // if so, mark it as TRUE 547 return 0; // Jump back 548 } 549 case WM_KEYUP: { // Has a key been released 550 keys[wParam] = FALSE; // if so, mark it as FALSE 551 return 0; // Jump back 552 } 553 case WM_SIZE: { // Resize the OpenGL window 554 ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord = width HiWord = height 555 return 0; // Jump back 556 } 557 } 558 return DefWindowProc(hWnd, uMsg, wParam, lParam); // Pass all unhandled message to DefWindwProc 559 } 560 561 int WINAPI WinMain(HINSTANCE hInstance, // Instance 562 HINSTANCE hPrevInstance, // Previous instance 563 LPSTR lpCmdLine, // Command line parameters 564 int nCmdShow) // Window show state 565 { 566 MSG msg; // Window message structure 567 BOOL done = FALSE; // Bool variable to exit loop 568 // Ask the user which screen mode they prefer 569 if (MessageBox(NULL, "Would you like to run in fullscreen mode?", 570 "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO) 571 { 572 fullscreen = FALSE; // Window mode 573 } 574 // Create our OpenGL window 575 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { // (Modified) 576 return 0; // Quit if window was not create 577 } 578 579 while (!done) { // Loop that runs until donw = TRUE 580 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Is there a message wating 581 if (msg.message == WM_QUIT) { // Havw we received a quit message 582 done = TRUE; // if so done = TRUE 583 } 584 else { // If not, deal with window message 585 TranslateMessage(&msg); // Translate message 586 DispatchMessage(&msg); // Dispatch message 587 } 588 } 589 else { 590 // Draw the scene. Watch for ESC key and quit message from DrawGLScene() 591 if (active) { // Program active 592 if (keys[VK_ESCAPE]) { // Was ESC pressed 593 done = TRUE; // ESC signalled a quit 594 } 595 else { // Not time to quit, update screen 596 DrawGLScene(); // Draw scene 597 SwapBuffers(hDC); // Swap buffers (double buffering) 598 } 599 } 600 601 /* 602 * It allows us to press the F1 key to switch from fullscreen mode to 603 * windowed mode or windowed mode to fullscreen mode. 604 */ 605 /******************************************************************************************************************************************/ 606 /******************************************************************************************************************************************/ 607 /******************************************************************************************************************************************/ 608 /******************************************************************************************************************************************/ 609 if (keys[VK_F1]) { // Is F1 being pressed 610 keys[VK_F1] = FALSE; // If so make key FASLE 611 KillGLWindow(); // Kill our current window 612 fullscreen = !fullscreen; // Toggle fullscreen / window mode 613 //Recreate our OpenGL window(modified) 614 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { 615 return 0; // Quit if window was not create 616 } 617 } 618 } 619 } 620 // Shutdown 621 KillGLWindow(); // Kill the window 622 return (msg.wParam); // Exit the program 623 }
Thanks for Nehe‘s tutorials, this is his home.
时间: 2024-11-05 00:48:15