Flutter Impeller
geometry.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <memory>
8 #include <ostream>
9 
11 #include "impeller/core/formats.h"
18 #include "impeller/scene/importer/scene_flatbuffers.h"
19 #include "impeller/scene/shaders/skinned.vert.h"
20 #include "impeller/scene/shaders/unskinned.vert.h"
21 
22 namespace impeller {
23 namespace scene {
24 
25 //------------------------------------------------------------------------------
26 /// Geometry
27 ///
28 
29 Geometry::~Geometry() = default;
30 
31 std::shared_ptr<CuboidGeometry> Geometry::MakeCuboid(Vector3 size) {
32  auto result = std::make_shared<CuboidGeometry>();
33  result->SetSize(size);
34  return result;
35 }
36 
37 std::shared_ptr<Geometry> Geometry::MakeVertexBuffer(VertexBuffer vertex_buffer,
38  bool is_skinned) {
39  if (is_skinned) {
40  auto result = std::make_shared<SkinnedVertexBufferGeometry>();
41  result->SetVertexBuffer(std::move(vertex_buffer));
42  return result;
43  } else {
44  auto result = std::make_shared<UnskinnedVertexBufferGeometry>();
45  result->SetVertexBuffer(std::move(vertex_buffer));
46  return result;
47  }
48 }
49 
50 std::shared_ptr<Geometry> Geometry::MakeFromFlatbuffer(
51  const fb::MeshPrimitive& mesh,
52  Allocator& allocator) {
53  IndexType index_type;
54  switch (mesh.indices()->type()) {
55  case fb::IndexType::k16Bit:
56  index_type = IndexType::k16bit;
57  break;
58  case fb::IndexType::k32Bit:
59  index_type = IndexType::k32bit;
60  break;
61  }
62 
63  const uint8_t* vertices_start;
64  size_t vertices_bytes;
65  bool is_skinned;
66 
67  switch (mesh.vertices_type()) {
68  case fb::VertexBuffer::UnskinnedVertexBuffer: {
69  const auto* vertices =
70  mesh.vertices_as_UnskinnedVertexBuffer()->vertices();
71  vertices_start = reinterpret_cast<const uint8_t*>(vertices->Get(0));
72  vertices_bytes = vertices->size() * sizeof(fb::Vertex);
73  is_skinned = false;
74  break;
75  }
76  case fb::VertexBuffer::SkinnedVertexBuffer: {
77  const auto* vertices = mesh.vertices_as_SkinnedVertexBuffer()->vertices();
78  vertices_start = reinterpret_cast<const uint8_t*>(vertices->Get(0));
79  vertices_bytes = vertices->size() * sizeof(fb::SkinnedVertex);
80  is_skinned = true;
81  break;
82  }
83  case fb::VertexBuffer::NONE:
84  VALIDATION_LOG << "Invalid vertex buffer type.";
85  return nullptr;
86  }
87 
88  const uint8_t* indices_start =
89  reinterpret_cast<const uint8_t*>(mesh.indices()->data()->Data());
90 
91  const size_t indices_bytes = mesh.indices()->data()->size();
92  if (vertices_bytes == 0 || indices_bytes == 0) {
93  return nullptr;
94  }
95 
96  DeviceBufferDescriptor buffer_desc;
97  buffer_desc.size = vertices_bytes + indices_bytes;
99 
100  auto buffer = allocator.CreateBuffer(buffer_desc);
101  buffer->SetLabel("Mesh vertices+indices");
102 
103  if (!buffer->CopyHostBuffer(vertices_start, Range(0, vertices_bytes))) {
104  return nullptr;
105  }
106  if (!buffer->CopyHostBuffer(indices_start, Range(0, indices_bytes),
107  vertices_bytes)) {
108  return nullptr;
109  }
110 
111  VertexBuffer vertex_buffer = {
112  .vertex_buffer = {.buffer = buffer, .range = Range(0, vertices_bytes)},
113  .index_buffer = {.buffer = buffer,
114  .range = Range(vertices_bytes, indices_bytes)},
115  .vertex_count = mesh.indices()->count(),
116  .index_type = index_type,
117  };
118  return MakeVertexBuffer(std::move(vertex_buffer), is_skinned);
119 }
120 
121 void Geometry::SetJointsTexture(const std::shared_ptr<Texture>& texture) {}
122 
123 //------------------------------------------------------------------------------
124 /// CuboidGeometry
125 ///
126 
128 
130 
132  size_ = size;
133 }
134 
135 // |Geometry|
138 }
139 
140 // |Geometry|
143  // Layout: position, normal, tangent, uv
144  builder.AddVertices({
145  // Front.
146  {Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
147  Color::White()},
148  {Vector3(1, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 0),
149  Color::White()},
150  {Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
151  Color::White()},
152  {Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
153  Color::White()},
154  {Vector3(0, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 1),
155  Color::White()},
156  {Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
157  Color::White()},
158  });
159  return builder.CreateVertexBuffer(allocator);
160 }
161 
162 // |Geometry|
163 void CuboidGeometry::BindToCommand(const SceneContext& scene_context,
164  HostBuffer& buffer,
165  const Matrix& transform,
166  RenderPass& pass) const {
167  pass.SetVertexBuffer(
168  GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
169 
170  UnskinnedVertexShader::FrameInfo info;
171  info.mvp = transform;
172  UnskinnedVertexShader::BindFrameInfo(pass, buffer.EmplaceUniform(info));
173 }
174 
175 //------------------------------------------------------------------------------
176 /// UnskinnedVertexBufferGeometry
177 ///
178 
180 
182 
184  VertexBuffer vertex_buffer) {
185  vertex_buffer_ = std::move(vertex_buffer);
186 }
187 
188 // |Geometry|
191 }
192 
193 // |Geometry|
195  Allocator& allocator) const {
196  return vertex_buffer_;
197 }
198 
199 // |Geometry|
201  const SceneContext& scene_context,
202  HostBuffer& buffer,
203  const Matrix& transform,
204  RenderPass& pass) const {
205  pass.SetVertexBuffer(
206  GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
207 
208  UnskinnedVertexShader::FrameInfo info;
209  info.mvp = transform;
210  UnskinnedVertexShader::BindFrameInfo(pass, buffer.EmplaceUniform(info));
211 }
212 
213 //------------------------------------------------------------------------------
214 /// SkinnedVertexBufferGeometry
215 ///
216 
218 
220 
222  vertex_buffer_ = std::move(vertex_buffer);
223 }
224 
225 // |Geometry|
227  return GeometryType::kSkinned;
228 }
229 
230 // |Geometry|
232  Allocator& allocator) const {
233  return vertex_buffer_;
234 }
235 
236 // |Geometry|
238  const SceneContext& scene_context,
239  HostBuffer& buffer,
240  const Matrix& transform,
241  RenderPass& pass) const {
242  pass.SetVertexBuffer(
243  GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
244 
245  SamplerDescriptor sampler_desc;
246  sampler_desc.min_filter = MinMagFilter::kNearest;
247  sampler_desc.mag_filter = MinMagFilter::kNearest;
248  sampler_desc.mip_filter = MipFilter::kNearest;
250  sampler_desc.label = "NN Repeat";
251 
252  SkinnedVertexShader::BindJointsTexture(
253  pass,
254  joints_texture_ ? joints_texture_ : scene_context.GetPlaceholderTexture(),
255  scene_context.GetContext()->GetSamplerLibrary()->GetSampler(
256  sampler_desc));
257 
258  SkinnedVertexShader::FrameInfo info;
259  info.mvp = transform;
260  info.enable_skinning = joints_texture_ ? 1 : 0;
261  info.joint_texture_size =
262  joints_texture_ ? joints_texture_->GetSize().width : 1;
263  SkinnedVertexShader::BindFrameInfo(pass, buffer.EmplaceUniform(info));
264 }
265 
266 // |Geometry|
268  const std::shared_ptr<Texture>& texture) {
269  joints_texture_ = texture;
270 }
271 } // namespace scene
272 } // namespace impeller
impeller::scene::SkinnedVertexBufferGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, RenderPass &pass) const override
Definition: geometry.cc:237
impeller::scene::SkinnedVertexBufferGeometry::~SkinnedVertexBufferGeometry
~SkinnedVertexBufferGeometry() override
impeller::scene::Geometry::SetJointsTexture
virtual void SetJointsTexture(const std::shared_ptr< Texture > &texture)
Definition: geometry.cc:121
point.h
impeller::IndexType::k16bit
@ k16bit
impeller::scene::Geometry::MakeCuboid
static std::shared_ptr< CuboidGeometry > MakeCuboid(Vector3 size)
Definition: geometry.cc:31
vertex_buffer.h
impeller::scene::GeometryType::kUnskinned
@ kUnskinned
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
impeller::HostBuffer
Definition: host_buffer.h:28
impeller::VertexBuffer
Definition: vertex_buffer.h:13
impeller::scene::UnskinnedVertexBufferGeometry::UnskinnedVertexBufferGeometry
UnskinnedVertexBufferGeometry()
impeller::scene::SkinnedVertexBufferGeometry::SkinnedVertexBufferGeometry
SkinnedVertexBufferGeometry()
impeller::scene::UnskinnedVertexBufferGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:189
formats.h
impeller::scene::CuboidGeometry::~CuboidGeometry
~CuboidGeometry() override
impeller::scene::SceneContext::GetPlaceholderTexture
std::shared_ptr< Texture > GetPlaceholderTexture() const
Definition: scene_context.cc:110
impeller::RenderPass::SetVertexBuffer
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:123
impeller::scene::CuboidGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:136
impeller::scene::UnskinnedVertexBufferGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:194
impeller::DeviceBufferDescriptor::size
size_t size
Definition: device_buffer_descriptor.h:16
impeller::VertexBufferBuilder::AddVertices
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
Definition: vertex_buffer_builder.h:70
impeller::scene::SceneContext
Definition: scene_context.h:41
impeller::IndexType::k32bit
@ k32bit
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:14
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:17
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::MipFilter::kNearest
@ kNearest
Sample from the nearest mip level.
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::scene::SkinnedVertexBufferGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:226
impeller::scene::SkinnedVertexBufferGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:231
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
render_pass.h
impeller::Allocator::CreateBuffer
std::shared_ptr< DeviceBuffer > CreateBuffer(const DeviceBufferDescriptor &desc)
Definition: allocator.cc:44
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:24
impeller::scene::UnskinnedVertexBufferGeometry::SetVertexBuffer
void SetVertexBuffer(VertexBuffer vertex_buffer)
Definition: geometry.cc:183
impeller::IndexType
IndexType
Definition: formats.h:344
impeller::DeviceBufferDescriptor::storage_mode
StorageMode storage_mode
Definition: device_buffer_descriptor.h:15
impeller::scene::Geometry::~Geometry
virtual ~Geometry()
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:20
impeller::scene::CuboidGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, RenderPass &pass) const override
Definition: geometry.cc:163
impeller::Color::White
static constexpr Color White()
Definition: color.h:256
impeller::Allocator
An object that allocates device memory.
Definition: allocator.h:22
impeller::scene::Geometry::MakeFromFlatbuffer
static std::shared_ptr< Geometry > MakeFromFlatbuffer(const fb::MeshPrimitive &mesh, Allocator &allocator)
Definition: geometry.cc:50
impeller::scene::Geometry::MakeVertexBuffer
static std::shared_ptr< Geometry > MakeVertexBuffer(VertexBuffer vertex_buffer, bool is_skinned)
Definition: geometry.cc:37
impeller::scene::UnskinnedVertexBufferGeometry::~UnskinnedVertexBufferGeometry
~UnskinnedVertexBufferGeometry() override
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:18
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
Definition: vertex_buffer_builder.h:84
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
sampler_descriptor.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::scene::GeometryType
GeometryType
Definition: pipeline_key.h:13
impeller::scene::CuboidGeometry::CuboidGeometry
CuboidGeometry()
impeller::scene::GeometryType::kSkinned
@ kSkinned
impeller::Range
Definition: range.h:14
vector.h
impeller::scene::SkinnedVertexBufferGeometry::SetVertexBuffer
void SetVertexBuffer(VertexBuffer vertex_buffer)
Definition: geometry.cc:221
impeller::scene::UnskinnedVertexBufferGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, RenderPass &pass) const override
Definition: geometry.cc:200
impeller::scene::SceneContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: scene_context.cc:106
impeller::BufferView::buffer
std::shared_ptr< const DeviceBuffer > buffer
Definition: buffer_view.h:16
impeller::HostBuffer::EmplaceUniform
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition: host_buffer.h:50
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
geometry.h
device_buffer_descriptor.h
impeller::scene::CuboidGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:141
impeller::scene::SkinnedVertexBufferGeometry::SetJointsTexture
void SetJointsTexture(const std::shared_ptr< Texture > &texture) override
Definition: geometry.cc:267
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Vector3
Definition: vector.h:20
vertex_buffer_builder.h
impeller::scene::CuboidGeometry::SetSize
void SetSize(Vector3 size)
Definition: geometry.cc:131
impeller::SamplerAddressMode::kRepeat
@ kRepeat