This assignment was both interesting and less “hand-holdy” than the previous ones. The instructions were pointing in the right direction but never actually telling you exactly what needs to be done. I loved it, because I got to exercise my brain and explore the code base to figure out the solutions.
The end goal of the assignment was to have textures on the sprites that we are rendering. I started out by adding the “TextureBuilder” project to the solution and setting up its dependencies. The next step was building the textures using the lua script from last time. I added some more function calls in the script that would invoke the TextureBuilder functions to build the textures. The tricky part in this was to figure out how to get my TextureBuilder project to build before the AssetBuilder could access it. I kept getting errors from my lua script saying that it couldn’t find TextureBuilder.exe. This led me down a rabbit hole of following reference until I figured out where the first call that triggered the asset build was coming from, it was BuildExampleGameAssets. By adding a TextureBuilder as a project dependency to this project I was able to make sure that the project was built and the .exe file was there for the lua file to access.
Adding the UV data in the C++ code in a convenient way was a bit tricky but not too hard. The requirement was to not have the user input the values and instead infer the right UV values from the vertex data. Because of the way I make the user submit the initial vertex data (top left vertex, width and height), it was easy for me to figure out the U values because they are the same for D3D and OpenGL. I had to think a bit about how I would populate the V data because they are inverted for D3D and OpenGL; I didn’t want to have platform specific functions that would do the V data calculation. I managed to end up having a single implementation which would set the UV data based on whether the vertex was on the left/right/top/bottom of the sprite and drive the U and V values through const member variables (0 or 1). I used preprocessor macros to drive the platform specific V values for top and bottom of the sprite.
Now that the textures and were built and their UV data was ready, I had to load them and render them in my code. To do this I had to use our Professor John-Paul’s (JP) Texture handle which would create a Handle that could then be passed around and used to call specific functions. The handle represents a reference counted pointer. The use of the handle prevents a file from being loaded more than once. When a request to load a file is made, the manager checks if it already has a handle for it, if a handle exists, the pointer reference count is incremented and a new handle is returned. This means that the handle never has any real idea about the definition or implementation of the pointer it represents. This means that we can’t increment the reference count directly using the handle, we instead need to use the manager to get the pointer that the handle represents and call the increment function on that. Decrementing the reference count however, is pretty straightforward and can be done by calling the manager’s Release function and passing the handle in, the manager will then destroy the handle and decrement the reference count of the relevant pointer. If we attempt to decrement the reference count directly we could end up with a situation where a handle could be representing a pointer that has been destroyed.
Once everything was ready I could finally load my textures and show them on the screen.
For the textures, I decided to use pixel art images three of my favourite characters from Dark Souls, Siegmeyer of Catarina, Solaire of Astora and Knight Artorias. One of the objectives of the assignment was to have one of the sprites change every time a certain period has passed. I decided to use a gif of Knight Artorias, split it into its individual frames and swap textures cyclically at a rate of 24 frames per second (every 0.042 seconds). Another objective was to change a texture based on key press. I set it up so that when the Space key is held down, the Siegmeyer and Solaire sprites get swapped. To achieve this I had to do some pretty dirty coding, namely declaring each of these textures as individual member variables of my game class but I am pretty happy with the way it turned out.