{"id":33185651,"url":"https://github.com/admtrv/objcurses","last_synced_at":"2026-04-04T17:39:59.163Z","repository":{"id":293362533,"uuid":"887103582","full_name":"admtrv/objcurses","owner":"admtrv","description":"ncurses 3d object viewer","archived":false,"fork":false,"pushed_at":"2025-05-22T00:25:37.000Z","size":14947,"stargazers_count":45,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-22T01:19:40.628Z","etag":null,"topics":["3d-engine","3d-graphics","ascii","ascii-graphics","ascii-rendering","c-cpp","command-line","command-line-tool","cplusplus","cplusplus-20","cpp","educational-project","from-scratch","learning-project","rendering","rendering-3d-graphics","rendering-engine","retro-programming","terminal","wavefront-obj"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/admtrv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-12T07:07:12.000Z","updated_at":"2025-05-22T00:25:40.000Z","dependencies_parsed_at":"2025-05-15T00:49:51.166Z","dependency_job_id":null,"html_url":"https://github.com/admtrv/objcurses","commit_stats":null,"previous_names":["admtrv/objcurses"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/admtrv/objcurses","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admtrv%2Fobjcurses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admtrv%2Fobjcurses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admtrv%2Fobjcurses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admtrv%2Fobjcurses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/admtrv","download_url":"https://codeload.github.com/admtrv/objcurses/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admtrv%2Fobjcurses/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31407647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-engine","3d-graphics","ascii","ascii-graphics","ascii-rendering","c-cpp","command-line","command-line-tool","cplusplus","cplusplus-20","cpp","educational-project","from-scratch","learning-project","rendering","rendering-3d-graphics","rendering-engine","retro-programming","terminal","wavefront-obj"],"created_at":"2025-11-16T05:00:20.097Z","updated_at":"2026-04-04T17:39:59.157Z","avatar_url":"https://github.com/admtrv.png","language":"C++","readme":"\n```\n      ___.        __                                          \n  ____\\_ |__     |__| ____  __ _________  ______ ____   ______\n /  _ \\| __ \\    |  |/ ___\\|  |  \\_  __ \\/  ___// __ \\ /  ___/\n(  \u003c_\u003e ) \\_\\ \\   |  \\  \\___|  |  /|  | \\/\\___ \\\\  ___/ \\___ \\ \n \\____/|___  /\\__|  |\\___  \u003e____/ |__|  /____  \u003e\\___  \u003e____  \u003e\n           \\/\\______|    \\/                  \\/     \\/     \\/ \n```\n\n**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.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/demo.gif\" alt=\"TUI Demo Gif\" width=\"600\"\u003e\n\u003c/p\u003e\n\n# Features\n\n- Render `.obj` files directly in terminal\n- Real-time camera and directional light control\n- Basic color support from `.mtl` material files\n- Start animation with consistent auto-rotation\n- HUD overlay for additional stats\n- Minimal dependencies: C/C++, `ncurses`, math\n\n# Use Cases\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/usage.gif\" alt=\"One Use Case\" width=\"800\"\u003e\n\u003c/p\u003e\n\n* Preview 3D files instantly without launching heavy editors\n* Generate custom ASCII art for neofetch or terminal splash\n* Style CLI tools or games with ASCII-based intros and visuals\n* Animate coding workspace with rotating retro-style ASCII models\n* Create stylish character-based GIFs from terminal-rendered scenes\n\n# Usage\n\n```bash\nobjcurses [OPTIONS] \u003cfile.obj\u003e\n```\n\n## Options\n\n```\n-c, --color \u003ctheme\u003e  Enable colors support, optional theme {dark|light|transparent}\n-l, --light          Disable light rotation\n-a, --animate \u003cdeg\u003e  Start with animated object, optional speed [default: 30.0 deg/s]\n-z, --zoom \u003cx\u003e       Provide initial zoom [default: 1.0 x]\n    --flip           Flip faces winding order\n    --invert-x       Flip geometry along X axis\n    --invert-y       Flip geometry along Y axis\n    --invert-z       Flip geometry along Z axis\n-h, --help           Print help\n-v, --version        Print version\n```\n\nExamples:\n\n```bash\nobjcurses file.obj                # basic\nobjcurses -c file.obj             # enable colors\nobjcurses -c transparent file.obj # set transparent color theme\nobjcurses -c -a -z 1.5 file.obj   # start animation with zoom 1.5 x\nobjcurses -c -a 10 file.obj       # start animation with speed 10.0 deg/s\nobjcurses -c --invert-z file.obj  # flip z axis if blender model \n```\n\n## Controls\n\nSupports arrow keys, WASD, and Vim-style navigation:\n\n```\n←, h, a            Rotate left\n→, l, d            Rotate right\n↑, k, w            Rotate up\n↓, j, s            Rotate down\n+, i               Zoom in\n-, o               Zoom out\nTab                Toggle HUD\nq                  Quit\n```\n\n# Installation\n\nLatest release available [here](https://github.com/admtrv/objcurses/releases). Replace `\u003cversion\u003e` with the actual release version, e.g. `1.2.3`.\n\n## Manual (build from source)\n\nTo manually compile and install `objcurses`, follow these steps:\n\n### Install Dependencies\n\nMake sure you have CMake and a C++ compiler installed:\n\n```bash\nsudo apt update\nsudo apt install cmake g++ libncurses6 libtinfo6 -y\n```\n\n### Clone the Repository\n\n```bash\ngit clone https://github.com/admtrv/objcurses\ncd objcurses\n```\n\n### Compile the Program\n\n```bash\nmkdir cmake-build-release\ncd cmake-build-release\ncmake ..\nmake\n```\n\n### Install for Global Use (optional)\n\n```bash\nsudo make install\n```\n\n---\n\n## From `.tar.gz`\n\nTo install `objcurses` from the binary archive:\n\n```bash\ntar -xzvf objcurses-\u003cversion\u003e-linux.tar.gz\ncd objcurses-\u003cversion\u003e-linux\nsudo mv objcurses /usr/local/bin/\nsudo chmod +x /usr/local/bin/objcurses\n```\n\n---\n\n## From `.deb`\n\nFor Debian-based distributions (Ubuntu, Mint, etc.), use:\n\n```bash\nsudo dpkg -i objcurses-\u003cversion\u003e-linux.deb\n```\n\nTo uninstall:\n\n```bash\nsudo dpkg -r objcurses\n```\n\n---\n\n## Verify Installation\n\n```bash\nwhich objcurses\nobjcurses --help\n```\n\nYou should now be able to use `objcurses` from anywhere in your terminal.\n\n# References\n\n## Inspirations\n\n* [Codeology](http://codeology.kunstu.com/)\n  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.\n\n* [Donut math (a1k0n)](https://www.a1k0n.net/2011/07/20/donut-math.html)\n  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.\n\n* [3D ASCII Viewer (autopawn)](https://github.com/autopawn/3d-ascii-viewer)\n  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.\n\n## Resources\n\n* [Data Types (OpenGL Documentation)](https://www.khronos.org/opengl/wiki/Data_Type_%28GLSL%29)\n  Used to understand standard OpenGL types like `vec3`, etc.\n\n* [Polygon triangulation (Wikipedia)](https://en.wikipedia.org/wiki/Polygon_triangulation)\n  For correctly converting complex polygon shapes into triangles for rendering.\n\n* [OBJ Parsing (Stack Overflow)](https://stackoverflow.com/questions/52824956/how-can-i-parse-a-simple-obj-file-into-triangles)\n  Clarified parsing of `.obj` files and preparing vertex data.\n\n## Sample Models\n\nAll files are located in `/resources/objects/`.\n\n* [Fox Model (PixelMannen)](https://opengameart.org/content/fox-and-shiba) was used throughout development for testing `.obj` and `.mtl` parsing and rendering. \n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/fox-1.png\" width=\"600\"\u003e\n\u003c/p\u003e\n\n* [Low Poly Tree (kiprus)](https://free3d.com/3d-model/low_poly_tree-816203.html) 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.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/tree-1.png\" width=\"600\"\u003e\n\u003c/p\u003e\n\n* [Linux Mascot (Vido89)](https://blendswap.com/blend/23774) model help in fixing triangulation logic by triggering false degenerate cases due to its irregular normals and detailed geometry.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/linux-1.png\" width=\"600\"\u003e\n\u003c/p\u003e\n\n* [PlayStation Logo (Jay6T4)](https://www.models-resource.com/playstation/systembios/model/33332/) 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](https://www.reddit.com/r/Damnthatsinteresting/comments/1kkbruu/the_original_playstation_logo_is_a_fully_3d_model/).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"resources/images/pslogo-1.png\" width=\"600\"\u003e\n\u003c/p\u003e\n","funding_links":[],"categories":["\u003ca name=\"graphics\"\u003e\u003c/a\u003eGraphics"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadmtrv%2Fobjcurses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadmtrv%2Fobjcurses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadmtrv%2Fobjcurses/lists"}