This blog series is a part of the write-up assignments of our Game Engineering II class in the Master of Entertainment Arts & Engineering program at University of Utah.

This first assignment is mostly about how to link multiple projects and setting up dependencies. Before, when I was setting up dependencies between projects or static libraries, I usually just used the linker inside the property page, and then store them for future use. I don’t think I have ever used the project dependencies to allow Visual Studio to set up the build order for me, which was really useful. Especially considering that our solution contains 28 different projects now!

After creating a new Graphics project, we needed to add some projects to the Graphics reference, also add the newly created Graphics project to other project’s reference. One problem that I encounter right here was that I tried to build the solution before setting the dependencies, and then I look at the output window to check what the projects are that I needed to add dependencies for. But it turned out that it did not show all of the projects that the Graphics project actually need. The problem was fixed after I went through the source files one by one and looked at all the includes. When adding the Graphics library to other project’s reference, I thought the ShaderBuilder also needed a reference to the Graphics project, but it turned out it did not need it since it was only referencing the enums but not using any functions.
When setting external libraries, since visual studio won’t automatically handle the chain of “external libraries” within “static libraries”, we needed to use the

#pragma comment( lib, "someLibrary.lib" )

Official doc here
which
“is a compiler directive which indicates Visual C++ to leave a comment in the generated object file. The comment can then be read by the linker when it processes object files. It tells the linker to add the ‘libname’ library to the list of library dependencies, as if you had added it in the project properties at Linker->Input->Additional dependencies”
(from this post)

Edit:

This method of handling external libraries will only work on Windows platform therefore is not universal! However, this allows the libraries usage to be a part of the project setup.

When setting platform dependent codes, I always used the C preprocessor and include guards in the header, and it always worked. However, simply set the exclusion inside the files’ property page is so much cleaner! This is probably the most valuable lesson that I learned through this assignment.
After everything was set up properly, we made our own new projects for the main game, along with the asset builder project and a lua file that specifies the shader files it needed to build.
And now we can see a window displaying the botton left part of a triangle with static white color.

EngII_HW1_OriginalShader

And then, after utilizing the executing time the is being passed in to the shader, we can animate it by passing it into sin/cos function, play with some offsets and divide it by 2 at the end since the values of sin/cos ranges from [-1, +1]. I used something like this.

(sin(systemTime) + 1.0) / 2.0

ShaderScaledGif

Optional Challenges

To figure out how to manipulate time lapse with key presses, therefore affecting the shader, I looked for the source of the execution time being passed in. The shader should always render what’s being passed in without knowing what’s going on in the outside world so I definitely won’t be changing that. I found that the g_elapsedSecondCount can be traced back to cbApplicaiton.cpp line 250 where it calls the

Graphics::SubmitElapsedTime function.

On the other hand, inside the main game loop, UpdateBasedOnInput(), a virtual function overrided by MyGame class, is being called every frame. We can do our key check right here. I added a new variable called dTimeScale inside the Time namespace and a new function to set that value. Inside MyGame class, I also added a new variable to specify what our desire new time scale is when space is holding down, and a function to change the dTimeScale inside the Time namespace.
The first time I tried to compile, I got the LNK2005 already defined error, which was because I declared the variable inside the header file, which was included by multiple files. The error got fixed right after I moved that to the .cpp file.
At this point, I realized that I haven’t finished reading the assignment document, where our teacher clearly specified that there is already a function that can set the simulation rate for our application. Lesson learned, again, always finish the document first!

Final executables in below:
Press space bar to set the simulation time rate to 0.1
Windows x86 (OpenGL)
Windows x64 (Direct 3D)

Summary

This is a very interesting first assignment that I’ve ever experienced. Before, I thought this class would be about graphics and rendering systems. But it is so much more than that. Working on a large scale project and trying to maintain a clean solution can be extremely tricky, and sometimes frustrating. I feel like this class will provide us with enough training in terms of that skill. Also, using Direct 3D and OpenGL is just a mean to get us into a mentality of writing platform independent codes. I still hope to learn more about rendering and graphics in the class, but I think learning to implement good design patterns in practice is probably more useful than that.

Special thanks to

Chen Mi
Zhitao Zao
for giving me tips and helping me out with the assignment.