📄 dinput.cpp
字号:
hwnd = CreateWindowEx(NULL,// The extended window style.
"UltimateGameProgrammingClass",// window Class name.
"Direct Input tutorial - By the Programming Ace.",// window name.
WS_OVERLAPPEDWINDOW | WS_VISIBLE |// The window style.
WS_SYSMENU | WS_CLIPCHILDREN |// window style.
WS_CLIPSIBLINGS,// window style.
100, 100,// window x, y coordinate.
400,
400,// window width and height.
NULL,// handle to parent window.
NULL,// menu.
hInstance,// handle to app instance.
NULL); // pointer to window creation data.
// If there was an error with creating the window, then close the program.
if(!hwnd)
return 0;
ShowWindow(hwnd, SW_SHOW); // This shows the window.
UpdateWindow(hwnd); // This forces a paint message.
isFinished = false; // False = running, True = not running.
// If initialize fail (return false), then we don't want the program to run.
if(!InitializeGL())
isFinished = true;
// Here is where we set up Direct Input so we can get user input from the mouse & Keyboard.
if(!DirectInput.Initialize(hwnd, hInstance))
return false;
// This is the messsage loop.
while(!isFinished)
{
PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
if(msg.message == WM_QUIT)// If the application gets a quit message...
{
isFinished = true; // Then quit the program.
}
else // else render the scene.
{
RenderScene(); // Render and display the next frame.
// This will translate virtual key messages into character messages.
TranslateMessage(&msg);
// DispatchMessage will send a message to Windows to be processed.
DispatchMessage(&msg);
}
}
// Shutdown Direct Input.
DirectInput.Shutdown();
return msg.wParam; // End the application.
}
bool InitializeGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Clear the screen to black.
glShadeModel(GL_SMOOTH); // Smooth shading in our scenes.
glEnable(GL_DEPTH_TEST); // Enable desth testing for hidden surface removal.
glEnable(GL_LIGHTING); // Enable lighting.
// Here we will set up a spotlight light source in our scene. This light will shine on
// the objects giving them a nicer look than a plain dull color. This stuff has nothing
// to do with the tutorial it self but only to make things look better.
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 10.0f);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 75.0f);
// Enable our light.
glEnable(GL_LIGHT0);
// Set up the material information for our objects. Again this is just for show.
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularLight);
glMateriali(GL_FRONT, GL_SHININESS, 128);
// If all went well we return true.
return true;
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen.
glLoadIdentity(); //Reset modelview matrix for new frame.
// First lets test our input objects and see if the user has pressed any key we care
// about or has click any of the mouse buttons.
GetInput();
glTranslatef(0.0, 0.0, -5.0f); // Move back 5 units.
glRotatef(yRotation, 0.0f, 1.0f, 0.0f); // Rotate the object along the y axis.
glRotatef(xRotation, 1.0f, 0.0f, 0.0f); // Rotate the object along the x axis.
// Draw our object. Depending on what ObjectChoice is will depend on what is drawn...
switch(ObjectChoice)
{
case CUBE:
auxSolidCube(2.0); // Draw a solid cube.
break;
case SPHERE:
auxSolidSphere(1.5); // Draw a solid sphere.
break;
case TORUS:
auxSolidTorus(0.5, 1.0); // Draw a solid torus.
break;
case TEAPOT: // Draw a wireframe teapot.
auxWireTeapot(1.5);
break;
default: // Reset in case neither is true.
ObjectChoice = 0;
break;
}
// Increase the rotation.
xRotation += 0.1f;
yRotation += 0.2f;
// Error checking to make sure our values do not go over 360 degrees.
if(xRotation >= 360.0f)
xRotation = 0.0f;
if(yRotation >= 360.0f)
yRotation = 0.0f;
SwapBuffers(g_HDC); // Display the new frame.
}
void GetInput()
{
// First we will update all the devices our input system supports. This will
// check which keys are pressed and which mouse buttons are pressed.
// We use CheckTime to only allow input to be processed only every 1/15ths of a second.
// If .15 has passed then we allow the processing of input to continue.
if(CheckTime(0.15))
{
// Update all devices.
DirectInput.UpdateDevices();
// Next we will check for the keys and buttons we care about.
// Check if the user pressed the escape key.
if(DirectInput.KeyDown(DIK_ESCAPE))
PostQuitMessage(0);
// Check if the user pressed the number 1 key.
if(DirectInput.KeyDown(DIK_1))
ObjectChoice = CUBE;
// Check if the user pressed the number 2 key.
if(DirectInput.KeyDown(DIK_2))
ObjectChoice = SPHERE;
// Check if the user pressed the number 3 key.
if(DirectInput.KeyDown(DIK_3))
ObjectChoice = TORUS;
// Check if the user pressed the number 4 key.
if(DirectInput.KeyDown(DIK_4))
ObjectChoice = TEAPOT;
// Check if the user pressed the left mouse button. If so increase the ObjectChoice variable.
if(DirectInput.MouseButtonDown(LEFT_BUTTON))
ObjectChoice++;
// Check if the user pressed the right mouse button. If so decrease the ObjectChoice variable.
if(DirectInput.MouseButtonDown(RIGHT_BUTTON))
ObjectChoice--;
}
// Error checking.
if(ObjectChoice >= 4)
ObjectChoice = CUBE;
if(ObjectChoice < 0)
ObjectChoice = TEAPOT;
}
bool CheckTime(float amount)
{
// This will be used to check if a second has passed.
float nextSecond = 0.0f;
// This is the last second that occured.
static float prevSecond = 0.0f;
// Get the second in millisecond then multiply it by 0.001 to convert this to seconds.
nextSecond = GetTickCount() * 0.001f;
// If amount in "amount" has passed we want to return true to the caller...
if( nextSecond - prevSecond > amount )
{
// Make the second (time) we just got the previous second so we can used this the
// next time the function is called.
prevSecond = nextSecond;
return true;
}
// Else not enough time has passed...
return false;
}
// Recap:
// Well there you have it. Getting input through the keyboard and mouse using Direct Input.
// As you can see it is not that hard. This is the better way to get input because using
// Direct Input you are accessing the hardware directly. Another good thing about Direct Input
// is that you can easily add more devices, such as a joystick, without any complex code.
// When ever I do a tutorial dealing with input from now on I will use Direct Input.
// Copyright March 2003
// All Rights Reserved!
// Allen Sherrod
// ProgrammingAce@UltimateGameProgramming.com
// www.UltimateGameProgramming.com
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -