David Piuva's Software Renderer is a static C++ library for graphics and user interfaces. You don't need to install OpenGL or any third party media layer. Replace all of that with one static library that calls the system directly and actually works. No more missing drivers, complex extension wranglers, feature flags, awkward legacy limitations, closed proprietary features, driver bugs, blue-screen crashes, shader dialects, random funky colors, failed pixel alignments, incompatible screen resolutions... This library takes the safe route and still gets more than enough performance for most needs.
The current beta runs on Linux and Windows. If you find a bug in the library, you can change it in the source code and let the library recompile automatically using the build system. Just don't forget to make a pull-request with your bug fix, so that it won't break next time you pull an update.
The main feature is to efficiently render isometric scenes on the CPU using a set of depth-buffered 2D draw calls. By pre-rendering diffuse, normal and position maps using an offline rendering tool, the game can then have unlimited detail level like in old 2D games, but with pixel-exact depth masking and modern dynamic light. The Sandbox example demonstrates how this technique can be used for real-time light sources with deferred normal mapping and depth based shadows cast from 3D models in a lower triangle count.
You don't need to emulate 2D graphics on top of a complex 3D graphics pipeline. The software-renderer is a non-equivalent replacement for OpenGL that focuses on having more than just 3D. While the GPU might struggle to render a retro 2D game in 60 frames per second because of 3D pipeline overhead and many small sprites being drawn, a CPU can reach 300 frames per second with the same dynamic light effects by designing the game around how cache prediction works and not having a huge overhead from draw calls.
Zero dependency library All features are one implementation in one static library. It only depends on the C++ language itself and C compiler extensions. All dynamic dependencies like X11 are added when needed by the application to keep the core clean.
Simple open source license terms Mainly using the permissive ZLIB open source license, and public domain for the rest. The stb_image library is included in the source code under public domain terms, so that you don't have to worry about getting sued over forgetting a name in the credits of a binary release, or having someone pulling back contributions in anger. It's all non-revocable and doesn't require crediting. Forced crediting don't generate much attention to open source projects anyway, so it's better to have a few users actively endorsing it.
Full screen the hardware agnostic way Instead of trying to change the display to a random resolution and wait for the crash like most media layers do, the resolution can be up-scaled on the CPU. Multi-threading is used to upload the resulting image to the screen while the application does single-threaded logic for the next frame.
2D features:
- Print text using bitmap fonts.
- Draw basic shapes.
- Draw images with different filter effects.
- Create images from lambda functions in a compact and memory efficient way. Useful for generating images when starting an application.
- Multi-threading and SIMD abstractions for high performance when making real-time image filters. Also useful for machine vision instead of OpenCV if you prefer to make custom image filters from scratch for better performance with less dependencies.
Isometric features:
- Depth buffered 2D draw calls using multiple target images, allow drawing isometric sprites with normal maps. Depth clipping per pixel allow creating larger and more complex isometric sprites because you are no longer limited to tiny convex shapes for sprites.
- Engine specific features like dynamic light are implemented in the Sandbox example. These will most likely be heavily modified to optimize performance in new games, so time will tell if a new set of reusable functions will move into the core library or if an engine will become reusable enough with many settings.
3D rasterization features:
- Fixed function rendering pipeline using SIMD-vectorization and multi-threading
- Depth buffers use linear Z for isometric cameras and 1 / Z for perspective cameras
- Bounding box culling against camera view frustum
- Occlusion is currently only implemented on the pixel level, so you get correct results but it could be faster for first person games with many overlapping surfaces. There are plans for implementing hierarchical Z-buffer occlusion, but it's more urgent to make sure that everything's working first.
- Optional multi-resolution texture pyramids
- Bi-linear texture sampling
- Alpha filtering
- Light-maps
- Vertex colors
- Render to texture
Graphical user interface features:
- Load a layout from file or embedded text using a single line of code.
- Flexible coordinate system using both relative anchors and absolute offsets. Setting an X coordinate to 20%+4 will place the location at 80% of the parent's left side, 20% of the parent's right side and then adjust 4 pixels to the right. No need for having split panels everywhere, just focus on organizing the major groups using invisible panels and scalable coordinates.
- Connect actions in lambda functions with components by name in the layout file.
- Resolve identical names by index.
- Built-in frame, button, label, picture and list-box components. Still experimental because the exact behavior is highly subjective, so count on changes here.
- Ability to create and register custom components. Once registered with the class name at start-up, they can be created from a layout file.
- Dynamic theme system using a virtual machine to draw scalable graphics. This can later be used for generating custom themes, but first the basic components have to be implemented to avoid incomplete themes.