The Juggler: In Rust

render of the Amiga juggler demo

Back on the theme of learning to program by taking on a meaningful project — we have another raytracing demo — this time using Rust on the Raspberry Pi. [Unfastener] saw our previous article about writing a simple raytracer in spectrum BASIC and got inspired to try something similar. The plan was to recreate the famous juggler 3D demo, from the early days of 3D rendering on the Amiga.

The juggler story starts with an Amiga programmer called [Eric Graham] who created ssg, the first ray tracer application on a personal computer. A demo was shown to Commodore, who didn’t believe it was done on their platform, but a quick follow-up with the actual software used soon quelled their doubts. Once convinced, they purchased the rights to the demo for a couple of thousand dollars (in 1986 money, mind you) to use in promotional materials. [Eric] developed ssg into the popular Sculpt 3D, which became available also on Mac and Windows platforms, and kick-started a whole industry of personal 3D modelling and ray tracing.

Anyway, back to the point. [Unfastener] needed to get up the considerable Rust learning curve, and the best way to do that is to let someone else take care of some of the awkward details of dealing with GUI, and just concentrate on the application. To that end, they use the softbuffer and winit Rust crates that deal with the (important, yet frankly uninteresting) details of building frame buffers and pushing the pixels out to the window manager in a cross-platform way. Vecmath takes care of — you guessed it — the vector math. There’s no point reinventing that wheel either. Whilst [Unfastener] mentions the original Amiga demo took about an hour per frame to render, this implementation runs in real-time. To that end, the code performs a timed pre-render to determine the most acceptable resolution to get an acceptable frame rate, achieving a respectable 30 or so frames per second on a Pi 5, with the older Pis needing to drop the resolution a little. This goes to show how efficient Rust code can be and, how capable the new Pi is. How far we have come.

We saw another interesting rust-based raytracer a while back, which is kinda fun. We’ve also covered rust in other applications a few times, like inside the Linux kernel. Finally here’s our guide to getting started with rust, in case you need any more motivation to have a crack at this upcoming language.

12 thoughts on “The Juggler: In Rust

  1. Give it to me straight boys, should I learn Rust? I work with Cortex M4 MCUs mostly.

    I find the push towards using Rust inorganic and unnatural, and I cannot help feel someone stands to gain by its adoption. That aside, I also don’t really look at languages as anything more than tools, so if a “superior” tool is available, I’ll learn to use it.

      1. They really aren’t.

        They are tools that can be used for the job, but they’re comparable to using a pair of mole grips to tighten a bolt when you have a powered socket wrench with torque control in your toolbox.

    1. Yeap, you should! Check out embassy (https://embassy.dev/), an async RTOS where all sync code is essentially a critical section and use probe-rs & defmt to debug your code. It’s mind boggling.
      Also almost everything in embedded rust is a HAL and if you play your cards right your code can easily run on different architectures, on simulators, have unit tests that can run on the host but integration tests that run on the target etc.

      Just be aware of the learning curve. it’s very steep but the moment you overcome it everything magically makes sense

    2. My experience of moving from C to Rust on similar targets has been pretty good, but the cost/benefit ratio isn’t great for everyone.
      As a beginner it’s pretty hard to work getting even basic embedded stuff to compile in Rust, part of that is that it forces you to check your assumptions constantly.
      C by comparison lets you compile any old shit, but it’s much more likely to fall apart when things don’t go quite to plan.
      If you were learning either language from the start, I’d reccomend rust wholeheartedly for development and C only as an educational tool, but if you’re an experienced C programmer you probably have pretty strong subconscious intuitions for what assumptions need checking in C, so the benefit is not as strong.
      I also found my ‘c brained’ approach often made learning rust feel frustrating, finding it hard to understand when things were ending up in stack vs heap for example.

      Main Benefits for me:
      – More robust code by default, defined behaviour for all cases, memory management mostly handled for you
      – Easier modularity – Swapping out and creating modular components is a much more refined process
      – Better portability – Mainly for the above reason, swapping between chips and architectures is fairly painless as it’s easy to abstract away the details
      – Better resources – With rust I find myself writing a lot less code. Whatever I want to do, there’s probably a crate available that does it pretty well. In C I spend a lot more time re-inventing wheels because what’s available online isn’t quite right, or is too heavily tied to another platform.

      I’ve not got much hands on experience, but I suspect working in a bigger team is less painful with rust too.
      The tooling is good, and fairly unified. You don’t have to deal with everyone’s preferred combination of 10 different programs and scripts.
      The modularity makes collaboration and splitting up work feel a lot nicer, built in testing also really helps here
      The compiler is a lot more opinionated about the ‘right way’ of doing things. Steepens the learning curve, but gets everyone on the same page faster.
      It’s just harder to write bad code, reviewing contributions from less experienced devs is way easier because you know the compiler has caught all the basics for you.
      You can focus on the intent and behaviour, instead of doing mental gymnastics to work out if maybe in some edge case that pointer might not be initialised.

      I guess this all assumes you’re coming from C.
      From modern C++ rust can’t add much new, but it does remove lots of old and crusty.
      Rust is safe and clean by default, C++ is safe and clean if you really work at it.

    3. IMO nobody can make that choice for you. If memory safety and the knock on effects of having it are worth learning a new language and perhaps not having some library equivalents to your current workflow not a dealbreaker…

      Unless you are really really young there is probably never going to be a need to know Rust, but as Rust is looking likely to become the C family replacement as time goes on…

    4. 40-year C programmer here, and I had exactly [shinsukke]’s questions, but never voiced them quite so well.

      Thanks for the question and the excellent responses.

      I’m far enough along my professional career that I’ll expect never have a paying gig that needs Rust, but these answers have convinced me that it’s worth attempting that learning curve anyway.

    5. Been programming in C close to 20 years; I just started learning Rust a few weeks ago just to stretch myself and learn something new. My first perception was that Rust felt like C but with 40 years of hindsight. All sorts of undefined behaviors are eliminated by the language design or checked by the compiler. The compiler error/warning output is the best I’ve seen. The build system and availability of open-source crates for all kinds of takes gives me a sense of productivity almost matching Python. There’s definitely a learning curve (that I’m just starting to encounter) but my sense is that Rust’s growing popularity is well-deserved.

    6. If you ever need to use proprietary binary blobs in your project, then definitely not. Trying to get C code built with version X GCC to talk to version Y Rust is a recipe for disaster.

      However, if all your code talks directly with the hardware then you have to mark the interface as “unsafe” which eliminates the primary advantage of Rust. If you aren’t using an MCU with a decent amount of FLASH then you run into the memory allocator problem where the code for dynamic allocation is too large. If you are using static allocation then the primary advantage of Rust is a moot point.

      In the Rust language itself there are some very cool ideas but they aren’t going to be of much benefit on an MCU.

      1. You can still mess up memory access even with static allocation in C/Cpp.

        Safety isn’t magical and the unsafe keyword doesn’t remove any advantages – if you go deep enough everything is unsafe. It’s a contract specification.

    7. You should look at the benefits of rust. The increased safety offered by rust is a huge plus along with the package manager. While there are a number of rust specific concepts you need to learn to use rust effectively, starting simple is perfectly possible, introducing features when you feel comfortable with your understanding.

    8. I started to learn Rust. But, now I’m starting to see the same inorganic push that you are. The Rust Foundation showed results for a survey they put out to all their users. In certain areas, there numbers were actually down. But, they showed them as percentages so it looked like the values were going up. Feels iffy.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.