| 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
5 #include "impeller/scene/geometry.h"
6
7 #include <memory>
8 #include <ostream>
9
10 #include "impeller/core/device_buffer_descriptor.h"
11 #include "impeller/core/formats.h"
12 #include "impeller/core/sampler_descriptor.h"
13 #include "impeller/core/vertex_buffer.h"
14 #include "impeller/geometry/point.h"
15 #include "impeller/geometry/vector.h"
16 #include "impeller/renderer/render_pass.h"
17 #include "impeller/renderer/vertex_buffer_builder.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;
98 buffer_desc.storage_mode = StorageMode::kHostVisible;
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
127 CuboidGeometry::CuboidGeometry() = default;
128
129 CuboidGeometry::~CuboidGeometry() = default;
130
131 void CuboidGeometry::SetSize(Vector3 size) {
132 size_ = size;
133 }
134
135 // |Geometry|
136 GeometryType CuboidGeometry::GetGeometryType() const {
137 return GeometryType::kUnskinned;
138 }
139
140 // |Geometry|
141 VertexBuffer CuboidGeometry::GetVertexBuffer(Allocator& allocator) const {
142 VertexBufferBuilder<UnskinnedVertexShader::PerVertexData, uint16_t> builder;
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
179 UnskinnedVertexBufferGeometry::UnskinnedVertexBufferGeometry() = default;
180
181 UnskinnedVertexBufferGeometry::~UnskinnedVertexBufferGeometry() = default;
182
183 void UnskinnedVertexBufferGeometry::SetVertexBuffer(
184 VertexBuffer vertex_buffer) {
185 vertex_buffer_ = std::move(vertex_buffer);
186 }
187
188 // |Geometry|
189 GeometryType UnskinnedVertexBufferGeometry::GetGeometryType() const {
190 return GeometryType::kUnskinned;
191 }
192
193 // |Geometry|
194 VertexBuffer UnskinnedVertexBufferGeometry::GetVertexBuffer(
195 Allocator& allocator) const {
196 return vertex_buffer_;
197 }
198
199 // |Geometry|
200 void UnskinnedVertexBufferGeometry::BindToCommand(
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
217 SkinnedVertexBufferGeometry::SkinnedVertexBufferGeometry() = default;
218
219 SkinnedVertexBufferGeometry::~SkinnedVertexBufferGeometry() = default;
220
221 void SkinnedVertexBufferGeometry::SetVertexBuffer(VertexBuffer vertex_buffer) {
222 vertex_buffer_ = std::move(vertex_buffer);
223 }
224
225 // |Geometry|
226 GeometryType SkinnedVertexBufferGeometry::GetGeometryType() const {
227 return GeometryType::kSkinned;
228 }
229
230 // |Geometry|
231 VertexBuffer SkinnedVertexBufferGeometry::GetVertexBuffer(
232 Allocator& allocator) const {
233 return vertex_buffer_;
234 }
235
236 // |Geometry|
237 void SkinnedVertexBufferGeometry::BindToCommand(
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;
249 sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
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|
267 void SkinnedVertexBufferGeometry::SetJointsTexture(
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