Make Renderer own the scenes.

PiperOrigin-RevId: 936547976
Change-Id: Iec87426a9ae255cdbd3efadc7b602d4183679c81
This commit is contained in:
Haroon Qureshi
2026-06-23 03:15:05 -07:00
committed by Copybara-Service
parent 2800a682e4
commit 7f66f42568
7 changed files with 45 additions and 44 deletions
@@ -40,28 +40,25 @@ using filament::math::float4;
using filament::math::mat3;
using filament::math::mat4;
SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model)
: ctx_(ctx) {
mjrfSceneParams params;
mjrf_defaultSceneParams(&params);
scene_ = CreateScene(ctx_, params);
SceneBridge::SceneBridge(mjrfContext* ctx, mjrfScene* scene, const mjModel* model)
: ctx_(ctx), scene_(scene) {
model_objects_ = std::make_unique<ModelObjects>(model, ctx_);
scene_objects_ = std::make_unique<SceneObjects>(ctx_);
mjrf_configureSceneFromModel(scene_.get(), model);
mjrf_configureSceneFromModel(scene_, model);
auto clear_color = ReadElement(model, "filament.clearColor",
filament::math::float4(0, 0, 0, 1));
mjrf_setClearColor(ctx_, &clear_color[0]);
light_manager_ =
std::make_unique<LightManager>(ctx_, scene_.get(), model_objects_.get());
std::make_unique<LightManager>(ctx_, scene_, model_objects_.get());
}
SceneBridge::~SceneBridge() {
light_manager_.reset();
for (auto& iter : renderables_) {
mjrf_removeRenderableFromScene(scene_.get(), iter.get());
mjrf_removeRenderableFromScene(scene_, iter.get());
}
renderables_.clear();
}
@@ -115,7 +112,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
// Remove all drawables from previous render and prepare new ones.
for (auto& iter : renderables_) {
mjrf_removeRenderableFromScene(scene_.get(), iter.get());
mjrf_removeRenderableFromScene(scene_, iter.get());
}
renderables_.clear();
for (int i = 0; i < scene->ngeom; ++i) {
@@ -154,7 +151,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
mjrf_setRenderableMaterial(vertex.get(), &material);
mjrf_setRenderableSize(vertex.get(), size);
mjrf_setRenderableTransform(vertex.get(), scene->flexvert + 3*v, rot);
mjrf_addRenderableToScene(scene_.get(), vertex.get());
mjrf_addRenderableToScene(scene_, vertex.get());
renderables_.push_back(std::move(vertex));
}
}
@@ -199,7 +196,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
mjrf_setRenderableMaterial(vertex.get(), &material);
mjrf_setRenderableSize(vertex.get(), size);
mjrf_setRenderableTransform(vertex.get(), pos, rot);
mjrf_addRenderableToScene(scene_.get(), vertex.get());
mjrf_addRenderableToScene(scene_, vertex.get());
renderables_.push_back(std::move(vertex));
}
}
@@ -215,7 +212,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
UniquePtr<mjrfRenderable> renderable = CreateGeomRenderable(
*geom, ctx_, model_objects_.get(), scene_objects_.get());
mjrf_addRenderableToScene(scene_.get(), renderable.get());
mjrf_addRenderableToScene(scene_, renderable.get());
renderables_.push_back(std::move(renderable));
}
@@ -269,8 +266,6 @@ void SceneBridge::SetDrawTextFunction(DrawTextAtFn fn) {
draw_text_callback_ = std::move(fn);
}
mjrfScene* SceneBridge::GetScene() const { return scene_.get(); }
mjrCamera SceneBridge::GetCamera() const { return camera_; }
} // namespace mujoco
@@ -35,7 +35,7 @@ namespace mujoco {
// Manages all mjModel data and updates a SceneView using an mjvScene.
class SceneBridge {
public:
SceneBridge(mjrfContext* ctx, const mjModel* model);
SceneBridge(mjrfContext* ctx, mjrfScene* scene, const mjModel* model);
~SceneBridge();
// Updates the Entities in the filament Scene to match the current mjvScene
@@ -50,8 +50,7 @@ class SceneBridge {
using DrawTextAtFn = std::function<void(const char*, float, float, float)>;
void SetDrawTextFunction(DrawTextAtFn fn);
// Returns the managed scene.
mjrfScene* GetScene() const;
// Returns the camera used for rendering the scene.
mjrCamera GetCamera() const;
SceneBridge(const SceneBridge&) = delete;
@@ -64,12 +63,12 @@ class SceneBridge {
const filament::math::float3& pos) const;
mjrfContext* ctx_ = nullptr;
mjrfScene* scene_ = nullptr;
std::unique_ptr<ModelObjects> model_objects_;
std::unique_ptr<SceneObjects> scene_objects_;
std::unique_ptr<LightManager> light_manager_;
mjrCamera camera_;
DrawTextAtFn draw_text_callback_;
UniquePtr<mjrfScene> scene_{nullptr, nullptr};
std::vector<UniquePtr<mjrfRenderable>> renderables_;
filament::math::mat4 clip_from_world_;
};
+10 -7
View File
@@ -59,7 +59,8 @@ class CompatContext {
private:
mjrDrawMode draw_mode_ = mjDRAW_MODE_DEFAULT;
UniquePtr<mjrfContext> context_;
UniquePtr<mjrfContext> context_{nullptr, nullptr};
UniquePtr<mjrfScene> scene_{nullptr, nullptr};
std::unique_ptr<SceneBridge> scene_bridge_;
mjtFramebuffer framebuffer_ = mjFB_WINDOW;
UniquePtr<mjrfRenderTarget> color_target_{nullptr, nullptr};
@@ -67,9 +68,11 @@ class CompatContext {
};
CompatContext::CompatContext(const mjrfContextConfig* config,
const mjModel* model)
: context_(CreateContext(*config)) {
scene_bridge_ = std::make_unique<SceneBridge>(context_.get(), model);
const mjModel* model) {
context_ = CreateContext(*config);
scene_ = CreateScene(context_.get(), {});
scene_bridge_ =
std::make_unique<SceneBridge>(context_.get(), scene_.get(), model);
}
void CompatContext::Render(const mjrRect& viewport, const mjvScene* scene) {
@@ -92,7 +95,7 @@ void CompatContext::Render(const mjrRect& viewport, const mjvScene* scene) {
if (framebuffer_ == mjFB_WINDOW) {
mjrfRenderRequest req;
mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene();
req.scene = scene_.get();
req.draw_mode = draw_mode_;
req.camera = scene_bridge_->GetCamera();
req.viewport = viewport;
@@ -121,7 +124,7 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb,
mjrfRenderRequest req;
mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene();
req.scene = scene_.get();
req.draw_mode = draw_mode_;
req.camera = scene_bridge_->GetCamera();
req.viewport = viewport;
@@ -149,7 +152,7 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb,
mjrfRenderRequest req;
mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene();
req.scene = scene_.get();
req.draw_mode = mjDRAW_MODE_DEPTH;
req.camera = scene_bridge_->GetCamera();
req.viewport = viewport;
+14 -9
View File
@@ -69,8 +69,8 @@ Renderer::Renderer(void* native_window, GraphicsMode gfx)
}
g_update_gui_callback = [this]() {
if (scene_bridge_) {
mjrf_DEBUG_drawImguiEditor(scene_bridge_->GetScene());
if (main_scene_) {
mjrf_DEBUG_drawImguiEditor(main_scene_.get());
}
};
}
@@ -102,9 +102,12 @@ void Renderer::Init(const mjModel* model) {
? mjGRAPHICS_API_OPENGL
: mjGRAPHICS_API_VULKAN;
filament_context_ = CreateContext(cfg);
scene_bridge_ =
std::make_unique<SceneBridge>(filament_context_.get(), model);
imgui_bridge_ = std::make_unique<ImguiBridge>(filament_context_.get());
main_scene_ = CreateScene(filament_context_.get(), {});
ux_scene_ = CreateScene(filament_context_.get(), {});
scene_bridge_ = std::make_unique<SceneBridge>(filament_context_.get(),
main_scene_.get(), model);
imgui_bridge_ = std::make_unique<ImguiBridge>(filament_context_.get(),
ux_scene_.get());
scene_bridge_->SetDrawTextFunction(DrawTextAt);
}
@@ -122,6 +125,8 @@ void Renderer::Deinit() {
} else {
scene_bridge_.reset();
imgui_bridge_.reset();
ux_scene_.reset();
main_scene_.reset();
filament_context_.reset();
}
initialized_ = false;
@@ -242,7 +247,7 @@ void Renderer::DoRender(int width, int height) {
mjrfRenderRequest reqs[2];
mjrf_defaultRenderRequest(&reqs[0]);
reqs[0].scene = scene_bridge_->GetScene();
reqs[0].scene = main_scene_.get();
reqs[0].draw_mode = draw_mode;
reqs[0].camera = scene_bridge_->GetCamera();
reqs[0].viewport = viewport;
@@ -250,7 +255,7 @@ void Renderer::DoRender(int width, int height) {
reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION];
mjrf_defaultRenderRequest(&reqs[1]);
reqs[1].scene = imgui_bridge_->GetScene();
reqs[1].scene = ux_scene_.get();
reqs[1].draw_mode = mjDRAW_MODE_DEFAULT;
reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height);
reqs[1].viewport = viewport;
@@ -308,7 +313,7 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) {
mjrfRenderRequest reqs[2];
mjrf_defaultRenderRequest(&reqs[0]);
reqs[0].scene = scene_bridge_->GetScene();
reqs[0].scene = main_scene_.get();
reqs[0].draw_mode = draw_mode;
reqs[0].camera = scene_bridge_->GetCamera();
reqs[0].target = target.get();
@@ -317,7 +322,7 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) {
reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION];
mjrf_defaultRenderRequest(&reqs[1]);
reqs[1].scene = imgui_bridge_->GetScene();
reqs[1].scene = ux_scene_.get();
reqs[1].draw_mode = mjDRAW_MODE_DEFAULT;
reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height);
reqs[1].target = target.get();
+2
View File
@@ -112,6 +112,8 @@ class Renderer {
// State used by the filament renderer.
UniquePtr<mjrfContext> filament_context_{nullptr, nullptr};
UniquePtr<mjrfScene> main_scene_{nullptr, nullptr};
UniquePtr<mjrfScene> ux_scene_{nullptr, nullptr};
std::unique_ptr<SceneBridge> scene_bridge_;
std::unique_ptr<ImguiBridge> imgui_bridge_;
+4 -6
View File
@@ -33,10 +33,10 @@ namespace mujoco {
using filament::math::float3;
using filament::math::mat3f;
ImguiBridge::ImguiBridge(mjrfContext* ctx) : ctx_(ctx) {
ImguiBridge::ImguiBridge(mjrfContext* ctx, mjrfScene* scene)
: ctx_(ctx), scene_(scene) {
mjrfSceneParams params;
mjrf_defaultSceneParams(&params);
scene_ = CreateScene(ctx_, params);
}
ImguiBridge::~ImguiBridge() {
@@ -287,16 +287,14 @@ void ImguiBridge::PrepareRenderables(int count) {
params.receive_shadows = false;
params.blend_order = static_cast<std::uint16_t>(renderables_.size() + 1);
auto& renderable = renderables_.emplace_back(CreateRenderable(ctx_, params));
mjrf_addRenderableToScene(scene_.get(), renderable.get());
mjrf_addRenderableToScene(scene_, renderable.get());
}
while (renderables_.size() > count) {
mjrf_removeRenderableFromScene(scene_.get(), renderables_.back().get());
mjrf_removeRenderableFromScene(scene_, renderables_.back().get());
renderables_.pop_back();
}
}
mjrfScene* ImguiBridge::GetScene() const { return scene_.get(); }
mjrCamera ImguiBridge::GetCamera(int width, int height) const {
mjrCamera camera;
camera.orthographic = true;
+3 -4
View File
@@ -28,7 +28,7 @@ namespace mujoco {
// Creates and manages a SceneView using data read from ImGui.
class ImguiBridge {
public:
explicit ImguiBridge(mjrfContext* ctx);
explicit ImguiBridge(mjrfContext* ctx, mjrfScene* scene);
~ImguiBridge();
// Prepares the Renderables using data from the current ImGui state. This
@@ -36,8 +36,7 @@ class ImguiBridge {
// synced.
void Update();
// Returns the managed UX scene.
mjrfScene* GetScene() const;
// Returns the camera used for rendering the UX scene.
mjrCamera GetCamera(int width, int height) const;
// Uploads texture to be used with ImGui's Image and ImageButton functions.
@@ -58,7 +57,7 @@ class ImguiBridge {
mjrfTexture* GetTexture(uintptr_t tex_id) const;
mjrfContext* ctx_ = nullptr;
UniquePtr<mjrfScene> scene_{nullptr, nullptr};
mjrfScene* scene_ = nullptr;
std::vector<UniquePtr<mjrfRenderable>> renderables_;
std::vector<UniquePtr<mjrfMesh>> meshes_;
std::unordered_map<uintptr_t, UniquePtr<mjrfTexture>> textures_;