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