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