diff --git a/src/experimental/filament/compat/scene_bridge.cc b/src/experimental/filament/compat/scene_bridge.cc index fdc69936..ac3a9d37 100644 --- a/src/experimental/filament/compat/scene_bridge.cc +++ b/src/experimental/filament/compat/scene_bridge.cc @@ -88,6 +88,10 @@ SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model) mjrf_configureSceneFromModel(scene_.get(), model); + auto clear_color = ReadElement(model, "filament.clearColor", + filament::math::float4(0, 0, 0, 1)); + mjrf_setClearColor(ctx_, &clear_color[0]); + default_shadow_map_size_ = ReadElement( model, "filament.shadows.map_size", default_shadow_map_size_); default_vsm_blur_width_ = ReadElement( diff --git a/src/experimental/filament/filament/filament_context.cc b/src/experimental/filament/filament/filament_context.cc index d7f81cb4..fdee15c2 100644 --- a/src/experimental/filament/filament/filament_context.cc +++ b/src/experimental/filament/filament/filament_context.cc @@ -36,16 +36,12 @@ #include #include "experimental/filament/filament/filament_platform_factory.h" #include "experimental/filament/filament/object_manager.h" +#include "experimental/filament/filament/render_target.h" +#include "experimental/filament/filament/scene_view.h" #include "experimental/filament/render_context_filament.h" namespace mujoco { -// Forward declarations of functions defined in scene_view.cc to prevent -// circular dependencies. -void DoRender(filament::Renderer* renderer, const mjrRenderRequest& request); -void DoReadPixels(filament::Renderer* renderer, const mjrRenderRequest& request, - const mjrReadPixelsRequest& read_request); - FilamentContext::FilamentContext(const mjrFilamentConfig* config) : config_(*config) { FilamentPlatformSetup setup = CreateFilamentPlatform(config_); @@ -127,7 +123,8 @@ mjrFrameHandle FilamentContext::Render( break; } if (render_began) { - DoRender(renderer_, request); + SceneView* scene_view = SceneView::downcast(request.scene); + scene_view->Render(renderer_, request); } } else { if (read_requests.empty()) { @@ -147,8 +144,11 @@ mjrFrameHandle FilamentContext::Render( break; } if (render_began) { - DoRender(renderer_, request); - DoReadPixels(renderer_, request, read_request); + SceneView* scene_view = SceneView::downcast(request.scene); + scene_view->Render(renderer_, request); + RenderTarget* render_target = RenderTarget::downcast(request.target); + render_target->ReadColorPixels(renderer_, (uint8_t*)read_request.output, + read_request.num_bytes); } } } diff --git a/src/experimental/filament/filament/light.cc b/src/experimental/filament/filament/light.cc index 396aee42..9132c6fa 100644 --- a/src/experimental/filament/filament/light.cc +++ b/src/experimental/filament/filament/light.cc @@ -26,7 +26,6 @@ #include #include #include "experimental/filament/filament_util.h" -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/render_context_filament.h" @@ -35,8 +34,8 @@ namespace mujoco { using filament::math::float3; using filament::math::mat3f; -Light::Light(FilamentContext* ctx, const mjrLightParams& params) - : engine_(ctx->GetEngine()), params_(params) { +Light::Light(filament::Engine* engine, const mjrLightParams& params) + : engine_(engine), params_(params) { // Filament treats image-based lights (IBLs) as separate objects (i.e. // filament::IndirectLight) and so we need to handle IBLs specially. if (params.type == mjLIGHT_IMAGE) { diff --git a/src/experimental/filament/filament/light.h b/src/experimental/filament/filament/light.h index 106dcba8..73b092d2 100644 --- a/src/experimental/filament/filament/light.h +++ b/src/experimental/filament/filament/light.h @@ -20,7 +20,6 @@ #include #include #include -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/render_context_filament.h" namespace mujoco { @@ -29,7 +28,7 @@ namespace mujoco { // IndirectLight. class Light : public mjrLight { public: - Light(FilamentContext* ctx, const mjrLightParams& params); + Light(filament::Engine* engine, const mjrLightParams& params); ~Light() noexcept; Light(const Light&) = delete; diff --git a/src/experimental/filament/filament/renderable.cc b/src/experimental/filament/filament/renderable.cc index ddd45503..232cdfb9 100644 --- a/src/experimental/filament/filament/renderable.cc +++ b/src/experimental/filament/filament/renderable.cc @@ -31,7 +31,6 @@ #include #include "experimental/filament/filament_util.h" #include "experimental/filament/filament/builtins.h" -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/object_manager.h" @@ -49,8 +48,10 @@ using filament::math::mat4f; static constexpr float kArrowScale = 1.f / 6.f; static constexpr float kArrowHeadSize = 1.75f; -Renderable::Renderable(FilamentContext* ctx, const mjrRenderableParams& params) - : object_mgr_(ctx->GetObjectManager()), params_(params) { +Renderable::Renderable(filament::Engine* engine, + const mjrRenderableParams& params, + ObjectManager* object_mgr) + : object_mgr_(object_mgr), params_(params) { mjr_defaultMaterial(&material_); } diff --git a/src/experimental/filament/filament/renderable.h b/src/experimental/filament/filament/renderable.h index 3d7707da..39a267d5 100644 --- a/src/experimental/filament/filament/renderable.h +++ b/src/experimental/filament/filament/renderable.h @@ -25,7 +25,6 @@ #include #include #include "experimental/filament/filament_util.h" -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/object_manager.h" #include "experimental/filament/render_context_filament.h" @@ -39,7 +38,8 @@ namespace mujoco { // on the surface). class Renderable : public mjrRenderable { public: - Renderable(FilamentContext* ctx, const mjrRenderableParams& params); + Renderable(filament::Engine* engine, const mjrRenderableParams& params, + ObjectManager* object_mgr); ~Renderable() noexcept; Renderable(const Renderable&) = delete; diff --git a/src/experimental/filament/filament/scene_view.cc b/src/experimental/filament/filament/scene_view.cc index d7ff12e6..c761a099 100644 --- a/src/experimental/filament/filament/scene_view.cc +++ b/src/experimental/filament/filament/scene_view.cc @@ -42,7 +42,6 @@ #include #include "experimental/filament/filament_util.h" #include "experimental/filament/filament/color_grading_options.h" -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" #include "experimental/filament/filament/render_target.h" #include "experimental/filament/filament/renderable.h" @@ -122,9 +121,8 @@ static void SetupReflectionCamera(const mat4& surface_xform, reflection_camera->setCustomProjection(oblique, near, far); } -SceneView::SceneView(FilamentContext* ctx, const mjrSceneParams& params) - : ctx_(ctx) { - filament::Engine* engine = ctx_->GetEngine(); +SceneView::SceneView(filament::Engine* engine, const mjrSceneParams& params) + : engine_(engine) { scene_ = engine->createScene(); camera_ = engine->createCamera(utils::EntityManager::get().create()); reflect_camera_ = engine->createCamera(utils::EntityManager::get().create()); @@ -168,10 +166,9 @@ SceneView::SceneView(FilamentContext* ctx, const mjrSceneParams& params) } SceneView::~SceneView() { - filament::Engine* engine = ctx_->GetEngine(); if (skybox_) { scene_->setSkybox(nullptr); - engine->destroy(skybox_); + engine_->destroy(skybox_); } for (auto& light : lights_) { light->RemoveFromScene(scene_); @@ -182,15 +179,15 @@ SceneView::~SceneView() { lights_.clear(); renderables_.clear(); reflect_targets_.clear(); - engine->destroyCameraComponent(reflect_camera_->getEntity()); - engine->destroy(reflect_view_); - engine->destroyCameraComponent(camera_->getEntity()); + engine_->destroyCameraComponent(reflect_camera_->getEntity()); + engine_->destroy(reflect_view_); + engine_->destroyCameraComponent(camera_->getEntity()); if (color_grading_) { - engine->destroy(color_grading_); + engine_->destroy(color_grading_); } - engine->destroy(scene_); + engine_->destroy(scene_); for (auto& view : views_) { - engine->destroy(view); + engine_->destroy(view); } } @@ -239,8 +236,11 @@ void SceneView::SetSkybox(const Texture* skybox_texture) { } } -void SceneView::Render(filament::Renderer* renderer, - const RenderRequest& request) { +void SceneView::Render(filament::Renderer* renderer, const mjrRenderRequest& request) { + if (request.scene != this) { + mju_error("Invalid scene for SceneView::Render."); + } + filament::Viewport viewport(request.viewport.left, request.viewport.bottom, request.viewport.width, request.viewport.height); for (auto& view : views_) { @@ -258,8 +258,8 @@ void SceneView::Render(filament::Renderer* renderer, filament::MultiSampleAntiAliasingOptions options = view->getMultiSampleAntiAliasingOptions(); - filament::RenderTarget* render_target = - request.target ? request.target->GetFilamentRenderTarget() : nullptr; + + RenderTarget* render_target = RenderTarget::downcast(request.target); if (render_target) { // We need to disable msaa in order to render to texture. view->setMultiSampleAntiAliasingOptions({.enabled = false}); @@ -287,7 +287,8 @@ void SceneView::Render(filament::Renderer* renderer, } } - view->setRenderTarget(render_target); + view->setRenderTarget(render_target ? render_target->GetFilamentRenderTarget() + : nullptr); renderer->render(view); view->setRenderTarget(nullptr); @@ -308,8 +309,7 @@ void SceneView::AddReflectiveRenderable(Renderable* renderable) { config.color_format = mjPIXEL_FORMAT_RGBA8; config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - reflect_targets_.push_back( - std::make_unique(ctx_->GetEngine(), config)); + reflect_targets_.push_back(std::make_unique(engine_, config)); } // Prepare a render target for the reflective renderable. @@ -382,9 +382,6 @@ ColorGradingOptions SceneView::GetColorGradingOptions() const { } void SceneView::Configure(const mjModel* model) { - ctx_->SetClearColor(ReadElement(model, "filament.clearColor", - filament::math::float4(0, 0, 0, 1))); - filament::View* view = views_[mjDRAW_MODE_COLOR]; auto cg = color_grading_options_; @@ -483,30 +480,4 @@ void SceneView::Configure(const mjModel* model) { bloom.levels = ReadElement(model, "filament.bloom.levels", bloom.levels); view->setBloomOptions(bloom); } - -void DoRender(filament::Renderer* renderer, const mjrRenderRequest& request) { - SceneView::RenderRequest scene_view_request; - scene_view_request.draw_mode = request.draw_mode; - scene_view_request.viewport = request.viewport; - scene_view_request.camera = request.camera; - SceneView* scene_view = SceneView::downcast(request.scene); - scene_view->Render(renderer, scene_view_request); -} - -void DoReadPixels(filament::Renderer* renderer, - const mjrRenderRequest& request, - const mjrReadPixelsRequest& read_request) { - RenderTarget* render_target = RenderTarget::downcast(request.target); - - SceneView::RenderRequest scene_view_request; - scene_view_request.draw_mode = request.draw_mode; - scene_view_request.viewport = request.viewport; - scene_view_request.camera = request.camera; - scene_view_request.target = render_target; - SceneView* scene_view = SceneView::downcast(request.scene); - scene_view->Render(renderer, scene_view_request); - render_target->ReadColorPixels(renderer, (uint8_t*)read_request.output, - read_request.num_bytes); -} - } // namespace mujoco diff --git a/src/experimental/filament/filament/scene_view.h b/src/experimental/filament/filament/scene_view.h index 1522fe3c..f17b4022 100644 --- a/src/experimental/filament/filament/scene_view.h +++ b/src/experimental/filament/filament/scene_view.h @@ -27,7 +27,6 @@ #include #include #include "experimental/filament/filament/color_grading_options.h" -#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" #include "experimental/filament/filament/renderable.h" #include "experimental/filament/filament/render_target.h" @@ -43,7 +42,7 @@ namespace mujoco { // (e.g. normal, depth, segmentation, etc.) as well as reflective surfaces. class SceneView : public mjrScene { public: - SceneView(FilamentContext* ctx, const mjrSceneParams& params); + SceneView(filament::Engine* engine, const mjrSceneParams& params); ~SceneView(); SceneView(const SceneView&) = delete; @@ -56,23 +55,10 @@ class SceneView : public mjrScene { void RemoveFromScene(Renderable* renderable); void SetSkybox(const Texture* skybox_texture); - // Parameters for rendering the scene. - struct RenderRequest { - // The draw mode (e.g. normal, depth, segmentation) to render. - mjrDrawMode draw_mode = mjDRAW_MODE_COLOR; - // The target viewport for the rendered image. - mjrRect viewport; - // The camera from which to render the scene. - mjrCamera camera; - // An optional render target into which the scene will be rendered. - RenderTarget* target = nullptr; - }; - - // Renders the scene. - void Render(filament::Renderer* renderer, const RenderRequest& request); + void Render(filament::Renderer* renderer, const mjrRenderRequest& request); // Returns the filament Engine managing the scene. - filament::Engine* GetEngine() const { return ctx_->GetEngine(); } + filament::Engine* GetEngine() const { return engine_; } // Enables/disables shadows for the default render view. void EnableShadows(); @@ -110,7 +96,7 @@ class SceneView : public mjrScene { // rendered in their own passes to create the reflective texture. void AddReflectiveRenderable(Renderable* renderable); - FilamentContext* ctx_ = nullptr; + filament::Engine* engine_ = nullptr; filament::Scene* scene_ = nullptr; filament::Camera* camera_ = nullptr; filament::ColorGrading* color_grading_ = nullptr; diff --git a/src/experimental/filament/render_context_filament.cc b/src/experimental/filament/render_context_filament.cc index 220f87cc..5cc8ddf5 100644 --- a/src/experimental/filament/render_context_filament.cc +++ b/src/experimental/filament/render_context_filament.cc @@ -162,7 +162,8 @@ mjrMesh* mjrf_createMesh(mjrfContext* ctx, const mjrMeshData* data) { void mjrf_destroyMesh(mjrMesh* mesh) { delete mujoco::Mesh::downcast(mesh); } mjrScene* mjrf_createScene(mjrfContext* ctx, const mjrSceneParams* params) { - return new mujoco::SceneView(mujoco::FilamentContext::downcast(ctx), *params); + return new mujoco::SceneView( + mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params); } void mjrf_destroyScene(mjrScene* scene) { @@ -170,7 +171,8 @@ void mjrf_destroyScene(mjrScene* scene) { } mjrLight* mjrf_createLight(mjrfContext* ctx, const mjrLightParams* params) { - return new mujoco::Light(mujoco::FilamentContext::downcast(ctx), *params); + return new mujoco::Light(mujoco::FilamentContext::downcast(ctx)->GetEngine(), + *params); } void mjrf_destroyLight(mjrLight* light) { @@ -179,8 +181,9 @@ void mjrf_destroyLight(mjrLight* light) { mjrRenderable* mjrf_createRenderable(mjrfContext* ctx, const mjrRenderableParams* params) { - return new mujoco::Renderable(mujoco::FilamentContext::downcast(ctx), - *params); + return new mujoco::Renderable( + mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params, + mujoco::FilamentContext::downcast(ctx)->GetObjectManager()); } void mjrf_destroyRenderable(mjrRenderable* renderable) { @@ -346,6 +349,11 @@ void mjrf_waitForFrame(mjrfContext* ctx, mjrFrameHandle frame) { mujoco::FilamentContext::downcast(ctx)->WaitForFrame(frame); } +void mjrf_setClearColor(mjrfContext* ctx, const float color[3]) { + mujoco::FilamentContext::downcast(ctx)->SetClearColor( + {color[0], color[1], color[2], 1.0f}); +} + void mjrf_getFrameStats(mjrfContext* ctx, mjrFrameHandle frame, mjrFrameStats* stats_out) { mujoco::FilamentContext::downcast(ctx)->GetFrameStats(frame, stats_out); diff --git a/src/experimental/filament/render_context_filament.h b/src/experimental/filament/render_context_filament.h index 0d7d0cbd..f864a325 100644 --- a/src/experimental/filament/render_context_filament.h +++ b/src/experimental/filament/render_context_filament.h @@ -211,6 +211,9 @@ mjrFrameHandle mjrf_render(mjrfContext* ctx, const mjrRenderRequest* req, // triggering any callbacks as needed. void mjrf_waitForFrame(mjrfContext* ctx, mjrFrameHandle frame); +// Sets the clear color for the renderer. +void mjrf_setClearColor(mjrfContext* ctx, const float color[3]); + // Information about a single frame of rendering. struct mjrFrameStats { // The frame rate of the renderer, in frames per second.