quadratic可以做许多有趣的事,在声明全局变量时,GLUquadricObj为quadratic(二次曲面)的指针。在InitGL()函数中,glLightfv()函数已经见过好多次了,镜面反射,光线追踪都需要用到。gluNewQuadric()函数创建一个quadratic。gluQuadricNormals()函数选择一个none/smooth/flat标准。gluQuadricTexture()函数为quadratic设置贴图纹理。
这次绘制了六种quadratic,Cube、Cylinder、Disk、Sphere、Cone和PartialDisk。都有对应的函数,gluCylinder()、gluSphere()、gluCylinder()、gluDisk()、gluPartialDisk()。
gluDeleteQuadric()函数在KillGLWindow()函数时删除quadratic。
代码如下,同样修改部分位于双行星号内。
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 /******************************************************************************************************************************************/ 30 /******************************************************************************************************************************************/ 31 bool light; 32 bool lp; 33 bool fp; 34 bool sp; // Spacebar pressed 35 36 int part1; // Start of disc 37 int part2; // End of disc 38 int p1 = 0; // Increase 1 39 int p2 = 1; // Increase 2 40 41 GLfloat xrot; 42 GLfloat yrot; 43 GLfloat xspeed; 44 GLfloat yspeed; 45 46 GLfloat z = -5.0f; 47 48 GLUquadricObj * quadratic; // Storage for our quadratic objects 49 50 GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; 51 GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 52 GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; 53 54 GLuint filter; 55 GLuint texture[3]; 56 GLuint object = 0; 57 /******************************************************************************************************************************************/ 58 /******************************************************************************************************************************************/ 59 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc 60 61 AUX_RGBImageRec* LoadBMP(char* Filename) 62 { 63 FILE* File = NULL; 64 65 if (!Filename) { 66 return NULL; 67 } 68 69 File = fopen(Filename, "r"); 70 if (File) { 71 fclose(File); 72 return auxDIBImageLoad(Filename); 73 } 74 75 return NULL; 76 } 77 78 int LoadGLTextures() 79 { 80 int Status = FALSE; 81 82 /******************************************************************************************************************************************/ 83 /******************************************************************************************************************************************/ 84 AUX_RGBImageRec* TextureImage[2]; 85 86 memset(TextureImage, 0, sizeof(void*) * 2); 87 88 if (TextureImage[0] = LoadBMP("1.bmp")) { 89 Status = TRUE; 90 glGenTextures(3, &texture[0]); 91 92 glBindTexture(GL_TEXTURE_2D, texture[0]); 93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 95 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 96 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 97 98 glBindTexture(GL_TEXTURE_2D, texture[1]); 99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 101 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 102 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 103 104 glBindTexture(GL_TEXTURE_2D, texture[2]); 105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 107 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 108 GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 109 } 110 111 if (TextureImage[0]) { 112 if (TextureImage[0]->data) { 113 free(TextureImage[0]->data); 114 } 115 free(TextureImage[0]); 116 } 117 return Status; 118 } 119 /******************************************************************************************************************************************/ 120 /******************************************************************************************************************************************/ 121 GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window 122 { 123 if (height == 0) { // Prevent a divide by zero by 124 height = 1; // Making height equal one 125 } 126 127 glViewport(0, 0, width, height); // Reset the current viewport 128 129 /* 130 * The following lines set the screen up for a perspective view. 131 * Meaning things in the distance get smaller. This creates a realistic looking scene. 132 * The perspective is calculated with a 45 degree viewing angle based on 133 * the windows width and height. The 0.1f, 100.0f is the starting point and 134 * ending point for how deep we can draw into the screen. 135 * 136 * The projection matrix is responsible for adding perspective to our scene. 137 * glLoadIdentity() restores the selected matrix to it‘s original state. 138 * The modelview matrix is where our object information is stored. 139 * Lastly we reset the modelview matrix. 140 */ 141 142 glMatrixMode(GL_PROJECTION); // Select the projection matrix 143 glLoadIdentity(); // Reset the projection matrix 144 145 // Calculate the aspect ratio of the window 146 gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); 147 148 glMatrixMode(GL_MODELVIEW); // Seclet the modelview matrix 149 glLoadIdentity(); // Reset the modelview matrix 150 } 151 /******************************************************************************************************************************************/ 152 /******************************************************************************************************************************************/ 153 int InitGL(GLvoid) // All setup for OpenGL goes here 154 { 155 /* 156 * Smooth shading blends colors nicely across a polygon, and smoothes out lighting. 157 */ 158 159 if (!LoadGLTextures()) { 160 return FALSE; 161 } 162 163 glEnable(GL_TEXTURE_2D); 164 glShadeModel(GL_SMOOTH); // Enables smooth shading 165 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black background 166 167 glClearDepth(1.0f); // Depth buffer setup 168 169 glDepthFunc(GL_LEQUAL); 170 glEnable(GL_DEPTH_TEST); 171 172 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 173 174 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); 175 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); 176 glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); 177 178 glEnable(GL_LIGHT1); 179 180 quadratic = gluNewQuadric(); // Create a pointer to the quadratic object 181 gluQuadricNormals(quadratic, GLU_SMOOTH); // Create smooth normals 182 gluQuadricTexture(quadratic, GL_TRUE); // Create texture coords 183 184 return TRUE; 185 } 186 187 GLvoid glDrawCube() 188 { 189 glBegin(GL_QUADS); 190 // Front face 191 glNormal3f(0.0f, 0.0f, 0.0f); 192 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 193 glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 194 glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad 195 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad 196 // Back Face 197 glNormal3f(0.0f, 0.0f, -1.0f); 198 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad 199 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 200 glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 201 glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad 202 // Top Face 203 glNormal3f(0.0f, 1.0f, 0.0f); 204 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 205 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad 206 glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad 207 glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 208 // Bottom Face 209 glNormal3f(0.0f, -1.0f, 0.0f); 210 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad 211 glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad 212 glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 213 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 214 // Right face 215 glNormal3f(1.0f, 0.0f, 0.0f); 216 glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad 217 glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 218 glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad 219 glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 220 // Left Face 221 glNormal3f(-1.0f, 0.0f, 0.0f); 222 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad 223 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 224 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad 225 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 226 glEnd(); 227 } 228 229 /* 230 * For now all we will do is clear the screen to the color we previously decided on, 231 * clear the depth buffer and reset the scene. We wont draw anything yet. 232 */ 233 int DrawGLScene(GLvoid) // Here‘s where we do all the drawing 234 { 235 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer 236 glLoadIdentity(); 237 238 glTranslatef(0.0f, 0.0f, z-10.0f); 239 240 glBindTexture(GL_TEXTURE_2D, texture[filter]); 241 242 glRotatef(xrot+95.0f, 1.0f, 0.0f, 0.0f); 243 glRotatef(yrot, 0.0f, 1.0f, 0.0f); 244 245 switch(object) { 246 case 0: 247 glDrawCube(); break; // Cube 248 case 1: 249 glTranslatef(0.0f, 0.0f, -1.5f); 250 gluCylinder(quadratic, 1.0f, 1.0f, 3.0f, 32, 32); break; // Cylinder 251 case 2: 252 gluDisk(quadratic, 3.0f, 3.5f, 32, 32); break; // Disk 253 case 3: 254 gluSphere(quadratic, 1.3f, 32, 32); break; // Sphere 255 case 4: 256 glTranslatef(0.0f, 0.0f, -1.5f); 257 gluCylinder(quadratic, 1.0f, 0.0f, 3.0, 32, 32); break; // Cone 258 case 5: 259 part1 += p1; 260 part2 += p2; 261 262 if (part1 > 359) { 263 p1 = 0; 264 part1 = 0; 265 p2 = 1; 266 part2 = 0; 267 } 268 if (part2 > 359) { 269 p1 = 1; 270 p2 = 0; 271 } 272 gluPartialDisk(quadratic, 0.5f, 1.5f, 32, 32, part1, part2 - part1); break; 273 } 274 275 xrot += xspeed; 276 yrot += yspeed; 277 278 return TRUE; // everthing went OK 279 } 280 /******************************************************************************************************************************************/ 281 /******************************************************************************************************************************************/ 282 /* 283 * The job of KillGLWindow() is to release the Rendering Context, 284 * the Device Context and finally the Window Handle. 285 */ 286 287 GLvoid KillGLWindow(GLvoid) // Properly kill the window 288 { 289 if (fullscreen) { // Are we in fullscreen mode 290 291 /* 292 * We use ChangeDisplaySettings(NULL,0) to return us to our original desktop. 293 * After we‘ve switched back to the desktop we make the cursor visible again. 294 */ 295 296 ChangeDisplaySettings(NULL, 0); // if so switch back to the desktop 297 ShowCursor(TRUE); // Show mouse pointer 298 } 299 300 if (hRC) { // Do we have a rendering context 301 if (!wglMakeCurrent(NULL, NULL)) { // Are we able to release the DC and RC contexts 302 MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 303 } 304 305 if (!wglDeleteContext(hRC)) { // Are we able to delete the RC 306 MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 307 hRC = NULL; // Set RC to NULL 308 } 309 310 if (hDC && !ReleaseDC(hWnd, hDC)) { // Are we able to release the DC 311 MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 312 hDC = NULL; // Set DC to NULL 313 } 314 if (hWnd && !DestroyWindow(hWnd)) { // Are we able to destroy the window 315 MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 316 hWnd = NULL; // Set hWnd to NULL 317 } 318 319 if (!UnregisterClass("OpenGL", hInstance)) { // Are we able to unregister class 320 MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); 321 hInstance = NULL; // Set hInstance to NULL 322 } 323 } 324 /******************************************************************************************************************************************/ 325 /******************************************************************************************************************************************/ 326 gluDeleteQuadric(quadratic); 327 /******************************************************************************************************************************************/ 328 /******************************************************************************************************************************************/ 329 } 330 331 /* 332 * The next section of code creates our OpenGL Window. 333 */ 334 335 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) 336 { 337 /* 338 * Find a pixel format that matches the one we want 339 */ 340 GLuint PixelFormat; // Holds the result after serching for a match 341 342 /* 343 * Before you create a window, you MUST register a Class for the window 344 */ 345 WNDCLASS wc; // Windows class structure 346 347 /* 348 * dwExStyle and dwStyle will store the Extended and normal Window Style Information. 349 */ 350 DWORD dwExStyle; // Window extend style 351 DWORD dwStyle; // Window style 352 353 RECT WindowRect; // Grabs rectangle upper left/lower right values 354 WindowRect.left = (long)0; // Set left value to 0 355 WindowRect.right = (long)width; // Set right value to requested width 356 WindowRect.top = (long)0; // Set top value to 0 357 WindowRect.bottom = (long)height; // Set bottom value to requested height 358 359 fullscreen = fullscreenflag; // Set the global fullscreen flag 360 361 /* 362 * The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized. 363 * CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications. 364 * WndProc is the procedure that watches for messages in our program. 365 * No extra Window data is used so we zero the two fields. Then we set the instance. 366 * Next we set hIcon to NULL meaning we don‘t want an ICON in the Window, 367 * and for a mouse pointer we use the standard arrow. The background color doesn‘t matter 368 * (we set that in GL). We don‘t want a menu in this Window so we set it to NULL, 369 * and the class name can be any name you want. I‘ll use "OpenGL" for simplicity. 370 */ 371 hInstance = GetModuleHandle(NULL); // Grab an instance for our window 372 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on move, and own DC for window 373 wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc handles message 374 wc.cbClsExtra = 0; // No extra window date 375 wc.cbWndExtra = 0; // No extra window date 376 wc.hInstance = hInstance; // set the instance 377 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon 378 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer 379 wc.hbrBackground = NULL; // No background requried for GL 380 wc.lpszMenuName = NULL; // We don‘t want a menu 381 wc.lpszClassName = "OpenGL"; // set the class name 382 383 if (!RegisterClass(&wc)) { // Attempt to register the window class 384 MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 385 return FALSE; // Exit and return false 386 } 387 388 if (fullscreen) { // attempt fullsreen model 389 390 /* 391 T* here are a few very important things you should keep in mind when switching to full screen mode. 392 * Make sure the width and height that you use in fullscreen mode is the same as 393 * the width and height you plan to use for your window, and most importantly, 394 * set fullscreen mode BEFORE you create your window. 395 */ 396 DEVMODE dmScreenSettings; // Device mode 397 memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory‘s cleared 398 dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of devmode structure 399 dmScreenSettings.dmPelsWidth = width; // Select window width 400 dmScreenSettings.dmPelsHeight = height; // Select window height 401 dmScreenSettings.dmBitsPerPel = bits; // Select bits per pixel 402 dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 403 404 /* 405 * In the line below ChangeDisplaySettings tries to switch to a mode that matches 406 * what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes, 407 * because it‘s supposed to remove the start bar at the bottom of the screen, 408 * plus it doesn‘t move or resize the windows on your desktop when you switch to 409 * fullscreen mode and back. 410 */ 411 //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar 412 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { 413 //If the mode fails, offer two options. Quit or run in a window 414 if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use" 415 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) 416 { 417 fullscreen = FALSE; // Select windowed mode (fullscreen=FLASE) 418 } 419 else { 420 // Pop up a message box letting user know the programe is closing. 421 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP); 422 return FALSE; // Exit and return FALSE 423 } 424 } 425 } 426 427 if (fullscreen) { // Are we still in fullscreen mode 428 429 /* 430 * If we are still in fullscreen mode we‘ll set the extended style to WS_EX_APPWINDOW, 431 * which force a top level window down to the taskbar once our window is visible. 432 * For the window style we‘ll create a WS_POPUP window. 433 * This type of window has no border around it, making it perfect for fullscreen mode. 434 435 * Finally, we disable the mouse pointer. If your program is not interactive, 436 * it‘s usually nice to disable the mouse pointer when in fullscreen mode. It‘s up to you though. 437 */ 438 dwExStyle = WS_EX_APPWINDOW; // Window extended style 439 dwStyle = WS_POPUP; // Window style 440 ShowCursor(FALSE); // Hide mosue pointer 441 } 442 else { 443 444 /* 445 * If we‘re using a window instead of fullscreen mode, 446 * we‘ll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look. 447 * For style we‘ll use WS_OVERLAPPEDWINDOW instead of WS_POPUP. 448 * WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border, 449 * window menu, and minimize / maximize buttons. 450 */ 451 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style 452 dwStyle = WS_OVERLAPPEDWINDOW; // Window style 453 } 454 455 /* 456 * By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders, 457 * instead, the window will be made larger to account for the pixels needed to draw the window border. 458 * In fullscreen mode, this command has no effect. 459 */ 460 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust window to true resqusted 461 462 /* 463 * WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly. 464 * These styles prevent other windows from drawing over or into our OpenGL Window. 465 */ 466 if (!(hWnd = CreateWindowEx(dwExStyle, // Extended style for the window 467 "OpenGL", // Class name 468 title, // Window title 469 WS_CLIPSIBLINGS | // Requried window style 470 WS_CLIPCHILDREN | // Requried window style 471 dwStyle, // Select window style 472 0, 0, // Window position 473 WindowRect.right - WindowRect.left, // Calculate adjusted window width 474 WindowRect.bottom - WindowRect.top, // Calculate adjusted window height 475 NULL, // No parent window 476 NULL, // No menu 477 hInstance, // Instance 478 NULL))) // Don‘t pass anything to WM_CREATE 479 { 480 KillGLWindow(); //Reset the display 481 MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 482 return FALSE; // Retrurn FALSE; 483 } 484 485 /* 486 * aside from the stencil buffer and the (slow) accumulation buffer 487 */ 488 static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be 489 { 490 sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor 491 1, // Version number 492 PFD_DRAW_TO_WINDOW | // Format must support window 493 PFD_SUPPORT_OPENGL | // Format must support OpenGL 494 PFD_DOUBLEBUFFER, // Must support double buffer 495 PFD_TYPE_RGBA, // Request an RGBA format 496 bits, // Select our color depth 497 0, 0, 0, 0, 0, 0, // Color bits ignored 498 0, // No alpha buffer 499 0, // shift bit ignored 500 0, // No accumulation buffer 501 0, 0, 0, 0, // Accumulation bits ignored 502 16, // 16Bits Z_Buffer (depth buffer) 503 0, // No stencil buffer 504 0, // No auxiliary buffer 505 PFD_MAIN_PLANE, // Main drawing layer 506 0, // Reserved 507 0, 0, 0 // Layer makes ignored 508 }; 509 510 if (!(hDC = GetDC(hWnd))) { // Did we get a device context 511 KillGLWindow(); // Reset the display 512 MessageBox(NULL, "Can‘t create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 513 return FALSE; // Return FALSE 514 } 515 516 if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { // Did window find a matching pixel format 517 KillGLWindow(); // Reset the display 518 MessageBox(NULL, "Can‘t find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 519 return FALSE; // Return FALSE; 520 } 521 522 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) { // Are we able to set the pixel format 523 KillGLWindow(); // Reset the display 524 MessageBox(NULL, "Can‘t set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 525 return FALSE; // Return FALSE; 526 } 527 528 if (!(hRC = wglCreateContext(hDC))) { // Are we able to rendering context 529 KillGLWindow(); // Reset the display 530 MessageBox(NULL, "Can‘t create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 531 return FALSE; // Return FASLE; 532 } 533 534 if (!wglMakeCurrent(hDC, hRC)) { // Try to activate the rendering context 535 KillGLWindow(); // Reset the display 536 MessageBox(NULL, "Can‘t activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 537 return FALSE; // Return FALSE 538 } 539 540 /* 541 * ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen. 542 */ 543 ShowWindow(hWnd, SW_SHOW); // Show the window 544 SetForegroundWindow(hWnd); // slightly higher priority 545 SetFocus(hWnd); // Sets keyboard focus to the window 546 ReSizeGLScene(width, height); // Set up our perspective GL screen 547 548 /* 549 * we can set up lighting, textures, and anything else that needs to be setup in InitGL(). 550 */ 551 if (!InitGL()) { // Initialize our newly created GL window 552 KillGLWindow(); // Reset the display 553 MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); 554 return FALSE; // Return FALSE 555 } 556 return TRUE; 557 } 558 559 LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window 560 UINT uMsg, // Message for this window 561 WPARAM wParam, // Additional message information 562 LPARAM lParam) // Additional message information 563 { 564 switch (uMsg) { // Check for window message 565 case WM_ACTIVATE: { // Check minimization state 566 if (!HIWORD(wParam)) { 567 active = TRUE; // Program is active 568 } 569 else { 570 active = FALSE; // Program is no longer active 571 } 572 return 0; // Return to the message loop 573 } 574 case WM_SYSCOMMAND: { // Intercept system commands 575 switch (wParam) { // Check system calls 576 case SC_SCREENSAVE: // Screensaver trying to start 577 case SC_MONITORPOWER: // Monitor trying to enter powersave 578 return 0; // Prevent form happening 579 } 580 break; // Exit 581 } 582 case WM_CLOSE: { // Did we receive a close message 583 PostQuitMessage(0); // Send a quit message 584 return 0; 585 } 586 case WM_KEYDOWN: { // Is a key being held down 587 keys[wParam] = TRUE; // if so, mark it as TRUE 588 return 0; // Jump back 589 } 590 case WM_KEYUP: { // Has a key been released 591 keys[wParam] = FALSE; // if so, mark it as FALSE 592 return 0; // Jump back 593 } 594 case WM_SIZE: { // Resize the OpenGL window 595 ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord = width HiWord = height 596 return 0; // Jump back 597 } 598 } 599 return DefWindowProc(hWnd, uMsg, wParam, lParam); // Pass all unhandled message to DefWindwProc 600 } 601 602 int WINAPI WinMain(HINSTANCE hInstance, // Instance 603 HINSTANCE hPrevInstance, // Previous instance 604 LPSTR lpCmdLine, // Command line parameters 605 int nCmdShow) // Window show state 606 { 607 MSG msg; // Window message structure 608 BOOL done = FALSE; // Bool variable to exit loop 609 // Ask the user which screen mode they prefer 610 if (MessageBox(NULL, "Would you like to run in fullscreen mode?", 611 "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO) 612 { 613 fullscreen = FALSE; // Window mode 614 } 615 // Create our OpenGL window 616 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { // (Modified) 617 return 0; // Quit if window was not create 618 } 619 620 while (!done) { // Loop that runs until donw = TRUE 621 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Is there a message wating 622 if (msg.message == WM_QUIT) { // Havw we received a quit message 623 done = TRUE; // if so done = TRUE 624 } 625 else { // If not, deal with window message 626 TranslateMessage(&msg); // Translate message 627 DispatchMessage(&msg); // Dispatch message 628 } 629 } 630 else { 631 // Draw the scene. Watch for ESC key and quit message from DrawGLScene() 632 if (active) { // Program active 633 if (keys[VK_ESCAPE]) { // Was ESC pressed 634 done = TRUE; // ESC signalled a quit 635 } 636 else { // Not time to quit, update screen 637 DrawGLScene(); // Draw scene 638 SwapBuffers(hDC); // Swap buffers (double buffering) 639 } 640 } 641 /******************************************************************************************************************************************/ 642 /******************************************************************************************************************************************/ 643 if (keys[‘ ‘] && !sp) { 644 sp = TRUE; 645 object++; 646 if (object > 5) { 647 object = 0; 648 } 649 } 650 if (!keys[‘ ‘]) { 651 sp = FALSE; 652 } 653 654 if (keys[‘L‘] && !lp) { // L key being pressed not held 655 lp = TRUE; // lp become TRUE 656 light = !light; // Toggle light TRUE/FALSE 657 658 if (!light) { 659 glDisable(GL_LIGHTING); // Disable light 660 } 661 else { 662 glEnable(GL_LIGHTING); // Enable light 663 } 664 } 665 666 if (!keys[‘L‘]) { 667 lp = FALSE; 668 } 669 if (keys[‘F‘] && !fp) { 670 fp = TRUE; 671 filter += 1; 672 if (filter > 2) { 673 filter = 0; 674 } 675 } 676 if (!keys[‘F‘]) { 677 fp = FALSE; 678 } 679 if (keys[VK_SUBTRACT]) { //VK_PRIOR 680 z -= 0.005f; 681 } 682 if (keys[VK_ADD]) { // VK_NEXT 683 z += 0.005f; 684 } 685 if (keys[VK_UP]) { 686 xspeed -= 0.0005f; 687 } 688 if (keys[VK_DOWN]) { 689 xspeed += 0.0005f; 690 } 691 if (keys[VK_RIGHT]) { 692 yspeed += 0.0005f; 693 } 694 if (keys[VK_LEFT]) { 695 yspeed -= 0.0005f; 696 } 697 /******************************************************************************************************************************************/ 698 /******************************************************************************************************************************************/ 699 /* 700 * It allows us to press the F1 key to switch from fullscreen mode to 701 * windowed mode or windowed mode to fullscreen mode. 702 */ 703 if (keys[VK_F1]) { // Is F1 being pressed 704 keys[VK_F1] = FALSE; // If so make key FASLE 705 KillGLWindow(); // Kill our current window 706 fullscreen = !fullscreen; // Toggle fullscreen / window mode 707 //Recreate our OpenGL window(modified) 708 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) { 709 return 0; // Quit if window was not create 710 } 711 } 712 } 713 } 714 // Shutdown 715 KillGLWindow(); // Kill the window 716 return (msg.wParam); // Exit the program 717 }
Thanks for Nehe‘s tutorials, this is his home.
时间: 2024-09-29 03:46:19