I promised in the last blog post that I would make progress getting the sprite batch component of Xentu functional. It’s a week late, however I have good news as the component now works!
Before we dive into how I managed to make the largest leap forward for the project in many months. I want to talk about burn-out.
Coders like myself are prone to focusing too much on the digital world. Considering it’s what we love, can you really blame us? I believe the whole Covid-19 thing and Lock-down this year has compounded this effect though. With more of a reason to stay inside, it’s been almost like enabling an addiction for me.
This personally came to ahead just over a week ago when I posted the last update. I was getting to a point where mental fatigue was wearing me out. In work I was getting snappy and neglectful. In friendships I was less attentive, and especially trying to make headway on personal projects like Xentu I was failing to concentrate enough.
Getting Away For A While
So considering it was my birthday week, and I had booked time off. I decided to switch gears and get away for a while (sans the laptop!). Some of my savings were used to buy some basic camping gear, then I literally booked the first campsite I could find, and set-off the next day!
On Wednesday I arrived at a campsite (pictured above) with beautiful views looking over Snowdonia national park. While there I visited the town of Betws-y-coed, hiked up to lake Llyn Elsi, ate pub lunches with local ale, and talked late into the night with fellow campers I made friends with called Pete and Marie. It was awesome!
Getting older makes you realise how important it is to reset sometimes. If you are like me, consider taking a break too, as this few days gave my mind a time to rest, and I feel truly re-invigorated! Now back to the big news.
Sprite Batch Drawing Theory
So last week I said that I am using a project called Moony along side the SFML media library for inspiration. A clever quirk Moony is that it implements a sprite object which inherits a Transformable base class from SFML. This gives Moony the ability to calculate transforms (translation, scale, rotation) before building batches of sprites to render.
The job of a sprite batch is to collate sprites in “batches” by layer and texture. This enables you to draw many sprites at once with as minimal draw calls as possible. These systems break the process up into 3 stages;
Initialisation | Image blending rules are set, and batches are cleared ready for new sprites. |
Drawing | Sprites are “drawn” or organised into batches. |
Presentation | The batches are converted to vertex data then sent to the GPU for rendering. |
For Xentu I need to be able to expose this flow to Lua code in a reliable and unbreakable way. I decided the best way for me to do that is like this:
-- drawing event
game.on("draw", function()
game.sprites.begin()
game.sprites.draw_sprite("test", 25, 25, 50, 50)
game.sprites.present()
end)
The syntax is not final, and I suspect I’ll be changing draw_sprite() to just plain old draw(), however you can hopefully see what I am trying to achieve. Through these few lines of code we should see a sprite using the texture “test” at 25,25 with a size of 50 by 50 pixels, elegant right?
Binding To C++
In C++ I have to figure out how to make the above code work like Moony. This is where I began struggling with the implementation. When using Lua to script a C++ game, it can be unwise to constantly allocate memory as you have to do a lot of work to clean up. This makes that clever Sprite class that Moony uses is a no go, because it would use more memory than needed and require I start using smart pointers (which I really don’t want to do).
After a lot of pondering during my break in Wales, I somehow solved the problem. Instead of using many sprite instances, I instead just use 1 statically. This actually works great, because Moony doesn’t use the sprite class for much more than transforms anyway. In their example they basically just convert a sprite class into vertex data immediately. So treating the sprite class as a vertex transforming factory actually allows me to write cleaner sprite batch code!
So here it is running in all it’s glory! In the screenshot I wrote some extra Lua to test a simple animation I created. The biggest things to note here are that the frame-rate is ridiculously high, and the memory footprint below 23 megabytes is so much more efficient than how Xentu runs on C#.
It’s clear now that moving to C++ for the game engine is what the project needed. With one big step closer, next I’ll be tackling cleaning up the code, and working on feature parity. There is a lot to pull over from the C# build still, however the hardest bit is now over.
Wrapping Up
There has been an up-tick in visitors lately, and if you’ve read this far into the blog post I just want to say thanks. I know there is not much visually to show yet, but things are going to get more exciting throughout the rest of this year.
Thanks for sticking around, and I’ll see you next time!
Koda