Creating Your Device
For the rest of the development of this game, you should still be working with the project you started in the last chapter. One of the first things you want to do now is set up the project to actually work with the sample framework. In the Main method you created in the last chapter, add the code in Listing 4.1 immediately following the creation of the GameEngine class.
Listing 4.1. Hooking Events and Callbacks
// Set the callback functions. These functions allow the sample framework
// to notify the application about device changes, user input, and Windows
// messages. The callbacks are optional so you need only set callbacks for
// events you're interested in. However, if you don't handle the device
// reset/lost callbacks, then the sample framework won't be able to reset
// your device since the application must first release all device resources
// before resetting. Likewise, if you don't handle the device created/destroyed
// callbacks, then the sample framework won't be able to re-create your device
// resources.
sampleFramework.Disposing += new EventHandler(blockersEngine.OnDestroyDevice);
sampleFramework.DeviceLost += new EventHandler(blockersEngine.OnLostDevice);
sampleFramework.DeviceCreated +=
new DeviceEventHandler(blockersEngine.OnCreateDevice);
sampleFramework.DeviceReset +=
new DeviceEventHandler(blockersEngine.OnResetDevice);
sampleFramework.SetKeyboardCallback(new KeyboardCallback(
blockersEngine.OnKeyEvent));
// Catch mouse move events
sampleFramework.IsNotifiedOnMouseMove = true;
sampleFramework.SetMouseCallback(new MouseCallback(blockersEngine.OnMouseEvent));
sampleFramework.SetCallbackInterface(blockersEngine);
A lot of things are happening in this small section of code. A total of four events are being hooked to let you know when the rendering device has been created, lost, reset, and destroyed. You'll need to add the implementations for these handlers in a moment from Listing 4.2. After that, you'll notice that you're hooking two callbacks the sample framework has for user input, namely the keyboard and mouse (Listing 4.3). Finally, you call the SetCallbackInterface method passing in the game engine instance; however, you might notice that the instance doesn't implement the correct interface. You'll need to fix that as well.
Listing 4.2. Framework Event Handlers
///
/// This event will be fired immediately after the Direct3D device has been
/// created, which will happen during application initialization and
/// windowed/full screen toggles. This is the best location to create
/// Pool.Managed resources since these resources need to be reloaded whenever
/// the device is destroyed. Resources created here should be released
/// in the Disposing event.
///
private void OnCreateDevice(object sender, DeviceEventArgs e)
{
SurfaceDescription desc = e.BackBufferDescription;
}
///
/// This event will be fired immediately after the Direct3D device has been
/// reset, which will happen after a lost device scenario. This is the best
/// location to create Pool.Default resources since these resources need to
/// be reloaded whenever the device is lost. Resources created here should
/// be released in the OnLostDevice event.
///
private void OnResetDevice(object sender, DeviceEventArgs e)
{
SurfaceDescription desc = e.BackBufferDescription;
}
///
/// This event function will be called fired after the Direct3D device has
/// entered a lost state and before Device.Reset() is called. Resources created
/// in the OnResetDevice callback should be released here, which generally
/// includes all Pool.Default resources. See the "Lost Devices" section of the
/// documentation for information about lost devices.
///
private void OnLostDevice(object sender, EventArgs e)
{
}
///
/// This callback function will be called immediately after the Direct3D device
/// has been destroyed, which generally happens as a result of application
/// termination or windowed/full screen toggles. Resources created in the
/// OnCreateDevice callback should be released here, which generally includes
/// all Pool.Managed resources.
///
private void OnDestroyDevice(object sender, EventArgs e)
{
}
Listing 4.3. User Input Handlers
/// Hook the mouse events
private void OnMouseEvent(bool leftDown, bool rightDown, bool middleDown,
bool side1Down, bool side2Down, int wheel, int x, int y)
{
}
/// Handle keyboard strokes
private void OnKeyEvent(System.Windows.Forms.Keys key, bool keyDown,
bool altDown)
{
}
Now, the SetCallbackInterface method you called earlier expects a variable of type IFrameworkCallback, and you passed in the game engine class, which does not implement this type. You can fix this easily by changing the game engine class declaration:
public class GameEngine : IFrameworkCallback, IDeviceCreation
Of course, now you need to add the implementation of the two methods this interface defines (Listing 4.4).
Listing 4.4. Framework Callback Interface
///
/// This callback function will be called once at the beginning of every frame.
/// This is the best location for your application to handle updates to the
/// scene but is not intended to contain actual rendering calls, which should
/// instead be placed in the OnFrameRender callback.
///
public void OnFrameMove(Device device, double appTime, float elapsedTime)
{
}
///
/// This callback function will be called at the end of every frame to perform
/// all the rendering calls for the scene, and it will also be called if the
/// window needs to be repainted. After this function has returned, the sample
/// framework will call Device.Present to display the contents of the next
/// buffer in the swap chain
///
public void OnFrameRender(Device device, double appTime, float elapsedTime)
{
}
With that boilerplate code out of the way, you're ready to start doing something interesting now. First, you should tell the sample framework that you're ready to render your application and to start the game engine. Go back to the Main method, and add the code in Listing 4.5 immediately after your SetCallbackInterface call. |