This page goes through on how to build the 3D game for Windows 10 – it will be a win32 app which means you will get a .exe file to run the game. I am using Windows DirectX 12 which is an API that allows you to build a 3D game. It will run on a Windows Desktop / Laptop.
To build this app, I am using the following resources:
- Visual Studio Community IDE / Compiler
- the book Introduction to Game Programming with Direct 3D 12.0
- code from the book – you can get it on GitHub here
- win32 DirectX documentation from Microsoft
- code from Microsoft’s DirectX 12 Tool Kit
- code from a Microsoft sample 3D game – this game uses UWP but it’s helpful to view the game specific code
- Adobe Photoshop for textures and 2D images (you can use the free Gimp app instead)
- Maya LT for 3D models and 3D levels (you can use the free Blender app instead)
- Logic Pro X (similar to Garage Band), FL Studio and Audacity (free app) for music / audio creation and recording
You can follow the game code as I keep modifying it to build the game.
Creating the project
With Visual Studio Community, create a Windows Desktop app by creating a new project and select Windows Desktop Application.
I named my project Blindfate. You can name it with the name of your game.
When you build and play the app as below (press the green play button)
Then your app will look as below
It is useful to study the code if you are new to Windows programming. We will replace all the code and add other code to our project.
Familiarize yourself with Visual Studio – a tutorial on the IDE is here. Try changing the code and work with the features to get familiar with it if you are new to Visual Studio. How win32 works with the game loop is illustrated in the following code.
Initial 3D Game App
I will describe the steps that I used to get a working 3D game app. This includes being able to move in the game using the keyboard and mouse, as well as viewing a basic 3D world using a camera. I used the book’s 3D models and textures, but will later replace it with my own to make the game. Some screenshots are below.
- 3D model view
2. Wireframe view (when you press “1”) – the skull and car were created by the book’s author using 3D modelling software. The ground, buildings, columns with spheres were created using code from the book.
3. Zoomed out view of the 3D scene – ie. a birds eye view of the game. The 3D environment is only small. I use the W,A,S,D to move forward / back with A/D rotating, space bar to fly up, X to fly down, Q/E to strafe left and right, and the mouse to move around as well as rotate.
I purchased the book Introduction to 3D Game Programming with DirectX 12 by Frank D. Luna. It describes how to setup 3D graphics for DirectX 12. It doesn’t describe how to get a full game going, but has enough information so that we can create a 3D game from the code supplied.
I couldn’t publish the whole code base for my app due to copyright restrictions. So the following steps outline how I used the book’s code.
You can download the all the source files from the book here.
First step is to create a new C++ source file called win.cpp then copy and paste the windows code from Blindfate.cpp (or your own game file) into it. Then in win.cpp, comment all the code with /* and */ I am doing is to save the code in case I need it later on. Then make Blindfate.cpp blank.
I first used the book’s Common folder source files and copied them into my project folder, then added the .h and .cpp files to the solution.
In the file, d3dapp.cpp, there is a bug in line 547 – it should read as follows:
HANDLE eventHandle = CreateEventEx(nullptr, nullptr, false, EVENT_ALL_ACCESS);
In the file d3dapp.h, I changed line 121 to the following (this is the name of my game):
std::wstring mMainWndCaption = L"Blindfate"; // name of window
I used the book’s Shape app (chapter 7) to build the 3D geometry including boxes, columns, spheres, and the floor grid. The 3D geometry in this section is built mathematically.
I used the book’s camera demo (chapter 15) to create the camera. It uses a first person camera.
In the file camera.cpp, I added the following code in line 200:
// Fly up or down
void Camera::Fly(float d)
// mPosition += d*mUp
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR l = XMLoadFloat3(&mUp);
XMVECTOR p = XMLoadFloat3(&mPosition);
XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, l, p));
mViewDirty = true;
In the file camera.h, I added the following code in line 67:
void Fly(float d);
The resulting source code for my app Blindfate.cpp and Blindfate.h are here.
Note that these are the files that I will be changing to create my game – ie. all game specific code will be there.
Note the following for when you compile the app as an upgrade to Visual Studio 2019 made the compile fail:
//*** Compile Note:
// change "Conformance Mode" to "No" in the C/C++ -> Language project settings.
// eventually this will have to be fixed as it says "Compiler Error C2102 '&' requires l-value"
// happens after VS2019 upgrade
Code base of the initial 3D Game app
Microsoft has their full documentation on DirectX 3D Graphics here. The workflow for a DirectX 3D Graphics app is here. I found it easier to read the book to help understand what was happening, but you can also read through the code and change a few things to help you understand it.
Some more helpful references to understand how the DirectX 3D pipeline works are here:
The code contains C++ classes.
So far, the project has the following files (.cpp and .h):
- Blindfate – contains game specific code – this is used to build our game.
- d3dApp – used to build a window and to initialize all the DirectX 3D graphics
- GameTimer – a clock used to time our game loop. Includes FPS (frames per second) calculations
- GeometryGenerator – used to create 3D models using maths
- DDSTextureLoader – helps to load textures (.dds files) from disk
- Camera – code to build our first person camera
- d3dUtil – miscellaneous utilities and definitions used to build graphics
- MathHelper – contains some helper maths functions
- Frameresource – stores graphics resources to be presented to the GPU
- UploadBuffer – contains a buffer to store and upload graphics resources to the GPU
I put all the .cpp in the Source Files folder and the .h files in the Header Files folder to make things easier to find.
Folders in the game:
- Shaders folder – contains HLSL files Default.hlsl and LightingUtil.hlsl for lighting
- Textures folder – contains all textures used – these are in .dds format
- Models folder – contains text files of all 3D models
3D World Approach
The world will be situated in 3D space at a particular set of 3D co-ordinates. Then I will add items or levels at different world co-ordinates and move the camera accordingly. I will keep track of each level (room or part of the world), then restrict the camera to that level.
For example, I have a splashscreen texture on an x,y grid (3D model – x,y plane which is very thin), then I move the camera to the first scene which is behind it. That way I can put other scenes at different world co-ordinates.
Below shows the splashscreen and 3D models inserted such as the floor, columns and other 3D models.
Hence with this first approach, the whole 3D world including all the levels will be stored in memory but the 3D world will only be loaded once in the game.
Once I build the game, if things get too slow or memory is an issue, I will change the game to display each level separately – this will mean that I will need to clear the video memory to do so, and then unload / reload 3D models for each level.
Things to do
There is a lot more in the book which I haven’t tried yet such as adding a sky, mountains, water, shading and character animation. Also need to add sound, voice and music. Will be good to add a gamepad such as the Xbox game controller. I will also do a heads up display (HUD) to show player stats and also a menu system. Will work out how to do audio such as music, sound effects and voice.