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