Project Setup

The directory structure for the project will look like this:


File Structure

  • assets/
    • hdr/ Contains HDR maps used for skyboxes and environment mapping
    • models/ Contains 3D assets, such as *.gltf and *.glb files
    • shaders/ Contains all of the shaders used in the project
  • crates/
    • obsidian_app/ A library that handles the window and application input boilerplate
  • viewer/ An application that can render 3D models, developed over the course of this book

Creating the File Structure

Create the project as a library:

cargo new --lib obsidian
cd obsidian

Create the asset folders:

mkdir assets
mkdir assets/hdr
mkdir assets/icon
mkdir assets/models
mkdir assets/shaders

Edit Cargo.toml to make the project a cargo workspace:

# Leave the [package] section as is

members = ["crates/*", "viewer"]
default-members = ["viewer"]

obsidian_app = { path = "crates/obsidian_app" }

Create the application crate as a library:

cargo new --lib crates/obsidian_app

Create and edit crates/obsidian_app/src/ to add an Application struct. This will eventually contain everything needed for an Obsidian application, including a physics world, an entity component system, the renderer itself, and more.

pub struct Application;

Update crates/obsidian_app/src/

mod app;
pub use self::app::*;

Edit src/ to reference the app library:

pub mod app {
    pub use obsidian_app::*;

Create the viewer application:

cargo new viewer

Update the viewer/cargo.toml to reference all of obsidian as a single library.

obsidian = { path = ".." }

Now, run cargo run --release to compile and statically link the program. You should see:

"Hello, world!"