3 unstable releases
Uses new Rust 2024
0.2.1 | Jun 12, 2025 |
---|---|
0.2.0 | Jun 10, 2025 |
0.1.0 | Nov 30, 2018 |
#264 in Game dev
54 downloads per month
365KB
6K
SLoC
🍁 Maple 🍁
A simple 3D Game Engine in Rust!
Features
3D Model Support: load and manipulate 3D GLTF models
Customizable: create your own Nodes and use predefined nodes for more specific functionality
Write Your Own Shaders: write your own shaders with GLSL
Easily Add UI's: using egui you can easily set up a UI
Example Images
This work is based on "Japanese Restaurant Inakaya" by MGuegan, licensed under CC BY 4.0.
Guide to using the Engine
this guide goes over the basics of initializing the engine, adding nodes, and defining custom nodes.
you can find the code used in this tutorial here.
Initialization
lets start out by creating the bare minimum code to create and start the engine.
use maple::{Engine, config::{EngineConfig, Resolution}};
use std::{default::Default, error::Error};
fn main() -> Result<(), Box<dyn Error>> {
let mut engine = Engine::init(EngineConfig {
window_title: "Hello, Window!".to_string(),
resolution: Resolution {
width: 1920,
height: 1080,
},
..Default::default()
})?;
engine.begin()
}
if you run this code it creates a window at 1920x1080 resolution, but its a bit empty so next we'll create a scene.
Scene Creation
in this section we'll create the engine's scene. scenes can be defined then added to the engine to render that scene.
to keep it as organized, we should define the scene in a seperate file then import it into main.
use maple::context::scene::Scene;
pub struct MainScene;
impl MainScene {
pub fn build() -> Scene {
let mut scene = Scene::default();
/* Scene will go here */
scene
}
}
this code creates a function that will build the scene when called
before we add Nodes to the scene lets load this scene into the engine
use maple::{Engine, config::{EngineConfig, Resolution}};
use std::{default::Default, error::Error};
// create and import the main scene module
pub mod main_scene;
use main_scene::MainScene;
fn main() -> Result<(), Box<dyn Error>> {
let mut engine = Engine::init(EngineConfig {
window_title: "Hello, Window!".to_string(),
resolution: Resolution {
width: 1920,
height: 1080,
},
..Default::default()
})?;
// load the scene into the engine
engine.load_scene(MainScene::build());
engine.begin()
}
Node Creation
now we can finally add nodes to the Scene!
Nodes are easiest to build with the NodeBuilder which is a struct that helps define nodes. we'll use this to create a model and camera.
Model
lets create a pyramid model.
use maple::context::scene::Scene;
use maple::nodes::{model::Primitive, Model, ModelBuilder, Builder, Buildable};
scene
.add(
"pyramid", // name
Model::builder()
.add_primitive(Primitive::Pyramid) // add a Pyramid mesh to the model node
.build(), // builds the node
);
Camera3D
thats great but the engine doesnt know where to render the pyramid from for that we need a camera. cameras define the perspective so we'll need to position it properly.
use maple::{
math,
nodes::{Buildable, Builder, Camera3D},
};
scene.add(
"camera",
Camera3D::builder()
.position(math::vec3(0.0, 5.0, -10.0))
.orientation_vector(math::vec3(0.0, -0.5, 1.0))
.build(),
);
nning local AI models both on a Your scene file should now look like this:
use maple::{
context::scene::Scene,
math,
nodes::{Buildable, Builder, Camera3D, Model, model::Primitive},
};
pub struct MainScene;
impl MainScene {
pub fn build() -> Scene {
let mut scene = Scene::default();
scene.add(
"camera",
Camera3D::builder()
.position(math::vec3(0.0, 5.0, -10.0))
.orientation_vector(math::vec3(0.0, -0.5, 1.0))
.build(),
);
scene.add(
"pyramid",
Model::builder().add_primitive(Primitive::Pyramid).build(),
);
scene
}
}
Lighting
If everything has gone well then when you run the program you can see a window pop up and a pyramid in the center of the screen. However, the mesh is really dark since its just being lit by ambient light so now adding a light and some ground to the scene should help.
use maple::{
context::scene::Scene,
math,
nodes::{Buildable, Builder, DirectionalLight, Model, model::Primitive},
};
scene.add(
"light",
DirectionalLight::builder()
.direction(math::vec3(-1.0, 1.0, 0.0))
.build(),
);
scene.add(
"ground",
Model::builder()
.add_primitive(Primitive::Plane)
.position(math::vec3(0.0, -2.0, 0.0))
.scale_factor(10.0)
.build(),
);
Contributing
Contributions are welcome! If you have suggestions for improvements, feel free to create a pull request or open an issue.
License
This project is licensed under the MIT License
Acknowledgments
Dependencies
~12–25MB
~403K SLoC