📄 main.cpp
字号:
#define WIN32_LEAN_AND_MEAN // trim the excess fat from Windows
#define WIN32_EXTRA_LEAN
////// Includes
#include <windows.h> // standard Windows app include
#include <gl/gl.h> // standard OpenGL include
#include <gl/glu.h> // OpenGL utilties
#include <gl/glaux.h> // 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -