2 releases
Uses new Rust 2024
| 0.0.2 | Oct 17, 2025 |
|---|---|
| 0.0.1 | Oct 16, 2025 |
#283 in Games
43KB
308 lines
Rael OBJ
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:
- Import your model into Blender.
- Select the object you want to triangulate.
- Switch to Edit Mode (press
Tab). - Select all faces (press
A). - Go to
Face > Triangulate Faces(or use the shortcutCtrl+T). - Export the model as an
.objfile.
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