← Back

ofxEnTT

github.com/danoli3/ofxEnTT · @danoli3
OF 0.12 Game Engine Rendering

ECS EnTT for openFrameworks - Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more

0 0 Last commit 8h ago Created 9h ago

README

ofxEnTT



ofxEnTT

ofxEnTT

example_instancing: 51,146 spinning cubes drawn in one instanced draw call example_instancing: 51,146 entities, one instanced draw call, with the ofxGui inspector.

EnTT for openFrameworks: a fast entity component system, with a world that runs its systems every frame, a transform hierarchy, instanced rendering, JSON save / load, and bridges to ofParameter, ofxGui, ofxImGui and ofxAssimpModelLoader.

EnTT 4.0.0 (header-only, MIT, by Michele Caini) is included in libs/entt.

Requirements



Studio, VS Code), or CMake C++20 or later; addon_config.mk raises MSYS2 and Raspberry Pi armv6 / armv7 to C++20. Visual Studio 2019 (C++17) isn't supported. GLES 3 / WebGL 2. Without it, entities are drawn one by one.

Quick start



#include "ofxEnTT.h"
using namespace ofxEnTT;

World world;
auto cube = std::make_shared<ofVboMesh>(ofMesh::box(10, 10, 10));

// setup
for (int i = 0; i < 10000; i++) {
	auto e = world.create("cube");
	world.registry.get<Transform>(e).position = glm::sphericalRand(500.f);
	world.registry.emplace<Velocity>(e, glm::vec3(0), glm::vec3(0, 1, 0)); // spins
	world.registry.emplace<MeshRenderer>(e, cube).color = ofFloatColor::orange;
}

// update
world.update();

// draw
cam.begin();
world.draw();   // 10000 cubes, one instanced draw call
cam.end();


world.registry is a plain entt::registry, so the whole EnTT API is there: views, groups, sorting, signals, snapshots, and your own components. Add your own systems with world.addSystem("name", [](World & w, float dt) { ... }).

Components



Component
Namedisplay name (inspectors, JSON, findByName)
Transformlocal position, orientation (quaternion; Euler helpers in degrees), scale
WorldTransformworld matrix, written by the TransformSystem each update
Parent / Childrenhierarchy; use World::setParent (refuses cycles)
MeshRenderershared ofVboMesh, optional ofTexture / ofMaterial, colour, draw mode
Hiddentag: not drawn
Velocitylinear (units/s) and angular (rad/s) motion
Lifetimedestroyed when it reaches zero

World



before the TransformSystem

Rendering



The RenderSystem groups visible MeshRenderers by mesh, texture and draw mode. Each group is one drawInstanced call: per-instance matrices and colours go into vertex attributes 5-9 of the mesh's VBO, and a built-in shader draws them with simple directional lighting (renderer.lighting, renderer.lightDirection). Entities with an ofMaterial are drawn one at a time (ofMaterial has its own shader). renderer.instancing = false draws everything one at a time. renderer.getStats() gives draw calls and entity counts.

Textures are sampled as sampler2D: call ofDisableArbTex() before loading them.

JSON



ofxEnTT::saveJson(world, "scene.json");
ofxEnTT::loadJson(world, "scene.json");   // Name, Transform, Parent, Velocity, Lifetime, Hidden, colour


Meshes, textures and materials aren't saved: give them back to the loaded entities, e.g. by name.

Bridges



The ofParameter bridge is part of the addon. The others are header-only: include them, and add their addon to the project, only where you use them.

ofParameter



ofxEnTT::EntityParameters turns one entity's components into an ofParameterGroup. Changing a parameter writes the component, and pull() (each frame) follows systems that move the entity. The group only lists the components the entity has, and groupChanged fires when that changes.

ofxGui (ofxEnTTGui.h, ofxGui)



ofxEnTT::GuiInspector inspector;
inspector.setup(world);     // setup
inspector.update();         // update, after world.update()
inspector.draw();           // draw, outside the camera
inspector.select(entity);


ofxImGui (ofxEnTTImGui.h, ofxImGui develop branch)



ofxEnTT::Entity selected = ofxEnTT::Null;
gui.begin();
ofxEnTT::imgui::inspector(world, selected);   // tree, create / clone / destroy, component editors
gui.end();


ofxEnTT::imgui::entityTree and entityEditor are there for your own windows.

ofxAssimpModelLoader (ofxEnTTAssimp.h, ofxAssimpModelLoader)



auto model = std::make_shared<ofxAssimpModelLoader>();
model->load("druid.gltf");
auto druid = ofxEnTT::addModel(world, model, "druid");   // root + a child per mesh
auto another = world.clone(druid);                      // shares the meshes: instanced
ofxEnTT::updateModelAnimations(world);                  // in update, for animated models


ModelOptions: materials (keep ofMaterials instead of using the diffuse colour), textures, and yUp (on by default: removes the loader's 180 degree turn for OF's y-down screen, so models stand upright under ofEasyCam).

Examples



ExampleAddons
example_instancingofxGui20,000 spinning cubes in one draw call; space bursts particles with a Lifetime
example_hierarchyofxGuia solar system of parent / child transforms; s / l save and load JSON
example_assimpofxAssimpModelLoader, ofxGuia model as entities, cloned into an instanced grid; drop a model file to swap it
example_imguiofxImGui (develop)the ImGui inspector on a spinning ring of groups
example_testsofxUnitTeststhe addon's unit tests (headless, 63 checks)
Generate the project files with projectGenerator, or copy scripts/templates/<platform>/Makefile and config.make (or the CMake template) into the example folder.

License



ofxEnTT: MIT, Dan Rosser. EnTT: MIT, Michele Caini (libs/entt/license/LICENSE).

Get this addon

HTTPS
SSH