enigma is my first attempt to do a little graphics API for Rust. Please be aware that I'm not a professional graphics programmer, so the code is most likely butchering some conventions. I also don't take care of performance at the moment. That said, I have the following features working:
- Model loading from GLTF and OBJ
- Opaque and Transparent rendering
Material,Shader,Shape,ObjectAbstractions- PBR Shading
- Texturing, Normals and Vertex Colors
- up to 4 point lights per object
- one ambient light
- a
Camera - a simple Event system to inject functions and Keyboard presses and KeyCode modifiers into the
EventLoop. Atm events get processed one by one in sequence - a simple Update system to inject functions into the update loop. Atm, the functions get processes one by one in sequence
- Screen to World positions, including a selection system
- Postprocessing
- Skybox and Sky reflections
- egui integration for a simple UI
- loading resources from the
include_bytes!andinclude_str!macro to include them in the built application - adding and carrying an arbitrary amount of data within the
AppState - serialize currently loaded
AppStateto json and inject serializedAppStateinto running one.
A first little game, developed with enigma, can be found here: https://github.com/JeremiasMeister/enigma-flappy-bird
For support on how to use the Engine, you can use this GPT-4 if you are subscribed to ChatGPT+: https://chat.openai.com/g/g-omfu2zhKf-enigma-3d-expert
The API is quite straightforward and easy to use; see the example below.
PBR Bloom postprocess and transparent objects
Also added an outline postprocess as an example how to handle the depth buffer in postprocessing
Some more postprocessing in form of a black and white shader and a red outline instead of a black one
// create an enigma eventloop and appstate
let event_loop = new;
let mut app_state = new;
// set the icon from the resources
event_loop.set_icon_from_resource;
// some default event setups like e.g. selection
init_default;
// create a material and assign the UV checker texture from resources
let mut material = lit_pbr;
material.set_texture_from_resource;
// create an object, and load the Suzanne model from resources
let mut object = load_from_gltf_resource;
// set the material to the suzan object to the first shape (submesh) slot
object.add_material;
object.get_shapes_mut.set_material_from_object_list;
// set the name and position of the object
object.name = "Suzanne".to_string;
object.transform.set_position;
// adding the object to the app state
app_state.add_object;
// create a bunch of lights
let light1 = new;
let light2 = new;
let light3 = new;
let ambient_light = new;
// add the lights to the app state
app_state.add_light;
app_state.add_light;
app_state.add_light;
app_state.add_light; // only one ambient light is supported atm
// create and add a camera to the app state
let camera = new;
app_state.set_camera;
// add events
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
app_state.inject_event;
// add update functions
app_state.inject_update_function;
app_state.inject_update_function;
// add post processing effects
app_state.add_post_process;
app_state.add_post_process;
//add one ui function to the app state. multiple ui functions can be added modularly
app_state.inject_gui;
// add some arbitrary state data. This can be used to store any kind of data in the app state
// game globals, or other data that needs to be shared between different parts of the application
app_state.add_state_data;
app_state.add_state_data;
app_state.add_state_data;
// run the event loop
event_loop.run;