#terminal #renderer #tui #graphics #tui-console

rael_obj

a simple function to load obj file with lightning and transform, to draw it using rael

2 releases

Uses new Rust 2024

0.0.2 Oct 17, 2025
0.0.1 Oct 16, 2025

#283 in Games

MIT license

43KB
308 lines

Rael OBJ

Crates.io Docs.rs

A simple OBJ file loader and renderer for the terminal, designed to be used with the rael canvas.

Description

This library provides the core functionality to load a Wavefront .obj model and render it to a list of pixels. These pixels can then be drawn onto a rael::Canvas for display in the terminal.

It supports basic 3D transformations (position, rotation, scale), lighting (ambient and point lights), and texture mapping.

Installation

Add rael_obj to your project's Cargo.toml:

cargo add rael_obj

Important: Model Requirements

Your 3D models MUST be triangulated.

This renderer is designed to work with triangular faces only. Models that contain quadrilaterals ("quads") or other polygons with more than three vertices (n-gons) will likely not load or render correctly.

How to Triangulate a Model

You can easily triangulate a model using 3D modeling software like Blender:

  1. Import your model into Blender.
  2. Select the object you want to triangulate.
  3. Switch to Edit Mode (press Tab).
  4. Select all faces (press A).
  5. Go to Face > Triangulate Faces (or use the shortcut Ctrl+T).
  6. Export the model as an .obj file.

Example Usage

Here is a simple example of how to load a model and render it to the console.

use rael_obj::*;
use std::io::{BufReader, stdout, Write};
use std::fs::File;
use crossterm::{execute, style::Print};

fn main() -> std::io::Result<()> {
    // 1. Load the model and texture
    let input = BufReader::new(File::open("source/blahaj_tri.obj").expect("Failed to open OBJ"));
    let model: Obj<TexturedVertex> = load_obj(input).expect("Failed to load OBJ");
    let texture = Texture::from_file("source/texture.001.png");

    // 2. Set up the scene
    let lights = vec![
        Light {
            kind: LightKind::Ambient { intensity: 0.8 },
            color: Color { r: 255, g: 255, b: 255 },
        },
        Light {
            kind: LightKind::Point {
                position: (5.0, 8.0, -1.0),
                intensity: 3.0,
            },
            color: Color { r: 255, g: 180, b: 180 },
        },
    ];

    // 3. Define model transformations
    let rotation = [0, 180, 0];
    let position = [0.0, 0.0, 1.5];
    let scale = 0.2;
    let center = [0.0, 0.0, 0.0];
    let fov = -4.0;

    // 4. Create a canvas to draw on
    let (width, height) = (80, 40);
    let mut canvas = Canvas::new(width, height, Color { r: 0, g: 0, b: 0 });

    // 5. Call draw_obj to get the rendered pixels
    let pixels = draw_obj(
        &model,
        center,
        scale,
        rotation,
        position,
        &canvas,
        fov,
        &lights,
        &texture,
    );

    // 6. Draw the pixels to the canvas
    for (x, y, color) in pixels {
        canvas.set_pixel(x as usize, y as usize, 1, color);
    }

    // 7. Print the canvas to the terminal
    let output = canvas.render();
    execute!(stdout(), Print(output))?;
    stdout().flush()
}

License

This project is not yet licensed.

Dependencies

~11–17MB
~344K SLoC