A First DirectX-Framework
The secret of life, though, is to fall seven times and to get up eight times.
– Paulo Coelho, The Alchemist
This chapter concludes the introductory tutorials and summarizes everything that has been discussed so far. After having erred for many hours and after countless mistakes, there finally is a robust game framework for future projects. For further details about the different aspects of the framework, please refer to the appropriate tutorial chapters.
The Utility Classes
The utility classes are helpful helpers to make the life of a game programmer a little bit easier.
The String Converter Class
The static StringConverter class, defined in stringConverter.h can be used to convert strings to widestrings and vice versa.
The Expected Class
The expected class, defined in expected.h is used to enhance error and exception handling within the application.
The Log Class
This class, defined in log.h, handles the logging of events. So far, in these tutorials, only a file logger has been implemented, writing out a log file of game events to the My Documents folder.
The Service Locator Class
The service locator class, defined in serviceLocator.h, provides services to the entire application, without coupling anything together. So far, in these tutorials, the service locator provides a file logging service. Later, it will surely see more use, for example, when an audio service is implemented.
Here is an example of how to use the service locator to retrieve the file logger and to print information to the log file:
The Core Classes
Those are the core components of our application. They are invaluable to any Windows program.
The Timer Class
Keeping track of time is highly important for any game, especially if a mathematical simulation of a physical world is intended. The timer class does just that, by encapsulating a high-performance counter made available by Windows. It is automatically updated and used in the main game loop.
The Window Class
The window class initializes the main window and handles Windows messages. Basically, this class hides all the nasty Windows stuff, such that it will later on be easier to fully focus on programming the game, without worrying about Windows.
The DirectXApp Class
This is the central engine for the entire project — it initializes and connects all the other classes together. To quit the application, press the ESCAPE key. To switch between full-screen and windowed mode, press ALT+ENTER. To change the resolution, press PAGE_DOWN (lower resolution) or PAGE_UP (higher resolution). To show or hide the FPS information, press F1.
The Game Class
Derived of a DirectX Application, the game class is the main entry point to the game. Here all the data is initialized, the game world is updated and finally rendered to the screen.
DirectXGame(HINSTANCE hInstance)
The constructor takes the instance handle of the application and passes it to the constructor of the DirectXApp class.
~DirectXGame()
During deconstruction, all pointers to graphical elements (such as buffers or vertices of our objects) and sounds, are deleted.
util::Expected init() override
This method initializes the game, by first initializing the DirectXApp class (which then initializes all the other classes and binds them together) and then all other components, for example, graphics and sounds, are created.
void shutdown(util::Expected* expected = NULL) override
This method cleans up and shuts the game down, it also handles error messages.
util::Expected update(double dt)
This function updates the game world based on the laws of mathematics and physics.
util::Expected render(double farSeer)
This method renders the current, updated scene to the screen.
util::Expected initGraphics()
This function initializes the game graphics that are needed at the start of the game.
util::Expected run() override
This method calls the run method of the DirectXApp, thus entering the main event loop.
Graphics Classes
Those classes handle everything that is related to graphical processing.
Direct3D
This class is the graphical workhorse of the application. Most of the core graphical freatures of DirectX are found in this class: switching between full-screen and windowed mode, changing the resolution to computing antialiasing and depth buffering, …
Vertices
A vertex represents a vector in
ShaderBuffer
This structure holds the data read from a pre-compiled shader object.
All of its members are private, thus only available to friendly classes.
core::DirectXApp* dxApp
This member stores the pointer to the main application class.
Microsoft::WRL::ComPtr dev
This is a COM pointer to an interface of the actual Direct3D device.
Microsoft::WRL::ComPtr devCon
This member is a COM pointer to the context of the Direct3D device.
Microsoft::WRL::ComPtr swapChain
This is a COM pointer to the swap chain.
Microsoft::WRL::ComPtr renderTargetView
A COM pointer to the rendering target.
Microsoft::WRL::ComPtr depthStencilView
This member holds a COM pointer to the depth and stencil buffer.
Microsoft::WRL::ComPtr standardVertexShader
A COM pointer to the standard vertex shader.
Microsoft::WRL::ComPtr standardPixelShader
A COM pointer to the pixel shader.
DXGI_FORMAT desiredColourFormat
This member holds the desired colour format for the application to use. The default is: DXGI_FORMAT_B8G8R8A8_UNORM.
unsigned int numberOfSupportedModes
This member stores the number of screen modes that are supported by the GPU, for the above specified desired colour format.
DXGI_MODE_DESC* supportedModes
This member holds a list of all supported screen modes for the desired colour format.
DXGI_MODE_DESC currentModeDescription
This is a description of the currently active screen mode.
unsigned int currentModeIndex
This member stores the index of the current mode in the list of all supported screen modes.
bool startInFullscreen
This boolean is true if and only if the game should start in full-screen mode.
BOOL currentlyInFullscreen
This boolean is true if and only if the game is currently in full-screen mode.
bool changeMode
This boolean is true if and only if the screen resolution should be changed in this frame.
The following methods are private.
void changeResolution(bool increase)
This function changes the screen resolution, if increase is true, a higher resolution is chosen, else the resolution is lowered.
util::Expected writeCurrentModeDescriptionToConfigurationFile()
This method writes the current screen resolution to the configuration file.
util::Expected readConfigurationFile()
This method reads the preferences from the configuration file.
util::Expected createResources()
This method creates the main Direct3D interface and everything else related to it, such as, for example, the device context and the swap chain.
util::Expected onResize()
This method handles the resizing of all the graphical resources; i.e. it syncs the render target with the refresh rate of the monitor, and it initializes (or re-creates) all resolution dependent Direct3D objects, such as the render view and the depth/stencil buffers.
util::Expected initPipeline()
This function initializes the (graphics) rendering pipeline by loading the pre-compiled shader objects and setting them as the active shaders.
util::Expected loadShader(std::wstring filename)
This is a helper function to read shader data from .cso files.
void clearBuffers()
This method clears the back and depth/stencil buffers.
util::Expected present()
This method presents the chain, by flipping the buffers.
The following methods are public, and automatically invoked by the DirectXApp class.
Direct3D(core::DirectXApp* dxApp)
The constructor takes a pointer to the actual application and stores it in the appropriate member variable. It then calls the createDeviceResources method.
~Direct3D()
The destructor leaves fullscreen mode and deletes all used pointers.
Direct2D and DirectWrite
This class initializes Direct2D and DirectWrite. This comes in handy to write information to the screen, for debugging, for example, or to create a simple GUI.
The following members are private, thus only available to friendly classes.
core::DirectXApp* dxApp
A pointer to the main application class.
Microsoft::WRL::ComPtr writeFactory
A COM pointer to an interface of the DirectWrite factory.
Microsoft::WRL::ComPtr factory
A COM pointer to an interface of the Direct2D factory.
Microsoft::WRL::ComPtr dev
A COM pointer to an interface of the actual Direct2D object.
Microsoft::WRL::ComPtr devCon;
A COM pointer to the context of the above mentioned Direct2D object.
DirectXApp* dxApp
A pointer to the DirectX class.
The following members, mostly brushes, are publicly available.
Microsoft::WRL::ComPtr yellowBrush
Microsoft::WRL::ComPtr whiteBrush
Microsoft::WRL::ComPtr blackBrush
COM pointer to yellow, white and black brushes.
Microsoft::WRL::ComPtr textFormatFPS
A COM pointer to the text format for the FPS debug information.
Microsoft::WRL::ComPtr textLayoutFPS
A COM pointer to the text layout for the FPS debug information.
The following methods are private.
util::Expected createDevice()
This method creates and initializes the main Direct2D and DirectWrite objects.
util::Expected createBitmapRenderTarget()
This function creates the bitmap render target, set to be the same as the backbuffer already in use for Direct3D, that is, the function creates a bitmap target and sets DirectWrite to write to the Direct3D back buffer.
util::Expected initializeTextFormats()
This function initializes all text formats.
The following methods are public and automatically invoked by the DirectXApp class.
Direct2D(core::DirectXApp* dxApp)
The constructors takes a pointer to the actual DirectX application and stores it in the appropriate member variable. It then calls the createDevice() and initTextFormats() methods.
~Direct2D()
The destructor does what destructors do. It destroys.
util::Expected printFPS()
This method is responsible for printing the fps information to the screen.
The Helper Class
Download the source code here.
References
- Game Programming Algorithms and Techniques, by Sanjay Madhav
- Game Programming Patterns, by Robert Nystrom
- Introduction to 3D Game Programming with DirectX 11, by Frank D. Luna
- Microsoft Developer Network (MSDN)
- Tricks of the Windows Game Programming Gurus, by André LaMothe