**What's this?** A GBA MODE4 3D Software Engine - built from scratch.

This is (very) loosely based on David's 3D soft engine in C#/JS: https://www.davrous.com/2013/06/13/tutorial-series-learning-how-to-write-a-3d-soft-engine-from-scratch-in-c-typescript-or-javascript/

Engine blueprint: a stripped-down version of [https://git.brainbaking.com/wgroeneveld/gba-sprite-engine](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine) combined with more _tonc_ library functions.

Camera rotates `2/256` units on x and y each render cycle.

You 'should' see a cube forming based on 8 vertices. It's a simple example to showcase what the `Mesh` class is about, and how `GBAEngine` handles projections.

The `RasterizerRenderer` class draws triangles as 'fast' as possible, using horizontal scanlines.

There is a fast way to lines into VRAM. I tried implementing Z-buffering, but the buffer was too big and too slow as z-coords also had to be interpolated...

At this point, I do not think it's that interesting to go on to texture mapping other than the fun of it. Even with a lot of haxx and tricks, the colored monkey won't ever spin at 30FPS...

It did improve performance. I exported a few Babylon meshes, and the octahedron with 8 faces does run at 20FPS compared to 11FPS when back-face culling was implemented (that omits rendering certain faces if z <0)

Second problem, sin/cos are expensive so we use _tonc_'s lookup tables - but they also come with weird requirements.

For instance, input is normally in radians. But we have fixed-point radians. And the lookup table is filled in `[1-512]` slices but actually requires input in `[1-FFFFh]`:

```C

INLINE FIXED fxrad2lut(FIXED rad) {

int scale = fx2float(rad) / (2*M_PI / 512);

return (scale <<6)*2;

}

INLINE FIXED fxsin(FIXED fxrad) {

if(fxrad == 0) return 0;

FIXED theta = fxrad2lut(fxrad);

FIXED sin = lu_sin(theta);

return fx12Tofx8(sin);

}

```

Divisions are a bit of a mess, but converting them to fixed-point and going back is not going to help much.

More details in `math.h`.

In any case, lots of rounding errors occur. It is luckily not a problem due to GBA's limited screen dimensions.