Explorations in 3D Graphics and DirectX 12: Episode 1
Almost 20 years ago, I picked up a copy of Andre LaMothe’s Tricks of the Windows Game Programming Gurus book.
I don’t remember what prompted me to select this particular title. Around that time, in 2001, I was promoted to the President role for the Adtech division within Spirent Communications. We had been growing exponentially for the prior two years. And then the “tech wreck” hit us hard in 2002; our company shrank from 150 people down to 80 over the course of one year. We struggled just to survive. It was a very stressful time for everyone.
The long hours and stress were taking their toll, and I needed an outlet. I played some video games in my spare time, and had always wondered at the technology behind their creation. 3D graphics for video games were a new concept back then: one of our favorite games was Serious Sam, and though it looks pretty simple now, the graphics just blew us away at the time.
So, I read the book from cover to cover, in the evenings and on weekends. At about the same time as I finished the book, I started a new job, so then put it down and didn’t pick it up again until very recently. I had also bought LaMothe’s Tricks of the 3d Game Programming Gurus: Advanced 3d Graphics and Rasterization in 2003 (probably the very first book I had ever pre-ordered, I was so anxious to get it), but never got past the first few chapters before life intervened. Time flies. Almost 20 years.
Amazingly, both Tricks books are as fresh now as they were then. You have to give credit to Andre LaMothe for that. Most of the .exe files that were on the CDs still run, with no changes. You can’t say that about a lot of 20-year-old software.
But I’ll get back to Tricks of the Windows Game Programming Gurus later – let’s fast-forward to 2020, where the pressure of the pandemic made me look for another source of stress relief, and I returned to the comfort of computer graphics technology. After I flew through LaMothe’s book for a second time last month, I decided that I wanted to learn more. Time has moved on, and technology has advanced. And I was especially interested in the graphics part of game programming, as opposed to collision detection, sound generation, particle physics, and the other aspects of the application.
So, on a bit of a whim, I ordered Frank D. Luna’s 3D Game Programming with DirectX 12. It was published in 2016, but appears to be the most recent book on the topic.
In the Introduction, Luna gives a short description on compiling and running a demo application that displays a colored box on the screen. Like LaMothe’s book, a CD is provided with source code; and Luna has the source also in a Git repository. Unlike LaMothe’s books, though, the executables are not provided, so it is up to the reader to build the program and execute it.
I found (as have others on the web) that Luna’s build instructions don’t work “out of the box” (forgiving the pun). In the Introduction, on page xxix (Location 818 within my Kindle edition of the book) Luna starts a chapter entitled Demo Project Setup in Visual Studio 2010, even though he later refers to VS2015. I wanted to use Visual Studio 2019. Also, some API have (unbelievably) changed between then and now, so some code needs to be updated to reflect that. And there are a few other issues here and there.
So, I’ll dedicate the rest of this article on detailed, step-by-step directions on how to get the demo programs in his book to work.
You will, of course, need the Windows 10 SDK: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/. As of the time of this writing, the Windows 10 SDK (10.0.19041.0) for Windows 10, version 2004 provides the latest headers, libraries, metadata, and tools for building Windows 10 apps. There were no changes needed for Windows 10 20H2, the version I am running on now.
Open up VS2019, and select Empty Project:
Then save the Project, for example under the name Box (same as the Solution name). You’ll note that I have Luna’s “d3d12book\MyDemos” folder in my root (C:\) directory. But, do not check the checkbox for placing the solution and project in the same directory:
Right-click on the Project name, select Properties, and under General, ensure that the Windows SDK Version says “10.0 (latest installed version)”.
Also, under Properties, click on Linker > System, and change the Subsystem from Console to Windows:
Click OK.
Next, right-click on the Project again, and select Add… > Existing Item. Then go to C:\d3d12book\Common and pull across all the .cpp and .h files there into the Project:
Your Solution Explorer should then look like this:
Then, go to C:\d3d12book\Chapter 6 Drawing in Direct3D\Box, and copy BoxApp.cpp and the Shaders folder into the C:\d3d12book\MyDemos\Box folder:
Note that this must be in the top “Solution” level! There is another “Box” folder MyDemos\Box\Box, but don’t put the source there; the MyDemos\Box\Box folder holds the Project files.
Now, right-click on the Project, select Add… > Existing Item, and pull the BoxApp.cpp from its “\d3d12book\Chapter 6 Drawing in Direct3D”, into the Project:
You see that BoxApp.cpp is now part of the Project.
Now, we have to deal with an old artifact in the Luna’s code. Within d3dApp.cpp, there is a function call at line 547:
HANDLE eventHandle = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
This must be replaced with:
HANDLE eventHandle = CreateEventExW(nullptr, nullptr, NULL, EVENT_ALL_ACCESS);
There’s some history to this change that I haven’t thoroughly researched, but you need to do it; otherwise, the compiler will always error out with “invalid argument” C2664:
I made this change directly to the d3dApp.cpp within the Common folder, so I wouldn’t have to change it for each and every single Project.
Then, the Project will Build!
Note, you’re going to see a couple of Warnings:
1>C:\d3d12book\Common\d3dUtil.cpp(30,5): warning C4244: ‘argument’: conversion from ‘std::streamoff’ to ‘SIZE_T’, possible loss of data
1>C:\d3d12book\Common\d3dUtil.cpp(70,32): warning C4244: ‘=’: conversion from ‘UINT64’ to ‘LONG_PTR’, possible loss of data
But, these don’t seem to affect the outcome.
WAIT! There’s one more thing you need to do. The executable needs to be copied up one level, to get it into the same folder that holds the Shaders folder, for the executable to run without this error message:
So, copy Box.exe from C:\d3d12book\MyDemos\Box\Debug up to C:\d3d12book\MyDemos\Box:
And then, double-click on it:
It works! That’s all there is to it.
Hopefully, someone who might be stuck trying to get Luna’s demo programs to work reads this, and finds it helpful. The book looks really good: it was fun and satisfying to reverse-engineer the demo programs and get that thrill of having the programs run successfully. I’ll write more about what I learn as I plow through the material.