From fce29506d9232e492477fa01da68adb2ba997513 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 28 Sep 2022 06:48:51 -0700 Subject: [PATCH 1/9] Readme with draft interface --- impeller/scene/README.md | 130 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 impeller/scene/README.md diff --git a/impeller/scene/README.md b/impeller/scene/README.md new file mode 100644 index 0000000000000..732fa957bcc33 --- /dev/null +++ b/impeller/scene/README.md @@ -0,0 +1,130 @@ + + +## ⚠️ **Experimental:** Do not use in production! ⚠️ + +# Impeller Scene + +Impeller Scene is an experimental realtime 3D renderer powered by Impeller's +render layer with the following design priorities: + +* Ease to use. +* Suitability for mobile. +* Scalability in the common case. + +The aim is to create a familiar and flexible scene graph capable of building +complex dynamic scenes for games and beyond. + +## Example + +```cpp +std::shared_ptr context = + /* Create the backend-specific Impeller context */; + +auto allocator = context->GetResourceAllocator(); + +/// Load resources. + +auto dash_gltf = impeller::scene::LoadGLTF(allocator, "models/dash.glb"); +auto environment_hdri = + impeller::scene::LoadHDRI(allocator, "environment/table_mountain.hdr"); + +/// Construct a scene. + +auto scene = impeller::scene::Scene(); + +scene.Add(dash_gltf.scene); + +auto& dash_mixer = dash_gltf.scene.CreateAnimationPlayer(); +auto& walk_action = dash_mixer.CreateClipAction(dash_gltf.GetClip("Walk")); +walk_action.SetLoop(impeller::scene::AnimationAction::kLoopForever); +walk_action.SetWeight(0.7f); +walk_action.Seek(0.0f); +walk_action.Play(); +auto& run_action = dash_mixer.CreateClipAction(dash_gltf.GetClip("Run")); +run_action.SetLoop(impeller::scene::AnimationAction::kLoopForever); +run_action.SetWeight(0.3f); +run_action.Play(); + +scene.Add( + impeller::scene::DirectionalLight( + /* color */ impeller::Color::AntiqueWhite(), + /* intensity */ 5, + /* direction */ {2, 3, 4})); + +std::unique_ptr sphere = + impeller::scene::StaticMesh::MakeSphere(allocator, /* radius */ 2); +sphere->SetTransform(Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0})); +sphere->SetCullingMode(impeller::scene::CullingMode::kFrustum); + +auto material = impeller::scene::Material::MakeStandard(); +material.SetAlbedo(impeller::Color::Red()); +material.SetRoughness(0.4); +material.SetMetallic(0.2); +// Common properties shared by all materials. +material.SetEnvironmentMap(environment_hdri); +material.SetFlatShaded(true); +material.SetBlendConfig({ + impeller::BlendOperation::kAdd, // color_op + impeller::BlendFactor::kOne, // source_color_factor + impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor + impeller::BlendOperation::kAdd, // alpha_op + impeller::BlendFactor::kOne, // source_color_factor + impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor +}); +material.SetStencilConfig({ + impeller::StencilOperation::kIncrementClamp, // operation + impeller::CompareFunction::kAlways, // compare +}); + +auto cube = impeller::scene::StaticMesh::Cube({4, 4, 4}); +cube.SetTransform(Matrix::MakeTranslation({4, 0, 0})); + +sphere->Add(cube); +scene.Add(sphere); + +/// Post processing. + +auto dof = impeller::scene::PostProcessingEffect::MakeBokeh( + /* aperture_size */ 0.2, + /* focus_plane_distance */ 50); +scene.SetPostProcessing({dof}); + +/// Render the scene. + +auto renderer = impeller::Renderer(context); + +while(true) { + std::unique_ptr surface = /* Wrap the window surface */; + + renderer->Render(surface, [&scene](RenderTarget& render_target) { + /// Render a perspective view. + + auto camera = + impeller::Camera::MakePerspective( + /* fov */ kPiOver4, + /* position */ {50, -30, 50}) + .LookAt( + /* target */ impeller::Vector3::Zero, + /* up */ {0, -1, 0}); + + scene.Render(render_target, camera); + + /// Render an overhead view on the bottom right corner of the screen. + + auto size = render_target.GetRenderTargetSize(); + auto minimap_camera = + impeller::Camera::MakeOrthographic( + /* view */ Rect::MakeLTRB(-100, -100, 100, 100), + /* position */ {0, -50, 0}) + .LookAt( + /* target */ impeller::Vector3::Zero, + /* up */ {0, 0, 1}) + .WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4, + size.height / 5, size.height / 5)); + + scene.Render(render_target, minimap_camera); + + return true; + }); +} +``` From a6d2e83efb42f0878180dd6c65ec08415f931bbd Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Oct 2022 13:21:10 -0700 Subject: [PATCH 2/9] Scaffold scene --- impeller/scene/BUILD.gn | 36 +++++++++++++ impeller/scene/README.md | 16 +++--- impeller/scene/camera.cc | 9 ++++ impeller/scene/camera.h | 13 +++++ impeller/scene/mesh_entity.cc | 0 impeller/scene/mesh_entity.h | 25 +++++++++ impeller/scene/scene.cc | 31 +++++++++++ impeller/scene/scene.h | 35 ++++++++++++ impeller/scene/scene_encoder.cc | 19 +++++++ impeller/scene/scene_encoder.h | 30 +++++++++++ impeller/scene/scene_entity.cc | 67 +++++++++++++++++++++++ impeller/scene/scene_entity.h | 47 +++++++++++++++++ impeller/scene/scene_unittests.cc | 88 +++++++++++++++++++++++++++++++ 13 files changed, 409 insertions(+), 7 deletions(-) create mode 100644 impeller/scene/BUILD.gn create mode 100644 impeller/scene/camera.cc create mode 100644 impeller/scene/camera.h create mode 100644 impeller/scene/mesh_entity.cc create mode 100644 impeller/scene/mesh_entity.h create mode 100644 impeller/scene/scene.cc create mode 100644 impeller/scene/scene.h create mode 100644 impeller/scene/scene_encoder.cc create mode 100644 impeller/scene/scene_encoder.h create mode 100644 impeller/scene/scene_entity.cc create mode 100644 impeller/scene/scene_entity.h create mode 100644 impeller/scene/scene_unittests.cc diff --git a/impeller/scene/BUILD.gn b/impeller/scene/BUILD.gn new file mode 100644 index 0000000000000..b2fc7949a651c --- /dev/null +++ b/impeller/scene/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//flutter/impeller/tools/impeller.gni") + +impeller_component("scene") { + sources = [ + "camera.cc", + "camera.h", + "scene.cc", + "scene.h", + "scene_encoder.cc", + "scene_encoder.h", + "scene_entity.cc", + "scene_entity.h", + ] + + public_deps = [ "../renderer" ] + + deps = [ "//flutter/fml" ] +} + +impeller_component("scene_unittests") { + testonly = true + + sources = [ "scene_unittests.cc" ] + + deps = [ + ":scene", + "../fixtures", + "../playground:playground_test", + "//flutter/testing:testing_lib", + "//third_party/tinygltf", + ] +} diff --git a/impeller/scene/README.md b/impeller/scene/README.md index 732fa957bcc33..c7f1765c42b62 100644 --- a/impeller/scene/README.md +++ b/impeller/scene/README.md @@ -7,7 +7,7 @@ Impeller Scene is an experimental realtime 3D renderer powered by Impeller's render layer with the following design priorities: -* Ease to use. +* Ease of use. * Suitability for mobile. * Scalability in the common case. @@ -30,17 +30,17 @@ auto environment_hdri = /// Construct a scene. -auto scene = impeller::scene::Scene(); +auto scene = impeller::scene::Scene(context); scene.Add(dash_gltf.scene); -auto& dash_mixer = dash_gltf.scene.CreateAnimationPlayer(); -auto& walk_action = dash_mixer.CreateClipAction(dash_gltf.GetClip("Walk")); +auto& dash_player = dash_gltf.scene.CreateAnimationPlayer(); +auto& walk_action = dash_player.CreateClipAction(dash_gltf.GetClip("Walk")); walk_action.SetLoop(impeller::scene::AnimationAction::kLoopForever); walk_action.SetWeight(0.7f); walk_action.Seek(0.0f); walk_action.Play(); -auto& run_action = dash_mixer.CreateClipAction(dash_gltf.GetClip("Run")); +auto& run_action = dash_player.CreateClipAction(dash_gltf.GetClip("Run")); run_action.SetLoop(impeller::scene::AnimationAction::kLoopForever); run_action.SetWeight(0.3f); run_action.Play(); @@ -51,8 +51,8 @@ scene.Add( /* intensity */ 5, /* direction */ {2, 3, 4})); -std::unique_ptr sphere = - impeller::scene::StaticMesh::MakeSphere(allocator, /* radius */ 2); +std::unique_ptr sphere = + impeller::scene::MeshEntity::MakeSphere(allocator, /* radius */ 2); sphere->SetTransform(Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0})); sphere->SetCullingMode(impeller::scene::CullingMode::kFrustum); @@ -76,6 +76,8 @@ material.SetStencilConfig({ impeller::CompareFunction::kAlways, // compare }); +sphere->SetMaterial(material); + auto cube = impeller::scene::StaticMesh::Cube({4, 4, 4}); cube.SetTransform(Matrix::MakeTranslation({4, 0, 0})); diff --git a/impeller/scene/camera.cc b/impeller/scene/camera.cc new file mode 100644 index 0000000000000..faa3feb500341 --- /dev/null +++ b/impeller/scene/camera.cc @@ -0,0 +1,9 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace impeller { +namespace scene { + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/camera.h b/impeller/scene/camera.h new file mode 100644 index 0000000000000..d90bcd669f2da --- /dev/null +++ b/impeller/scene/camera.h @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +namespace impeller { +namespace scene { + +class Camera {}; + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/mesh_entity.cc b/impeller/scene/mesh_entity.cc new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/impeller/scene/mesh_entity.h b/impeller/scene/mesh_entity.h new file mode 100644 index 0000000000000..3eac19b2d5b0d --- /dev/null +++ b/impeller/scene/mesh_entity.h @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "flutter/fml/macros.h" + +#include "impeller/scene/scene_entity.h" + +namespace impeller { +namespace scene { + +class MeshEntity : SceneEntity { + public: + void Add(std::shared_ptr child); + + private: + bool OnRender(SceneEncoder& encoder, const Camera& camera) const override; + + FML_DISALLOW_COPY_AND_ASSIGN(MeshEntity); +}; + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene.cc b/impeller/scene/scene.cc new file mode 100644 index 0000000000000..e5e13901c0a85 --- /dev/null +++ b/impeller/scene/scene.cc @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/scene.h" + +#include +#include + +#include "impeller/renderer/render_target.h" +#include "impeller/scene/scene_encoder.h" + +namespace impeller { +namespace scene { + +Scene::Scene(std::shared_ptr context) : context_(std::move(context)){}; + +void Scene::Add(std::shared_ptr child) { + root_.Add(std::move(child)); +} + +bool Scene::Render(const RenderTarget& render_target, + const Camera& camera) const { + SceneEncoder encoder; + return root_.Render(encoder, camera); + std::shared_ptr geometry = + encoder.BuildGeometryCommandBuffer(render_target); +} + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene.h b/impeller/scene/scene.h new file mode 100644 index 0000000000000..0ac9e19a6e9b3 --- /dev/null +++ b/impeller/scene/scene.h @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#include "flutter/fml/macros.h" + +#include "impeller/renderer/render_target.h" +#include "impeller/scene/camera.h" +#include "impeller/scene/scene_entity.h" + +namespace impeller { +namespace scene { + +class Scene { + public: + Scene() = delete; + explicit Scene(std::shared_ptr context); + + void Add(std::shared_ptr child); + bool Render(const RenderTarget& render_target, const Camera& camera) const; + + private: + std::shared_ptr context_; + SceneEntity root_; + + FML_DISALLOW_COPY_AND_ASSIGN(Scene); +}; + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene_encoder.cc b/impeller/scene/scene_encoder.cc new file mode 100644 index 0000000000000..e8976ad788bed --- /dev/null +++ b/impeller/scene/scene_encoder.cc @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/fml/macros.h" + +#include "impeller/scene/scene_encoder.h" + +namespace impeller { +namespace scene { + +SceneEncoder::SceneEncoder() = default; + +std::shared_ptr SceneEncoder::BuildSceneCommandBuffer() const { + +} + +} +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene_encoder.h b/impeller/scene/scene_encoder.h new file mode 100644 index 0000000000000..6cc1016647cad --- /dev/null +++ b/impeller/scene/scene_encoder.h @@ -0,0 +1,30 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#include "flutter/fml/macros.h" + +#include "impeller/renderer/command_buffer.h" + +namespace impeller { +namespace scene { + +class Scene; + +class SceneEncoder { + private: + SceneEncoder(); + + std::shared_ptr BuildSceneCommandBuffer() const; + + friend Scene; + + FML_DISALLOW_COPY_AND_ASSIGN(SceneEncoder); +}; + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene_entity.cc b/impeller/scene/scene_entity.cc new file mode 100644 index 0000000000000..e5c939cb94c0a --- /dev/null +++ b/impeller/scene/scene_entity.cc @@ -0,0 +1,67 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/scene_entity.h" + +#include + +#include "impeller/base/validation.h" +#include "impeller/geometry/matrix.h" +#include "impeller/scene/scene_encoder.h" + +namespace impeller { +namespace scene { + +SceneEntity::SceneEntity() = default; + +void SceneEntity::SetLocalTransform(Matrix transform) { + local_transform_ = transform; +} + +Matrix SceneEntity::GetLocalTransform() const { + return local_transform_; +} + +void SceneEntity::SetGlobalTransform(Matrix transform) { + Matrix inverse_global_transform = + parent_ ? parent_->GetGlobalTransform().Invert() : Matrix(); + + local_transform_ = inverse_global_transform * transform; +} + +Matrix SceneEntity::GetGlobalTransform() const { + if (parent_) { + return parent_->GetGlobalTransform() * local_transform_; + } + return local_transform_; +} + +bool SceneEntity::Add(std::shared_ptr child) { + if (child->parent_ != nullptr) { + VALIDATION_LOG << "Cannot add SceneEntity as a child because it already " + "has a parent assigned."; + return false; + } + + children_.push_back(std::move(child)); + child->parent_ = this; + return true; +} + +bool SceneEntity::Render(SceneEncoder& encoder, const Camera& camera) const { + OnRender(encoder, camera); + for (auto& child : children_) { + if (!child->Render(encoder, camera)) { + return false; + } + } + return true; +} + +bool SceneEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const { + return true; +} + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene_entity.h b/impeller/scene/scene_entity.h new file mode 100644 index 0000000000000..f45c84a61c865 --- /dev/null +++ b/impeller/scene/scene_entity.h @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#include "flutter/fml/macros.h" + +#include "impeller/geometry/matrix.h" +#include "impeller/renderer/render_target.h" +#include "impeller/scene/camera.h" +#include "impeller/scene/scene_encoder.h" + +namespace impeller { +namespace scene { + +class SceneEntity { + public: + SceneEntity(); + + void SetLocalTransform(Matrix transform); + Matrix GetLocalTransform() const; + + void SetGlobalTransform(Matrix transform); + Matrix GetGlobalTransform() const; + + bool Add(std::shared_ptr child); + + bool Render(SceneEncoder& encoder, const Camera& camera) const; + + protected: + Matrix local_transform_; + + private: + virtual bool OnRender(SceneEncoder& encoder, const Camera& camera) const; + + SceneEntity* parent_; + std::vector> children_; + + FML_DISALLOW_COPY_AND_ASSIGN(SceneEntity); +}; + +} // namespace scene +} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene_unittests.cc b/impeller/scene/scene_unittests.cc new file mode 100644 index 0000000000000..1cf3b62d9a569 --- /dev/null +++ b/impeller/scene/scene_unittests.cc @@ -0,0 +1,88 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/fml/time/time_point.h" +#include "flutter/testing/testing.h" +#include "impeller/fixtures/impeller.frag.h" +#include "impeller/fixtures/impeller.vert.h" +#include "impeller/playground/playground.h" +#include "impeller/playground/playground_test.h" +#include "impeller/renderer/pipeline_library.h" +#include "impeller/renderer/render_pass.h" +#include "impeller/renderer/sampler_library.h" + +#include "third_party/tinygltf/tiny_gltf.h" + + +namespace impeller { +namespace testing { + +using SceneTest = PlaygroundTest; +INSTANTIATE_PLAYGROUND_SUITE(SceneTest); + +TEST_P(SceneTest, TheImpeller) { + + tinygltf::TinyGLTF ctx; + + using VS = ImpellerVertexShader; + using FS = ImpellerFragmentShader; + + auto context = GetContext(); + auto pipeline_descriptor = + PipelineBuilder::MakeDefaultPipelineDescriptor(*context); + ASSERT_TRUE(pipeline_descriptor.has_value()); + pipeline_descriptor->SetSampleCount(SampleCount::kCount4); + auto pipeline = + context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).get(); + ASSERT_TRUE(pipeline && pipeline->IsValid()); + + auto blue_noise = CreateTextureForFixture("blue_noise.png"); + SamplerDescriptor noise_sampler_desc; + noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat; + noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat; + auto noise_sampler = + context->GetSamplerLibrary()->GetSampler(noise_sampler_desc); + + auto cube_map = CreateTextureCubeForFixture( + {"table_mountain_px.png", "table_mountain_nx.png", + "table_mountain_py.png", "table_mountain_ny.png", + "table_mountain_pz.png", "table_mountain_nz.png"}); + auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({}); + + SinglePassCallback callback = [&](RenderPass& pass) { + auto size = pass.GetRenderTargetSize(); + + Command cmd; + cmd.pipeline = pipeline; + cmd.label = "Impeller SDF scene"; + VertexBufferBuilder builder; + builder.AddVertices({{Point()}, + {Point(0, size.height)}, + {Point(size.width, 0)}, + {Point(size.width, 0)}, + {Point(0, size.height)}, + {Point(size.width, size.height)}}); + cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + + VS::FrameInfo vs_uniform; + vs_uniform.mvp = Matrix::MakeOrthographic(size); + VS::BindFrameInfo(cmd, + pass.GetTransientsBuffer().EmplaceUniform(vs_uniform)); + + FS::FragInfo fs_uniform; + fs_uniform.texture_size = Point(size); + fs_uniform.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF(); + FS::BindFragInfo(cmd, + pass.GetTransientsBuffer().EmplaceUniform(fs_uniform)); + FS::BindBlueNoise(cmd, blue_noise, noise_sampler); + FS::BindCubeMap(cmd, cube_map, cube_map_sampler); + + pass.AddCommand(cmd); + return true; + }; + OpenPlaygroundHere(callback); +} + +} // namespace testing +} // namespace impeller From 3b6fdacd335a9be72941f51b6dcb45f5a11d241f Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 5 Nov 2022 00:27:49 -0700 Subject: [PATCH 3/9] Render loop scaffolding --- impeller/scene/BUILD.gn | 2 + impeller/scene/README.md | 8 ++-- impeller/scene/camera.cc | 4 +- impeller/scene/camera.h | 2 +- impeller/scene/material.cc | 69 +++++++++++++++++++++++++++++++ impeller/scene/material.h | 73 +++++++++++++++++++++++++++++++++ impeller/scene/mesh_entity.cc | 11 +++++ impeller/scene/scene.cc | 24 +++++++++-- impeller/scene/scene.h | 2 +- impeller/scene/scene_encoder.cc | 16 ++++++-- impeller/scene/scene_encoder.h | 8 +++- impeller/scene/scene_entity.cc | 2 +- impeller/scene/scene_entity.h | 2 +- 13 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 impeller/scene/material.cc create mode 100644 impeller/scene/material.h diff --git a/impeller/scene/BUILD.gn b/impeller/scene/BUILD.gn index b2fc7949a651c..0d70d310c63e1 100644 --- a/impeller/scene/BUILD.gn +++ b/impeller/scene/BUILD.gn @@ -8,6 +8,8 @@ impeller_component("scene") { sources = [ "camera.cc", "camera.h", + "material.cc", + "material.h", "scene.cc", "scene.h", "scene_encoder.cc", diff --git a/impeller/scene/README.md b/impeller/scene/README.md index c7f1765c42b62..7932f8a533575 100644 --- a/impeller/scene/README.md +++ b/impeller/scene/README.md @@ -1,5 +1,3 @@ - - ## ⚠️ **Experimental:** Do not use in production! ⚠️ # Impeller Scene @@ -9,7 +7,7 @@ render layer with the following design priorities: * Ease of use. * Suitability for mobile. -* Scalability in the common case. +* Common case scalability. The aim is to create a familiar and flexible scene graph capable of building complex dynamic scenes for games and beyond. @@ -68,8 +66,8 @@ material.SetBlendConfig({ impeller::BlendFactor::kOne, // source_color_factor impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor impeller::BlendOperation::kAdd, // alpha_op - impeller::BlendFactor::kOne, // source_color_factor - impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor + impeller::BlendFactor::kOne, // source_alpha_factor + impeller::BlendFactor::kOneMinusSourceAlpha, // destination_alpha_factor }); material.SetStencilConfig({ impeller::StencilOperation::kIncrementClamp, // operation diff --git a/impeller/scene/camera.cc b/impeller/scene/camera.cc index faa3feb500341..329f653d18add 100644 --- a/impeller/scene/camera.cc +++ b/impeller/scene/camera.cc @@ -5,5 +5,7 @@ namespace impeller { namespace scene { +// + } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/camera.h b/impeller/scene/camera.h index d90bcd669f2da..afa9470a129ad 100644 --- a/impeller/scene/camera.h +++ b/impeller/scene/camera.h @@ -10,4 +10,4 @@ namespace scene { class Camera {}; } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/material.cc b/impeller/scene/material.cc new file mode 100644 index 0000000000000..5d1365409baa4 --- /dev/null +++ b/impeller/scene/material.cc @@ -0,0 +1,69 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/material.h" +#include + +namespace impeller { +namespace scene { + +//------------------------------------------------------------------------------ +/// Material +/// + +std::unique_ptr Material::MakeStandard() { + return std::make_unique(); +} + +void Material::SetBlendConfig(BlendConfig blend_config) { + blend_config_ = blend_config; +} + +void Material::SetStencilConfig(StencilConfig stencil_config) { + stencil_config_ = stencil_config; +} + +void Material::SetTranslucent(bool is_translucent) { + is_translucent_ = is_translucent; +} + +//------------------------------------------------------------------------------ +/// StandardMaterial +/// + +void StandardMaterial::SetAlbedo(Color albedo) { + albedo_ = albedo; +} + +void StandardMaterial::SetRoughness(Scalar roughness) { + roughness_ = roughness; +} + +void StandardMaterial::SetMetallic(Scalar metallic) { + metallic_ = metallic; +} + +void StandardMaterial::SetAlbedoTexture( + std::shared_ptr albedo_texture) { + albedo_texture_ = std::move(albedo_texture); +} + +void StandardMaterial::SetNormalTexture( + std::shared_ptr normal_texture) { + normal_texture_ = std::move(normal_texture); +} + +void StandardMaterial::SetOcclusionRoughnessMetallicTexture( + std::shared_ptr occlusion_roughness_metallic_texture) { + occlusion_roughness_metallic_texture_ = + std::move(occlusion_roughness_metallic_texture); +} + +void StandardMaterial::SetEnvironmentMap( + std::shared_ptr environment_map) { + environment_map_ = std::move(environment_map); +} + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/material.h b/impeller/scene/material.h new file mode 100644 index 0000000000000..3cc13b6ee1927 --- /dev/null +++ b/impeller/scene/material.h @@ -0,0 +1,73 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#include "impeller/geometry/scalar.h" +#include "impeller/renderer/formats.h" +#include "impeller/renderer/texture.h" + +namespace impeller { +namespace scene { + +class StandardMaterial; + +class Material { + public: + struct BlendConfig { + BlendOperation color_op = BlendOperation::kAdd; + BlendFactor source_color_factor = BlendFactor::kOne; + BlendFactor destination_color_factor = BlendFactor::kOneMinusSourceAlpha; + BlendOperation alpha_op = BlendOperation::kAdd; + BlendFactor source_alpha_factor = BlendFactor::kOne; + BlendFactor destination_alpha_factor = BlendFactor::kOneMinusSourceAlpha; + }; + + struct StencilConfig { + StencilOperation operation = StencilOperation::kKeep; + CompareFunction compare = CompareFunction::kAlways; + }; + + std::unique_ptr MakeStandard(); + + void SetBlendConfig(BlendConfig blend_config); + void SetStencilConfig(StencilConfig stencil_config); + + void SetTranslucent(bool is_translucent); + + protected: + BlendConfig blend_config_; + StencilConfig stencil_config_; + bool is_translucent_ = false; +}; + +class StandardMaterial final : public Material { + public: + void SetAlbedo(Color albedo); + void SetRoughness(Scalar roughness); + void SetMetallic(Scalar metallic); + + void SetAlbedoTexture(std::shared_ptr albedo_texture); + void SetNormalTexture(std::shared_ptr normal_texture); + void SetOcclusionRoughnessMetallicTexture( + std::shared_ptr occlusion_roughness_metallic_texture); + + void SetEnvironmentMap(std::shared_ptr environment_map); + + private: + Color albedo_ = Color::CornflowerBlue(); + Scalar roughness_ = 0.5; + Scalar metallic_ = 0.5; + + std::shared_ptr albedo_texture_; + std::shared_ptr normal_texture_; + std::shared_ptr occlusion_roughness_metallic_texture_; + + std::shared_ptr environment_map_; +}; + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/mesh_entity.cc b/impeller/scene/mesh_entity.cc index e69de29bb2d1d..329f653d18add 100644 --- a/impeller/scene/mesh_entity.cc +++ b/impeller/scene/mesh_entity.cc @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace impeller { +namespace scene { + +// + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/scene.cc b/impeller/scene/scene.cc index e5e13901c0a85..017b0377a7a35 100644 --- a/impeller/scene/scene.cc +++ b/impeller/scene/scene.cc @@ -7,6 +7,7 @@ #include #include +#include "flutter/fml/logging.h" #include "impeller/renderer/render_target.h" #include "impeller/scene/scene_encoder.h" @@ -21,11 +22,26 @@ void Scene::Add(std::shared_ptr child) { bool Scene::Render(const RenderTarget& render_target, const Camera& camera) const { + // Collect the render commands from the scene. SceneEncoder encoder; - return root_.Render(encoder, camera); - std::shared_ptr geometry = - encoder.BuildGeometryCommandBuffer(render_target); + if (!root_.Render(encoder, camera)) { + FML_LOG(ERROR) << "Failed to render frame."; + return false; + } + + // Encode the commands. + std::shared_ptr command_buffer = + encoder.BuildSceneCommandBuffer(*context_, render_target); + + // TODO(bdero): Do post processing. + + if (!command_buffer->SubmitCommands()) { + FML_LOG(ERROR) << "Failed to submit command buffer."; + return false; + } + + return true; } } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/scene.h b/impeller/scene/scene.h index 0ac9e19a6e9b3..bda855c61fa62 100644 --- a/impeller/scene/scene.h +++ b/impeller/scene/scene.h @@ -32,4 +32,4 @@ class Scene { }; } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/scene_encoder.cc b/impeller/scene/scene_encoder.cc index e8976ad788bed..456a86df644d3 100644 --- a/impeller/scene/scene_encoder.cc +++ b/impeller/scene/scene_encoder.cc @@ -4,6 +4,8 @@ #include "flutter/fml/macros.h" +#include "fml/logging.h" +#include "impeller/renderer/render_target.h" #include "impeller/scene/scene_encoder.h" namespace impeller { @@ -11,9 +13,17 @@ namespace scene { SceneEncoder::SceneEncoder() = default; -std::shared_ptr SceneEncoder::BuildSceneCommandBuffer() const { +std::shared_ptr SceneEncoder::BuildSceneCommandBuffer( + Context& context, + const RenderTarget& render_target) const { + auto command_buffer = context.CreateCommandBuffer(); + if (!command_buffer) { + FML_LOG(ERROR) << "Failed to create command buffer."; + return nullptr; + } + return command_buffer; } -} -} // namespace impeller \ No newline at end of file +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/scene_encoder.h b/impeller/scene/scene_encoder.h index 6cc1016647cad..f026516abb6b4 100644 --- a/impeller/scene/scene_encoder.h +++ b/impeller/scene/scene_encoder.h @@ -16,10 +16,14 @@ namespace scene { class Scene; class SceneEncoder { + + private: SceneEncoder(); - std::shared_ptr BuildSceneCommandBuffer() const; + std::shared_ptr BuildSceneCommandBuffer( + Context& context, + const RenderTarget& render_target) const; friend Scene; @@ -27,4 +31,4 @@ class SceneEncoder { }; } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/scene_entity.cc b/impeller/scene/scene_entity.cc index e5c939cb94c0a..3533cbe7fe3b4 100644 --- a/impeller/scene/scene_entity.cc +++ b/impeller/scene/scene_entity.cc @@ -64,4 +64,4 @@ bool SceneEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const { } } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/scene/scene_entity.h b/impeller/scene/scene_entity.h index f45c84a61c865..e4fa44c9b4993 100644 --- a/impeller/scene/scene_entity.h +++ b/impeller/scene/scene_entity.h @@ -44,4 +44,4 @@ class SceneEntity { }; } // namespace scene -} // namespace impeller \ No newline at end of file +} // namespace impeller From 9916db9fd2ae6d506bddc199d4de58d64d59564f Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sun, 6 Nov 2022 05:26:30 -0800 Subject: [PATCH 4/9] Scaffold geometry, camera, and mesh entity --- impeller/BUILD.gn | 1 + impeller/scene/BUILD.gn | 4 ++ impeller/scene/README.md | 28 ++++++--- impeller/scene/camera.cc | 28 ++++++++- impeller/scene/camera.h | 23 ++++++- impeller/scene/geometry.cc | 36 +++++++++++ impeller/scene/geometry.h | 39 ++++++++++++ impeller/scene/material.cc | 13 ++++ impeller/scene/material.h | 12 +++- impeller/scene/mesh_entity.cc | 11 ---- impeller/scene/mesh_entity.h | 25 -------- impeller/scene/scene.cc | 6 +- impeller/scene/scene.h | 4 +- impeller/scene/scene_entity.cc | 9 ++- impeller/scene/scene_entity.h | 7 ++- impeller/scene/scene_unittests.cc | 92 ++++++++++------------------ impeller/scene/static_mesh_entity.cc | 29 +++++++++ impeller/scene/static_mesh_entity.h | 37 +++++++++++ 18 files changed, 291 insertions(+), 113 deletions(-) create mode 100644 impeller/scene/geometry.cc create mode 100644 impeller/scene/geometry.h delete mode 100644 impeller/scene/mesh_entity.cc delete mode 100644 impeller/scene/mesh_entity.h create mode 100644 impeller/scene/static_mesh_entity.cc create mode 100644 impeller/scene/static_mesh_entity.h diff --git a/impeller/BUILD.gn b/impeller/BUILD.gn index 2fbc00d125343..2920b94f91949 100644 --- a/impeller/BUILD.gn +++ b/impeller/BUILD.gn @@ -86,6 +86,7 @@ impeller_component("impeller_unittests") { "image:image_unittests", "playground", "renderer:renderer_unittests", + "scene:scene_unittests", "typographer:typographer_unittests", ] } diff --git a/impeller/scene/BUILD.gn b/impeller/scene/BUILD.gn index 0d70d310c63e1..ad366c89568d1 100644 --- a/impeller/scene/BUILD.gn +++ b/impeller/scene/BUILD.gn @@ -8,6 +8,8 @@ impeller_component("scene") { sources = [ "camera.cc", "camera.h", + "geometry.cc", + "geometry.h", "material.cc", "material.h", "scene.cc", @@ -16,6 +18,8 @@ impeller_component("scene") { "scene_encoder.h", "scene_entity.cc", "scene_entity.h", + "static_mesh_entity.cc", + "static_mesh_entity.h", ] public_deps = [ "../renderer" ] diff --git a/impeller/scene/README.md b/impeller/scene/README.md index 7932f8a533575..c17299293cacd 100644 --- a/impeller/scene/README.md +++ b/impeller/scene/README.md @@ -49,10 +49,15 @@ scene.Add( /* intensity */ 5, /* direction */ {2, 3, 4})); -std::unique_ptr sphere = - impeller::scene::MeshEntity::MakeSphere(allocator, /* radius */ 2); -sphere->SetTransform(Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0})); -sphere->SetCullingMode(impeller::scene::CullingMode::kFrustum); +impeller::scene::StaticMeshEntity sphere_entity; +sphere_entity.SetGlobalTransform( + Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0})); +sphere_entity.SetCullingMode(impeller::scene::CullingMode::kFrustum); + +std::unique_ptr sphere = + impeller::scene::Geometry::MakeSphere(allocator, /* radius */ 2); + +sphere_entity.SetGeometry(sphere); auto material = impeller::scene::Material::MakeStandard(); material.SetAlbedo(impeller::Color::Red()); @@ -74,13 +79,18 @@ material.SetStencilConfig({ impeller::CompareFunction::kAlways, // compare }); -sphere->SetMaterial(material); +sphere_entity->SetMaterials({material}); + + +impeller::scene::StaticMeshEntity cube_entity; +cube_entity.GetGeometry( + impeller::scene::Geometry::MakeCube(allocator, {4, 4, 4})); +cube_entity.SetMaterials({material}); -auto cube = impeller::scene::StaticMesh::Cube({4, 4, 4}); -cube.SetTransform(Matrix::MakeTranslation({4, 0, 0})); +cube_entity.SetLocalTransform(Matrix::MakeTranslation({4, 0, 0})); -sphere->Add(cube); -scene.Add(sphere); +sphere_entity->Add(sube_entity); +scene.Add(sphere_entity); /// Post processing. diff --git a/impeller/scene/camera.cc b/impeller/scene/camera.cc index 329f653d18add..b10673bd4899c 100644 --- a/impeller/scene/camera.cc +++ b/impeller/scene/camera.cc @@ -2,10 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "impeller/scene/camera.h" + namespace impeller { namespace scene { -// +Camera Camera::MakePerspective(Scalar fov_y, Vector3 position) { + Camera camera; + camera.fov_y_ = fov_y; + camera.position_ = position; + return camera; +} + +Camera Camera::LookAt(Vector3 target, Vector3 up) const { + Camera camera = *this; + camera.target_ = target; + camera.up_ = up; + return camera; +} + +Matrix Camera::GetTransform(ISize target_size) const { + if (transform_.has_value()) { + return transform_.value(); + } + + transform_ = + Matrix::MakePerspective(Radians(fov_y_), target_size, z_near_, z_far_) * + Matrix::MakeLookAt(position_, target_, up_).Invert(); + + return transform_.value(); +} } // namespace scene } // namespace impeller diff --git a/impeller/scene/camera.h b/impeller/scene/camera.h index afa9470a129ad..0eb02376ef684 100644 --- a/impeller/scene/camera.h +++ b/impeller/scene/camera.h @@ -4,10 +4,31 @@ #pragma once +#include + +#include "impeller/geometry/matrix.h" + namespace impeller { namespace scene { -class Camera {}; +class Camera { + public: + static Camera MakePerspective(Scalar fov_y, Vector3 position); + + Camera LookAt(Vector3 target, Vector3 up = Vector3(0, -1, 0)) const; + + Matrix GetTransform(ISize target_size) const; + + private: + Scalar fov_y_ = 60; + Vector3 position_ = Vector3(); + Vector3 target_ = Vector3(0, 0, -1); + Vector3 up_ = Vector3(0, -1, 0); + Scalar z_near_ = 0.1; + Scalar z_far_ = 1000; + + mutable std::optional transform_; +}; } // namespace scene } // namespace impeller diff --git a/impeller/scene/geometry.cc b/impeller/scene/geometry.cc new file mode 100644 index 0000000000000..47ed75f18b6d5 --- /dev/null +++ b/impeller/scene/geometry.cc @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/geometry.h" + +#include + +namespace impeller { +namespace scene { + +//------------------------------------------------------------------------------ +/// Geometry +/// + +std::shared_ptr Geometry::MakeCuboid(Vector3 size) { + auto result = std::make_shared(); + result->SetSize(size); + return result; +} + +//------------------------------------------------------------------------------ +/// CuboidGeometry +/// + +void CuboidGeometry::SetSize(Vector3 size) { + size_ = size; +} + +VertexBuffer CuboidGeometry::GetVertexBuffer( + std::shared_ptr& allocator) const { + return {}; +} + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/geometry.h b/impeller/scene/geometry.h new file mode 100644 index 0000000000000..f0e7e47eb38bd --- /dev/null +++ b/impeller/scene/geometry.h @@ -0,0 +1,39 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#include "impeller/geometry/vector.h" +#include "impeller/renderer/allocator.h" +#include "impeller/renderer/vertex_buffer.h" + +namespace impeller { +namespace scene { + +class CuboidGeometry; + +class Geometry { + public: + static std::shared_ptr MakeCuboid(Vector3 size); + + private: + virtual VertexBuffer GetVertexBuffer( + std::shared_ptr& allocator) const = 0; +}; + +class CuboidGeometry final : public Geometry { + public: + void SetSize(Vector3 size); + + private: + VertexBuffer GetVertexBuffer( + std::shared_ptr& allocator) const override; + + Vector3 size_; +}; + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/material.cc b/impeller/scene/material.cc index 5d1365409baa4..a38a14a4f539f 100644 --- a/impeller/scene/material.cc +++ b/impeller/scene/material.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "impeller/scene/material.h" + #include namespace impeller { @@ -12,6 +13,10 @@ namespace scene { /// Material /// +std::unique_ptr Material::MakeUnlit() { + return std::make_unique(); +} + std::unique_ptr Material::MakeStandard() { return std::make_unique(); } @@ -28,6 +33,14 @@ void Material::SetTranslucent(bool is_translucent) { is_translucent_ = is_translucent; } +//------------------------------------------------------------------------------ +/// UnlitMaterial +/// + +void UnlitMaterial::SetColor(Color color) { + color_ = color; +} + //------------------------------------------------------------------------------ /// StandardMaterial /// diff --git a/impeller/scene/material.h b/impeller/scene/material.h index 3cc13b6ee1927..a9e0be7a3ba7c 100644 --- a/impeller/scene/material.h +++ b/impeller/scene/material.h @@ -13,6 +13,7 @@ namespace impeller { namespace scene { +class UnlitMaterial; class StandardMaterial; class Material { @@ -31,7 +32,8 @@ class Material { CompareFunction compare = CompareFunction::kAlways; }; - std::unique_ptr MakeStandard(); + static std::unique_ptr MakeUnlit(); + static std::unique_ptr MakeStandard(); void SetBlendConfig(BlendConfig blend_config); void SetStencilConfig(StencilConfig stencil_config); @@ -44,6 +46,14 @@ class Material { bool is_translucent_ = false; }; +class UnlitMaterial final : public Material { + public: + void SetColor(Color color); + + private: + Color color_; +}; + class StandardMaterial final : public Material { public: void SetAlbedo(Color albedo); diff --git a/impeller/scene/mesh_entity.cc b/impeller/scene/mesh_entity.cc deleted file mode 100644 index 329f653d18add..0000000000000 --- a/impeller/scene/mesh_entity.cc +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -namespace impeller { -namespace scene { - -// - -} // namespace scene -} // namespace impeller diff --git a/impeller/scene/mesh_entity.h b/impeller/scene/mesh_entity.h deleted file mode 100644 index 3eac19b2d5b0d..0000000000000 --- a/impeller/scene/mesh_entity.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#pragma once - -#include "flutter/fml/macros.h" - -#include "impeller/scene/scene_entity.h" - -namespace impeller { -namespace scene { - -class MeshEntity : SceneEntity { - public: - void Add(std::shared_ptr child); - - private: - bool OnRender(SceneEncoder& encoder, const Camera& camera) const override; - - FML_DISALLOW_COPY_AND_ASSIGN(MeshEntity); -}; - -} // namespace scene -} // namespace impeller \ No newline at end of file diff --git a/impeller/scene/scene.cc b/impeller/scene/scene.cc index 017b0377a7a35..4a4cba16a59fc 100644 --- a/impeller/scene/scene.cc +++ b/impeller/scene/scene.cc @@ -14,10 +14,10 @@ namespace impeller { namespace scene { -Scene::Scene(std::shared_ptr context) : context_(std::move(context)){}; +Scene::Scene(const std::shared_ptr& context) : context_(context){}; -void Scene::Add(std::shared_ptr child) { - root_.Add(std::move(child)); +void Scene::Add(const std::shared_ptr& child) { + root_.Add(child); } bool Scene::Render(const RenderTarget& render_target, diff --git a/impeller/scene/scene.h b/impeller/scene/scene.h index bda855c61fa62..6a69e79e2be3f 100644 --- a/impeller/scene/scene.h +++ b/impeller/scene/scene.h @@ -19,9 +19,9 @@ namespace scene { class Scene { public: Scene() = delete; - explicit Scene(std::shared_ptr context); + explicit Scene(const std::shared_ptr& context); - void Add(std::shared_ptr child); + void Add(const std::shared_ptr& child); bool Render(const RenderTarget& render_target, const Camera& camera) const; private: diff --git a/impeller/scene/scene_entity.cc b/impeller/scene/scene_entity.cc index 3533cbe7fe3b4..9b7b17a574251 100644 --- a/impeller/scene/scene_entity.cc +++ b/impeller/scene/scene_entity.cc @@ -9,12 +9,19 @@ #include "impeller/base/validation.h" #include "impeller/geometry/matrix.h" #include "impeller/scene/scene_encoder.h" +#include "impeller/scene/static_mesh_entity.h" namespace impeller { namespace scene { SceneEntity::SceneEntity() = default; +SceneEntity::~SceneEntity() = default; + +std::shared_ptr SceneEntity::MakeStaticMesh() { + return std::make_shared(); +} + void SceneEntity::SetLocalTransform(Matrix transform) { local_transform_ = transform; } @@ -37,7 +44,7 @@ Matrix SceneEntity::GetGlobalTransform() const { return local_transform_; } -bool SceneEntity::Add(std::shared_ptr child) { +bool SceneEntity::Add(const std::shared_ptr& child) { if (child->parent_ != nullptr) { VALIDATION_LOG << "Cannot add SceneEntity as a child because it already " "has a parent assigned."; diff --git a/impeller/scene/scene_entity.h b/impeller/scene/scene_entity.h index e4fa44c9b4993..5adce3f9823c3 100644 --- a/impeller/scene/scene_entity.h +++ b/impeller/scene/scene_entity.h @@ -17,9 +17,14 @@ namespace impeller { namespace scene { +class StaticMeshEntity; + class SceneEntity { public: SceneEntity(); + virtual ~SceneEntity(); + + static std::shared_ptr MakeStaticMesh(); void SetLocalTransform(Matrix transform); Matrix GetLocalTransform() const; @@ -27,7 +32,7 @@ class SceneEntity { void SetGlobalTransform(Matrix transform); Matrix GetGlobalTransform() const; - bool Add(std::shared_ptr child); + bool Add(const std::shared_ptr& child); bool Render(SceneEncoder& encoder, const Camera& camera) const; diff --git a/impeller/scene/scene_unittests.cc b/impeller/scene/scene_unittests.cc index 1cf3b62d9a569..c72e8f90c68f9 100644 --- a/impeller/scene/scene_unittests.cc +++ b/impeller/scene/scene_unittests.cc @@ -2,87 +2,63 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/fml/time/time_point.h" #include "flutter/testing/testing.h" -#include "impeller/fixtures/impeller.frag.h" -#include "impeller/fixtures/impeller.vert.h" +#include "impeller/geometry/color.h" +#include "impeller/geometry/constants.h" +#include "impeller/geometry/matrix.h" +#include "impeller/geometry/vector.h" #include "impeller/playground/playground.h" #include "impeller/playground/playground_test.h" -#include "impeller/renderer/pipeline_library.h" -#include "impeller/renderer/render_pass.h" -#include "impeller/renderer/sampler_library.h" -#include "third_party/tinygltf/tiny_gltf.h" +#include "impeller/scene/camera.h" +#include "impeller/scene/geometry.h" +#include "impeller/scene/material.h" +#include "impeller/scene/scene.h" +#include "impeller/scene/static_mesh_entity.h" +#include "third_party/tinygltf/tiny_gltf.h" namespace impeller { +namespace scene { namespace testing { using SceneTest = PlaygroundTest; INSTANTIATE_PLAYGROUND_SUITE(SceneTest); -TEST_P(SceneTest, TheImpeller) { - - tinygltf::TinyGLTF ctx; +TEST_P(SceneTest, UnlitScene) { + auto allocator = GetContext()->GetResourceAllocator(); + auto scene = Scene(GetContext()); - using VS = ImpellerVertexShader; - using FS = ImpellerFragmentShader; + { + auto mesh = SceneEntity::MakeStaticMesh(); - auto context = GetContext(); - auto pipeline_descriptor = - PipelineBuilder::MakeDefaultPipelineDescriptor(*context); - ASSERT_TRUE(pipeline_descriptor.has_value()); - pipeline_descriptor->SetSampleCount(SampleCount::kCount4); - auto pipeline = - context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).get(); - ASSERT_TRUE(pipeline && pipeline->IsValid()); + auto material = Material::MakeUnlit(); + material->SetColor(Color::Red()); + mesh->SetMaterial(std::move(material)); - auto blue_noise = CreateTextureForFixture("blue_noise.png"); - SamplerDescriptor noise_sampler_desc; - noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat; - noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat; - auto noise_sampler = - context->GetSamplerLibrary()->GetSampler(noise_sampler_desc); + Vector3 size(1, 2, 3); + mesh->SetGeometry(Geometry::MakeCuboid(size)); - auto cube_map = CreateTextureCubeForFixture( - {"table_mountain_px.png", "table_mountain_nx.png", - "table_mountain_py.png", "table_mountain_ny.png", - "table_mountain_pz.png", "table_mountain_nz.png"}); - auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({}); + mesh->SetLocalTransform(Matrix::MakeTranslation(size / 2)); - SinglePassCallback callback = [&](RenderPass& pass) { - auto size = pass.GetRenderTargetSize(); + scene.Add(mesh); + } - Command cmd; - cmd.pipeline = pipeline; - cmd.label = "Impeller SDF scene"; - VertexBufferBuilder builder; - builder.AddVertices({{Point()}, - {Point(0, size.height)}, - {Point(size.width, 0)}, - {Point(size.width, 0)}, - {Point(0, size.height)}, - {Point(size.width, size.height)}}); - cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + Renderer::RenderCallback callback = [&](RenderTarget& render_target) { + auto camera = Camera::MakePerspective( + /* fov */ kPiOver4, + /* position */ {50, -30, 50}) + .LookAt( + /* target */ Vector3(), + /* up */ {0, -1, 0}); - VS::FrameInfo vs_uniform; - vs_uniform.mvp = Matrix::MakeOrthographic(size); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(vs_uniform)); - - FS::FragInfo fs_uniform; - fs_uniform.texture_size = Point(size); - fs_uniform.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF(); - FS::BindFragInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(fs_uniform)); - FS::BindBlueNoise(cmd, blue_noise, noise_sampler); - FS::BindCubeMap(cmd, cube_map, cube_map_sampler); - - pass.AddCommand(cmd); + scene.Render(render_target, camera); return true; }; + OpenPlaygroundHere(callback); } } // namespace testing +} // namespace scene } // namespace impeller diff --git a/impeller/scene/static_mesh_entity.cc b/impeller/scene/static_mesh_entity.cc new file mode 100644 index 0000000000000..1b092dd0146b4 --- /dev/null +++ b/impeller/scene/static_mesh_entity.cc @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/static_mesh_entity.h" +#include +#include "impeller/scene/material.h" + +namespace impeller { +namespace scene { + +StaticMeshEntity::StaticMeshEntity() = default; +StaticMeshEntity::~StaticMeshEntity() = default; + +void StaticMeshEntity::SetGeometry(std::shared_ptr geometry) { + geometry_ = std::move(geometry); +} + +void StaticMeshEntity::SetMaterial(std::shared_ptr material) { + material_ = std::move(material); +} + +// |SceneEntity| +bool StaticMeshEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const { + return true; +} + +} // namespace scene +} // namespace impeller diff --git a/impeller/scene/static_mesh_entity.h b/impeller/scene/static_mesh_entity.h new file mode 100644 index 0000000000000..7a1df4543d973 --- /dev/null +++ b/impeller/scene/static_mesh_entity.h @@ -0,0 +1,37 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#include "flutter/fml/macros.h" +#include "impeller/scene/geometry.h" +#include "impeller/scene/material.h" +#include "impeller/scene/scene_entity.h" + +namespace impeller { +namespace scene { + +class StaticMeshEntity final : public SceneEntity { + public: + StaticMeshEntity(); + ~StaticMeshEntity(); + + void SetGeometry(std::shared_ptr material); + void SetMaterial(std::shared_ptr material); + + private: + // |SceneEntity| + bool OnRender(SceneEncoder& encoder, const Camera& camera) const override; + + std::shared_ptr material_; + std::shared_ptr geometry_; + + FML_DISALLOW_COPY_AND_ASSIGN(StaticMeshEntity); +}; + +} // namespace scene +} // namespace impeller From a6b3a44013501306b655d17642e0cdf9ea27bfa7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 16 Nov 2022 15:48:48 -0800 Subject: [PATCH 5/9] Fix null issue --- impeller/scene/scene_entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/scene/scene_entity.h b/impeller/scene/scene_entity.h index 5adce3f9823c3..694d0cd3616fe 100644 --- a/impeller/scene/scene_entity.h +++ b/impeller/scene/scene_entity.h @@ -42,7 +42,7 @@ class SceneEntity { private: virtual bool OnRender(SceneEncoder& encoder, const Camera& camera) const; - SceneEntity* parent_; + SceneEntity* parent_ = nullptr; std::vector> children_; FML_DISALLOW_COPY_AND_ASSIGN(SceneEntity); From 92d624676c1a881715984030ceff50028f143fc0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 16 Nov 2022 22:23:14 -0800 Subject: [PATCH 6/9] Remove GLTF stuff for now --- impeller/scene/BUILD.gn | 3 ++- impeller/scene/scene_unittests.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/impeller/scene/BUILD.gn b/impeller/scene/BUILD.gn index ad366c89568d1..3389ad42bde7b 100644 --- a/impeller/scene/BUILD.gn +++ b/impeller/scene/BUILD.gn @@ -37,6 +37,7 @@ impeller_component("scene_unittests") { "../fixtures", "../playground:playground_test", "//flutter/testing:testing_lib", - "//third_party/tinygltf", + + #"//third_party/tinygltf", ] } diff --git a/impeller/scene/scene_unittests.cc b/impeller/scene/scene_unittests.cc index c72e8f90c68f9..3388c7062b54f 100644 --- a/impeller/scene/scene_unittests.cc +++ b/impeller/scene/scene_unittests.cc @@ -16,7 +16,7 @@ #include "impeller/scene/scene.h" #include "impeller/scene/static_mesh_entity.h" -#include "third_party/tinygltf/tiny_gltf.h" +// #include "third_party/tinygltf/tiny_gltf.h" namespace impeller { namespace scene { From 900ed2f1af5a1768ad63e214a557ca054bb82e45 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 16 Nov 2022 22:57:26 -0800 Subject: [PATCH 7/9] Licenses --- ci/licenses_golden/licenses_flutter | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 83d3b324cae10..9883e26b0455a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1576,6 +1576,21 @@ FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_playground.h FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_unittests.cc FILE: ../../../flutter/impeller/runtime_stage/runtime_types.cc FILE: ../../../flutter/impeller/runtime_stage/runtime_types.h +FILE: ../../../flutter/impeller/scene/camera.cc +FILE: ../../../flutter/impeller/scene/camera.h +FILE: ../../../flutter/impeller/scene/geometry.cc +FILE: ../../../flutter/impeller/scene/geometry.h +FILE: ../../../flutter/impeller/scene/material.cc +FILE: ../../../flutter/impeller/scene/material.h +FILE: ../../../flutter/impeller/scene/scene.cc +FILE: ../../../flutter/impeller/scene/scene.h +FILE: ../../../flutter/impeller/scene/scene_encoder.cc +FILE: ../../../flutter/impeller/scene/scene_encoder.h +FILE: ../../../flutter/impeller/scene/scene_entity.cc +FILE: ../../../flutter/impeller/scene/scene_entity.h +FILE: ../../../flutter/impeller/scene/scene_unittests.cc +FILE: ../../../flutter/impeller/scene/static_mesh_entity.cc +FILE: ../../../flutter/impeller/scene/static_mesh_entity.h FILE: ../../../flutter/impeller/tessellator/c/tessellator.cc FILE: ../../../flutter/impeller/tessellator/c/tessellator.h FILE: ../../../flutter/impeller/tessellator/dart/lib/tessellator.dart From de7ddce8b04ef2a86490fb95557f927f4f9382a9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 16 Nov 2022 22:58:31 -0800 Subject: [PATCH 8/9] Format --- impeller/scene/scene_encoder.h | 2 -- impeller/scene/static_mesh_entity.cc | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/impeller/scene/scene_encoder.h b/impeller/scene/scene_encoder.h index f026516abb6b4..2b8f15cab1cdd 100644 --- a/impeller/scene/scene_encoder.h +++ b/impeller/scene/scene_encoder.h @@ -16,8 +16,6 @@ namespace scene { class Scene; class SceneEncoder { - - private: SceneEncoder(); diff --git a/impeller/scene/static_mesh_entity.cc b/impeller/scene/static_mesh_entity.cc index 1b092dd0146b4..493d342b87e0e 100644 --- a/impeller/scene/static_mesh_entity.cc +++ b/impeller/scene/static_mesh_entity.cc @@ -21,7 +21,8 @@ void StaticMeshEntity::SetMaterial(std::shared_ptr material) { } // |SceneEntity| -bool StaticMeshEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const { +bool StaticMeshEntity::OnRender(SceneEncoder& encoder, + const Camera& camera) const { return true; } From d26e156be8480375dd1e18758e99d0676ab0edc2 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 16 Nov 2022 23:48:56 -0800 Subject: [PATCH 9/9] Fix move --- impeller/scene/scene_entity.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/scene/scene_entity.cc b/impeller/scene/scene_entity.cc index 9b7b17a574251..4183849a9e865 100644 --- a/impeller/scene/scene_entity.cc +++ b/impeller/scene/scene_entity.cc @@ -51,7 +51,7 @@ bool SceneEntity::Add(const std::shared_ptr& child) { return false; } - children_.push_back(std::move(child)); + children_.push_back(child); child->parent_ = this; return true; }