10 #include <utils/Entity.h>
22 #pragma warning(disable : 4068 4146 4293 4305)
25 #include <backend/PixelBufferDescriptor.h>
26 #include <filament/Engine.h>
27 #include <filament/LightManager.h>
28 #include <filament/RenderableManager.h>
29 #include <filament/Renderer.h>
30 #include <filament/Scene.h>
31 #include <filament/SwapChain.h>
48 namespace visualization {
52 void* native_drawable,
54 : engine_(engine), resource_mgr_(resource_mgr) {
55 swap_chain_ = engine_.createSwapChain(native_drawable,
56 filament::SwapChain::CONFIG_READABLE);
57 renderer_ = engine_.createRenderer();
59 materials_modifier_ = std::make_unique<FilamentMaterialModifier>();
66 : engine_(engine), resource_mgr_(resource_mgr) {
67 swap_chain_ = engine_.createSwapChain(
width,
height,
68 filament::SwapChain::CONFIG_READABLE);
69 renderer_ = engine_.createRenderer();
71 materials_modifier_ = std::make_unique<FilamentMaterialModifier>();
77 engine_.destroy(renderer_);
78 engine_.destroy(swap_chain_);
84 std::make_unique<FilamentScene>(engine_, resource_mgr_, *
this);
90 auto found = scenes_.find(
id);
91 if (found != scenes_.end()) {
92 return found->second.get();
103 filament::Renderer::ClearOptions co;
104 co.clearColor.r =
color.x();
105 co.clearColor.g =
color.y();
106 co.clearColor.b =
color.z();
107 co.clearColor.a =
color.w();
110 renderer_->setClearOptions(co);
118 void* native_win = swap_chain_->getNativeWindow();
119 engine_.destroy(swap_chain_);
120 swap_chain_ = engine_.createSwapChain(native_win);
124 engine_.destroy(swap_chain_);
125 swap_chain_ = engine_.createSwapChain(
width,
height,
126 filament::SwapChain::CONFIG_READABLE);
131 if (!buffer_renderers_.empty()) {
132 for (
auto& br : buffer_renderers_) {
142 engine_.flushAndWait();
144 buffer_renderers_.clear();
147 frame_started_ = renderer_->beginFrame(swap_chain_);
151 if (frame_started_) {
153 for (
const auto& pair : scenes_) {
154 pair.second->Draw(*renderer_);
161 gui_scene_->Draw(*renderer_);
164 if (on_after_draw_) {
171 if (frame_started_) {
172 renderer_->endFrame();
173 if (needs_wait_after_draw_) {
174 engine_.flushAndWait();
175 needs_wait_after_draw_ =
false;
183 std::function<void(std::shared_ptr<core::Tensor>)>
callback;
184 std::shared_ptr<core::Tensor>
image;
186 UserData(std::function<
void(std::shared_ptr<core::Tensor>)> cb,
187 std::shared_ptr<core::Tensor> img)
192 auto* user_data =
static_cast<UserData*
>(user);
193 user_data->callback(user_data->image);
202 std::function<
void(std::shared_ptr<core::Tensor>)>
callback) {
205 int64_t nbytes = shape.NumElements() * dtype.
ByteSize();
207 auto image = std::make_shared<core::Tensor>(shape, dtype);
211 using namespace backend;
213 PixelBufferDescriptor pd(
image->GetDataPtr(), nbytes, PixelDataFormat::RGB,
216 renderer_->readPixels(0, 0,
width,
height, std::move(pd));
217 needs_wait_after_draw_ =
true;
222 return resource_mgr_.CreateMaterial(request);
227 return resource_mgr_.CreateMaterialInstance(material);
231 materials_modifier_->Reset();
233 auto instance_id = resource_mgr_.CreateMaterialInstance(
id);
236 auto w_material_instance =
237 resource_mgr_.GetMaterialInstance(instance_id);
238 materials_modifier_->Init(w_material_instance.lock(), instance_id);
241 "Failed to create material instance for material handle {}.",
245 return *materials_modifier_;
250 materials_modifier_->Reset();
252 auto w_material_instance = resource_mgr_.GetMaterialInstance(
id);
253 if (!w_material_instance.expired()) {
254 materials_modifier_->Init(w_material_instance.lock(),
id);
257 "Failed to modify material instance: unknown instance handle "
262 return *materials_modifier_;
267 resource_mgr_.Destroy(
id);
272 if (request.
path_.empty()) {
274 "Texture can be loaded only from file");
278 return resource_mgr_.CreateTexture(request.
path_.data(), srgb);
283 const std::shared_ptr<geometry::Image>
image,
285 return resource_mgr_.UpdateTexture(texture,
image, srgb);
291 return resource_mgr_.UpdateTexture(texture,
image, srgb);
295 resource_mgr_.Destroy(
id);
300 if (request.
path_.empty()) {
302 request, -1,
"Indirect lights can be loaded only from files");
306 return resource_mgr_.CreateIndirectLight(request);
310 resource_mgr_.Destroy(
id);
314 if (request.
path_.empty()) {
316 "Skyboxes can be loaded only from files");
320 return resource_mgr_.CreateSkybox(request);
324 resource_mgr_.Destroy(
id);
328 auto renderer = std::make_shared<FilamentRenderToBuffer>(engine_);
329 buffer_renderers_.insert(renderer);
334 auto found = scenes_.find(
id);
336 if (found != scenes_.end()) {
337 if (gui_scene_ !=
nullptr) {
339 "FilamentRenderer::ConvertToGuiScene: guiScene_ is already "
342 gui_scene_ = std::move(found->second);
343 scenes_.erase(found);
348 const std::shared_ptr<geometry::Image>
image,
bool srgb) {
349 return resource_mgr_.CreateTexture(
image, srgb);
354 return resource_mgr_.CreateTexture(
image, srgb);
std::shared_ptr< core::Tensor > image
std::function< void(std::shared_ptr< core::Tensor >)> callback
The Image class stores image with customizable rows, cols, channels, dtype and device.
std::shared_ptr< visualization::rendering::RenderToBuffer > CreateBufferRenderer() override
MaterialInstanceHandle AddMaterialInstance(const MaterialHandle &material) override
IndirectLightHandle AddIndirectLight(const ResourceLoadRequest &request) override
void ConvertToGuiScene(const SceneHandle &id)
virtual void SetClearColor(const Eigen::Vector4f &color) override
SceneHandle CreateScene() override
FilamentRenderer(filament::Engine &engine, void *native_drawable, FilamentResourceManager &resource_mgr)
void RemoveMaterialInstance(const MaterialInstanceHandle &id) override
void RemoveIndirectLight(const IndirectLightHandle &id) override
void RemoveTexture(const TextureHandle &id) override
bool UpdateTexture(TextureHandle texture, const std::shared_ptr< geometry::Image > image, bool srgb) override
~FilamentRenderer() override
void RemoveSkybox(const SkyboxHandle &id) override
void UpdateSwapChain() override
void DestroyScene(const SceneHandle &id) override
Scene * GetScene(const SceneHandle &id) const override
TextureHandle AddTexture(const ResourceLoadRequest &request, bool srgb=false) override
SkyboxHandle AddSkybox(const ResourceLoadRequest &request) override
void SetOnAfterDraw(std::function< void()> callback) override
MaterialModifier & ModifyMaterial(const MaterialHandle &id) override
void BeginFrame() override
MaterialHandle AddMaterial(const ResourceLoadRequest &request) override
void RequestReadPixels(int width, int height, std::function< void(std::shared_ptr< core::Tensor >)> callback) override
void UpdateBitmapSwapChain(int width, int height) override
ErrorCallback error_callback_
constexpr const char * UserData
void ReadPixelsCallback(void *buffer, size_t buffer_size, void *user)
Generic file read and write utility for python interface.