Re-Open Your Eyes
49 Days Until I Can Walk
Exactly 7 weeks until I can walk!
Actually, to be perfectly honest that timer is a little off. I expect that I’ll be putting my feet on the ground a little sooner than that. August 8th if all goes well.
Anyway, the raycast function for walls is now working again, and I think it has been greatly improved by two changes, one minor and one (kinda) major.
I have introduced a Colour struct which greatly improves the readability of the code which draws to the screen. Instead of awkwardly indexing and writing to four contiguous array elements at a time, I am now able to push colour data with the help of a struct. This struct also incorporates the logic for alpha blending, which I plan to speed up by eliminating all floating point arithmetic. Searching around on the internet, it looks like there may be some very nice optimisations which eliminate division entirely in favour of some bit shifting and logic operations. I’ll keep investigating this.
I’ve optimised the draw function by eliminating the need to compute a texture offset and step for each column as it is drawn. A wall can be a minimum height of 8 pixels and a maximum height of 640 pixels. This means that I can compute texture indices for the draw function at compile time, and simply look up which point on a texture needs to be drawn for a texture, given a wall height and row number. The table is quite large, however, at \(632 \times 200\) elements (200 being the height of the projection plane). I don’t know if it is the case that having this large array floating around will brutalize my cache, so this feels like a good experiment for profiling. But at this precise point in time, this feels like an optimisation.
As with all the other tables, this one is generated by a procedural macro and inserted into the AST during compilation. Access to the table is via a proxy function defined in the trig
package.
I also felt that the render
package was getting a little large and messy, so I broke it out into three smaller sub-modules—renderer, raycast, and camera
—which are all exposed using pub use
through the render
package. Basically, in the public API, render
is the package that contains all your tools for rendering. But internally, for the sake of making this code a bit easier to maintain and read, there are a number of submodules to make it easier to see what is going on.
Tomorrow I’ll get floors and ceilings rendering again, and maybe even get that camera moving. That should bring me pretty close to where I was before the refactor, but now with a much cleaner, better thought out code base. I really want to get some form of map editor working so I can start designing some interesting environments. After watching so many videos on procedural generation over the weekend, I would love to implement something that randomly generates a level for players to walk around. We’ll see where I am on Monday. But that’s all for now.