Downloadable
Controls:
Exit: ESC or click X
Pause/Resume: Space
Key Points
Overall, assignment 2 requires us to separate platform-specific code from platform-independent code. In order to make function calls without knowing details from a lower level, we need to create an interface that’s not affected by what the real implementations are.
Let’s Refactor!
For this assignment, there are two things we need to move into our new classes. One is mesh(geometry), and the other is effect(shading).
Refactoring can become a mess, though sometimes all we do is copying and pasting. It’s easy to forget some variables only exist in certain scopes. My strategy is to find all lines that reference the data needed for rendering. After doing some reading, I notice these lines are in three places: initializing, cleaning up, and rendering frame. Accordingly, lines from these functions should be put into three different functions defined in class, which was what I thought at first.
Geometry related data went into Mesh class. It took me a while to think about what would happen if one more mesh were added. Currently, the code in the Mesh class was designed to draw triangles only. Changing the interface or moving data into Mesh class could be inappropriate and more problematic in the future. Therefore, I chose not to modify anything for now.
Shader data was put into Effect class. In my opinion, this one was so much easier, since if we want to load different files, we only need to use another path. Therefore, I added two parameters to the initializing function. There was also some code that gl platform and d3d platform had in common. I added some private platform-independent functions so that I could call them in platform-specific functions.
After doing all the above, I only need to call s_Effect.Bind() and s_Mesh.Draw() in rendering function.
Now, comparing two graphics files, there are still some differences. D3d platform needs to initialize view before initializing graphics and the RenderFrame function is still platform-specific. One solution I can think of is to create an abstraction of the higher level, so that they all share the same interfaces. Mesh and effect can be injected in as configurations. We can keep an array in this higher-level abstraction so that we can have control over all meshes and effects.
Add Another Triangle
After refactoring the code, we can start adding another triangle to our game. Basically, we only need to change 1 triangle to 2 triangles in both initializing and rendering functions in Mesh class.
Then we need to come up with a set of vertices. One thing I think should be paid attention to besides winding orders is that the origin of the coordinate system is the center of the window.
Here are my squares:
I also drew a house!
Useful Debugging Tool
It’s quite convenient and easy to use visual studio graphics analyzer to debug direct 3d project. With just running the game and pressing prtscn, we can capture any frame we want, and select and view a lot of useful information on how our game uses direct 3d, like call stacks.
However, I did run into some trouble getting RenderDoc to work. First of all, I notice that it can only run the release version. Secondly, even after I switched to the release version, my game crashed when launched in RenderDoc. After reading some documents, I supposed it might be caused by the graphics card, so I ran it again on a different computer and it worked! I think it’s probably because the OpenGL version is not compatible with RenderDoc.
Direct3D:
OpenGL:
Comments