If you like this, you may also like my similar project: [raycastlib](https://gitlab.com/drummyfish/raycastlib). These two libraries can very easily be combined together -- here is a proof-of-concept gif (environment rendered with raycastlib, cubes with small3dlib):
- **Different drawing strategies** to choose from: none, z-buffer (none, full, reduced), triangle sorting (back-to-front, fron-to-back with stencil buffer).
- Triangles provide **barycentric coordinates**, thanks to which practically anything that can be achieved with OpenGL can be achieved (texturing, shading, normal-mapping, texture fitering, transparency, PBR, shadow mapping, MIP mapping, ...).
- **Different near plane coliision handling strategies**, several options: cull, push, geometrically correct clip, geometrically and barycentric correct clip. Choose the one that best suits you program.
- At the moment there is no wireframe rendering, but you can simulate it easily (see model viewer example), or write it by hand (drawing lines is not that hard).
- Due to the limitations of using only integer arithmetics, some types of movement (particularly camera) **may look jerky, and artifact may appear** in specific situations. This can partially be fixed with `S3L_USE_WIDER_TYPES`.
- There's no extensive error and memory safety checking, you're supposed to not try to crash the library.
- There are **no built in-shaders, I/O, LOD, mipmaps, texture filtering, collision detection, sprite drawing, terrain, bone animation, font drawing, postprocessing, v-sync, sound** and other things you might find in the "big" engines. This is only a simple 3D rasterization library, you're supposed to implement the above mentioned things yourself (or use other libraries), however it's not that hard and it's usually the fun step. Check out the examples to see how it's done.
For start take a look at the [helloWorld.c](programs/helloWorld.c) program, then [terminalCube](programs/terminalCube.c) and then other examples (e.g. `level.c` shows simple integration with SDL).
For more see the other examples and **the library code itself**, it is meant to be self-documenting, i.e. the source code IS the documentation -- you'll find the description of a lot of things at the start of the file. You can also use doxygen to generate an HTML documentation.
and tells you which pixels you should write. How you do it is up to you, you can use whatever library that can draw pixels to the screen to do it (SDL, SFML, X11, QT, ncurses, ...).
- **Before including the header, define `S3L_PIXEL_FUNCTION`** to the name of a function you will use to
- Also **init screen resolution**, either by defining `S3L_RESOLUTION_X` and `S3L_RESOLUTION_Y` (before including the library) or by setting `S3L_resolutionX` and `S3L_resolutionY` variables.
- Your pixel drawing function (`S3L_PIXEL_FUNCTION`) will mostly be the performance bottleneck, try to make it as fast as possible. The number of pixels is usually much higher than the number of triangles or vertices processed, so you should focus on pixels the most.
- In your `S3L_PIXEL_FUNCTION`**use a per-triangle cache!** This saves a lot of CPU time. Basically make sure you don't compute per-triangle values per-pixel, but only once, with the first pixel of the triangle. You can do this by remembering the last `triangleID` and only recompute the value when the ID changes. See the examples for how this is done.
- Some things, such as screen resolution, can be specified as static (compile time, can't change during run time) or dynamic. If you can, prefer setting them to static and a power of two (e.g. `#define S3L_RESOLUTION_X 512`) to increase performance!
- Seeing buggy triangles flashing in front of the camera? With the limited 32bit arithmetic far-away things may be overflowing. Defining `S3L_USE_WIDER_TYPES` to `1` will likely help. Besides this you can try to scale down the scene. If you also don't mind it, set `S3L_STRICT_NEAR_CULLING` to `1`. With a bit of work you can implement big scene rendering even without wider types by multipass rendering (first render the far away scene scaled down, then clear z-buffer and render the near part of the scene over it).
- Seeing triangles weirdly deform in front of the camera? See `S3L_STRICT_NEAR_CULLING == 0`, you may set it to correctly handle near plane culling for a cost of some performance, or you may try different things like subdividing your model to more triangles which may reduce the negative effect.
- Seeing triangles disappear randomly in sorted modes? This is because the size of the memory for triangle sorting is limited by default -- increase `S3L_MAX_TRIANGLES_DRAWN`.
- Sorted mode sorts triangles before drawing, but sometimes you need to control the drawing order more precisely. This can be done by reordering the objects in the scene list or rendering the scene multiple times without clearing the screen.
Everything in this repository is CC0 1.0 (public domain, https://creativecommons.org/publicdomain/zero/1.0/) + a waiver of all other IP rights (including patents and trademarks).
This project is made out of love and to be truly helpful to everyone, not for any self interest. I want it to forever stay completely in the public domain, not owned by anyone.
This is not mandatory but please consider supporting free software and free culture by using free licenses and/or waivers.
You can also choose to use this under the following waiver which is here to just ensure more legal safety and waiving of additional IP such as patents:
The intent of this waiver is to ensure that this work will never be encumbered by any exclusive intellectual property rights and will always be in the public domain world-wide, i.e. not putting any restrictions on its use.
Each contributor to this work agrees that they waive any exclusive rights, including but not limited to copyright, patents, trademark, trade dress, industrial design, plant varieties and trade secrets, to any and all ideas, concepts, processes, discoveries, improvements and inventions conceived, discovered, made, designed, researched or developed by the contributor either solely or jointly with others, which relate to this work or result from this work. Should any waiver of such right be judged legally invalid or ineffective under applicable law, the contributor hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to this right.