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