___. __
____\_ |__ |__| ____ __ _________ ______ ____ ______
/ _ \| __ \ | |/ ___\| | \_ __ \/ ___// __ \ / ___/
( <_> ) \_\ \ | \ \___| | /| | \/\___ \\ ___/ \___ \
\____/|___ /\__| |\___ >____/ |__| /____ >\___ >____ >
\/\______| \/ \/ \/ \/
objcurses is a minimalistic 3D object viewer that runs in your terminal using ncurses
. It renders .obj
models in real time using ASCII characters and a simple rendering pipeline. The project was built from scratch in modern C++20 using up-to-date best practices and a clean modular design, as a personal exploration of low-level graphics programming - without relying on external graphic engines or frameworks.
- Render
.obj
files directly in terminal - Real-time camera and directional light control
- Basic color support from
.mtl
material files - Start animation with consistent auto-rotation
- HUD overlay for additional stats
- Minimal dependencies: C/C++,
ncurses
, math
- Preview 3D files instantly without launching heavy editors
- Generate custom ASCII art for neofetch or terminal splash
- Style CLI tools or games with ASCII-based intros and visuals
- Animate coding workspace with rotating retro-style ASCII models
- Create stylish character-based GIFs from terminal-rendered scenes
objcurses [OPTIONS] <file.obj>
-c, --color <theme> Enable colors support, optional theme {dark|light|transparent}
-l, --light Disable light rotation
-a, --animate <deg> Start with animated object, optional speed [default: 30.0 deg/s]
-z, --zoom <x> Provide initial zoom [default: 1.0 x]
--flip Flip faces winding order
--invert-x Flip geometry along X axis
--invert-y Flip geometry along Y axis
--invert-z Flip geometry along Z axis
-h, --help Print help
-v, --version Print version
Examples:
objcurses file.obj # basic
objcurses -c file.obj # enable colors
objcurses -c transparent file.obj # set transparent color theme
objcurses -c -a -z 1.5 file.obj # start animation with zoom 1.5 x
objcurses -c -a 10 file.obj # start animation with speed 10.0 deg/s
objcurses -c --invert-z file.obj # flip z axis if blender model
Supports arrow keys, WASD, and Vim-style navigation:
←, h, a Rotate left
→, l, d Rotate right
↑, k, w Rotate up
↓, j, s Rotate down
+, i Zoom in
-, o Zoom out
Tab Toggle HUD
q Quit
Latest release available here. Replace <version>
with the actual release version, e.g. 1.2.3
.
To manually compile and install objcurses
, follow these steps:
Make sure you have CMake and a C++ compiler installed:
sudo apt update
sudo apt install cmake g++ libncurses6 libtinfo6 -y
git clone https://github.com/admtrv/objcurses
cd objcurses
mkdir cmake-build-release
cd cmake-build-release
cmake ..
make
sudo make install
To install objcurses
from the binary archive:
tar -xzvf objcurses-<version>-linux.tar.gz
cd objcurses-<version>-linux
sudo mv objcurses /usr/local/bin/
sudo chmod +x /usr/local/bin/objcurses
For Debian-based distributions (Ubuntu, Mint, etc.), use:
sudo dpkg -i objcurses-<version>-linux.deb
To uninstall:
sudo dpkg -r objcurses
which objcurses
objcurses --help
You should now be able to use objcurses
from anywhere in your terminal.
-
Codeology The seed of an idea. Codeology visualizes GitHub repositories as abstract 3D shapes made from symbols. This inspired me to create an ASCII-based 3D renderer from scratch.
-
Donut math (a1k0n) Cool article that breaks down the logic of the classic
donut.c
- a rotating ASCII torus in terminal using C. A great example of terminal 3D rendering and a key resource for understanding core rendering math. -
3D ASCII Viewer (autopawn) Viewer of 3D models in ASCII, written in C. I treated it as a logical predecessor to my project - it helped me explore how more complex rendering math could work.
-
Data Types (OpenGL Documentation) Used to understand standard OpenGL types like
vec3
, etc. -
Polygon triangulation (Wikipedia) For correctly converting complex polygon shapes into triangles for rendering.
-
OBJ Parsing (Stack Overflow) Clarified parsing of
.obj
files and preparing vertex data.
All files are located in /resources/objects/
.
- Fox Model (PixelMannen) was used throughout development for testing
.obj
and.mtl
parsing and rendering.
- Low Poly Tree (kiprus) played a key role in identifying a flaw in the triangulation algorithm, as it contains complex non-convex polygons that exposed edge cases in ear clipping algorithm.
- Linux Mascot (Vido89) model help in fixing triangulation logic by triggering false degenerate cases due to its irregular normals and detailed geometry.
- PlayStation Logo (Jay6T4) revealed a bug in the projection-to-viewport logic and showed the need for Z-axis inversion. This led to implementing axis inversion options to handle incorrectly exported Blender models. Also interesting to see live after this publication.