Z3dPy is my 3D game engine that runs in Python. It can be used with any library that can draw to a screen.
This was just a personal project for fun, I wasn't planning on turning it into a module, until I looked online and found that the only 3D engines in Python were made specifically for the game it runs, and the ones that do exist are written entirely in C or C++. I decided to make a 3D engine that could run entirely within Python, no math modules required, no 3D modules required. Because of the cross-platform nature of Python I made sure that it didn't depend on a single display or input method, but for convenience I ended up writing some Windows API support so that the barrier for entry is even lower, at least on Windows. I was also aiming to make a 3D engine that was simple, while being customizable. I wanted it to feel like a retro computer where it's so simple, and the documentation is well made, so the person using it knows everything there is to know about it, but that doesn't limit what you can do with the computer.
There were quite a few compromises I had to make to get it running in real time, the main one is shading. Z3dPy mostly relies on whatever display module you have to draw triangles quickly, but all of them accept a single colour for the whole shape, you can't blend between vertex colours or anything like that so the only fast option for drawing triangles forces the shading to be primitive.
Depth turned out to be a real issue as well, as 2D libraries don't have depth buffers or any depth interpolation, so triangles can only be drawn on top or below other ones, so large triangles can confuse the engine and get placed too high or too low.
Introducing, Z3dPyFast 3.0
On Windows, z3dpyfast can now handle both the window and reading inputs from the mouse and keyboard. The display API is custom-made using bitmaps, and then blitz'd to the screen with Direct2D and displayed in a window using the Windows API. This allowed me to implement my own 3D specific features that need C++ to draw quickly, like depth culling, vertex colour interpolation, and more in the future. The input API uses DirectInput to read the state of the mouse and keyboard, while the mouse data can be used as is, the keyboard only returns wether a key is pressed or not, so I wrote my own mapping system to divide it up into pressed, held, and released, making it much easier to implement complex control schemes.