www.pudn.com > airhockey.rar > main.cpp
#define WIN32_LEAN_AND_MEAN // trim the excess fat from Windows #define WIN32_EXTRA_LEAN ////// Includes #include// standard Windows app include #include // standard OpenGL include #include // OpenGL utilties #include // OpenGL auxiliary functions #include "HiResTimer.h" // hi resolution timer #include "vector.h" // vector math #include "object.h" // base object #include "table.h" // table object #include "puck.h" // puck object #include "player.h" // player object ////// Global Variables //float angle = 0.0f; // current angle of the rotating triangle HDC g_HDC; // global device context int mouseX, mouseY; ////// Lighting variables float ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // ambient light float diffuseLight[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // diffuse light float lightPosition[] = { 0.0f, -1.0f, 0.0f, 0.0f }; // spotlight position ////// The Air Hockey Objects CTable *myTable = NULL; CPuck *myPuck = NULL; CHiResTimer *timer = NULL; CPlayer *player = NULL; // Initialize() // desc: intialize OpenGL and allocate objects void Initialize() { glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); // Now setup LIGHT0 glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); // setup the ambient element glLightfv(GL_LIGHT0, GL_DIFFUSE, ambientLight); // the diffuse element glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); // place the light in the world // Enable the light glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_TEXTURE_2D); myTable = new CTable; myTable->Load(); myPuck = new CPuck(10.0); timer = new CHiResTimer; timer->Init(); player = new CPlayer; } // Render() // desc: perform physics and draw world void Render() { float elapsedSec = timer->GetElapsedSeconds(1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(150.0, 150.0, 200.0, 150.0, 0.0, -300.0, 0.0, 1.0, 0.0); // do physics/movement player->Move(elapsedSec, mouseX, mouseY, myTable, myPuck); myPuck->Animate(elapsedSec, myTable); // draw objects player->Draw(); myTable->Draw(); myPuck->Draw(); glFlush(); SwapBuffers(g_HDC); } // CleanUp() // desc: free memory of objects void CleanUp() { myTable->Unload(); delete myTable; myTable = NULL; delete myPuck; myPuck = NULL; delete timer; timer = NULL; delete player; player = NULL; } // SetupPixelFormat() // function to set the pixel format for the device context void SetupPixelFormat(HDC hDC) { int nPixelFormat; // our pixel format index static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of structure 1, // default version PFD_DRAW_TO_WINDOW | // window drawing support PFD_SUPPORT_OPENGL | // OpenGL support PFD_DOUBLEBUFFER, // double buffering support PFD_TYPE_RGBA, // RGBA color mode 32, // 32 bit color mode 0, 0, 0, 0, 0, 0, // ignore color bits, non-palettized mode 0, // no alpha buffer 0, // ignore shift bit 0, // no accumulation buffer 0, 0, 0, 0, // ignore accumulation bits 16, // 16 bit z-buffer size 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main drawing plane 0, // reserved 0, 0, 0 }; // layer masks ignored nPixelFormat = ChoosePixelFormat(hDC, &pfd); // choose best matching pixel format SetPixelFormat(hDC, nPixelFormat, &pfd); // set pixel format to device context } // WndProc() // the Windows Procedure event handler LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HGLRC hRC; // rendering context static HDC hDC; // device context char string[] = "Hello, world!"; // text to be displayed int width, height; // window width and height int oldMouseX, oldMouseY; switch(message) { case WM_CREATE: // window is being created hDC = GetDC(hwnd); // get current window's device context g_HDC = hDC; SetupPixelFormat(hDC); // call our pixel format setup function // create rendering context and make it current hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); return 0; break; case WM_CLOSE: // windows is closing // deselect rendering context and delete it wglMakeCurrent(hDC, NULL); wglDeleteContext(hRC); // send WM_QUIT to message queue PostQuitMessage(0); return 0; break; case WM_SIZE: height = HIWORD(lParam); // retrieve width and height width = LOWORD(lParam); if (height==0) // don't want a divide by zero { height=1; } glViewport(0, 0, width, height); // reset the viewport to new dimensions glMatrixMode(GL_PROJECTION); // set projection matrix current matrix glLoadIdentity(); // reset projection matrix // calculate aspect ratio of window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f); glMatrixMode(GL_MODELVIEW); // set modelview matrix glLoadIdentity(); // reset modelview matrix return 0; break; case WM_MOUSEMOVE: // save old mouse coordinates oldMouseX = mouseX; oldMouseY = mouseY; // get mouse coordinates from Windows mouseX = LOWORD(lParam); mouseY = HIWORD(lParam); break; default: break; } return (DefWindowProc(hwnd, message, wParam, lParam)); } // WinMain() // the main windows entry point int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WNDCLASSEX windowClass; // window class HWND hwnd; // window handle MSG msg; // message bool done; // flag saying when our app is complete // fill out the window class structure windowClass.cbSize = sizeof(WNDCLASSEX); windowClass.style = CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = WndProc; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = hInstance; windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // default icon windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // default arrow windowClass.hbrBackground = NULL; // don't need background windowClass.lpszMenuName = NULL; // no menu windowClass.lpszClassName = "MyClass"; windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // windows logo small icon // register the windows class if (!RegisterClassEx(&windowClass)) return 0; // class registered, so now create our window hwnd = CreateWindowEx(NULL, // extended style "MyClass", // class name "Air Hockey Demo", // app name WS_OVERLAPPEDWINDOW | WS_VISIBLE | // style WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, // x,y coordinate 800, 600, // width, height NULL, // handle to parent NULL, // handle to menu hInstance, // application instance NULL); // no extra params // check if window creation failed (hwnd would equal NULL) if (!hwnd) return 0; ShowWindow(hwnd, SW_SHOW); // display the window UpdateWindow(hwnd); // update the window done = false; // intialize the loop condition variable Initialize(); ShowCursor(FALSE); // main message loop while (!done) { PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE); if (msg.message == WM_QUIT) // do we receive a WM_QUIT message? { done = true; // if so, time to quit the application } else { Render(); // render world TranslateMessage(&msg); // translate and dispatch to event queue DispatchMessage(&msg); } } CleanUp(); ShowCursor(TRUE); return msg.wParam; }