Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5429243

Browse files
authored
[Impeller Scene] Render imported meshes (#38097)
* [Impeller Scene] Render imported meshes * Address comments
1 parent 185e2f3 commit 5429243

12 files changed

Lines changed: 239 additions & 22 deletions

File tree

impeller/fixtures/BUILD.gn

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impeller_shaders("shader_fixtures") {
3333
}
3434
}
3535

36-
scenec("geometry_fixtures") {
36+
scenec("scene_fixtures") {
3737
geometry = [ "flutter_logo.glb" ]
3838
type = "gltf"
3939
}
@@ -85,16 +85,20 @@ test_fixtures("file_fixtures") {
8585
fixtures += [ "/System/Library/Fonts/Apple Color Emoji.ttc" ]
8686
}
8787
fixtures +=
88-
filter_include(get_target_outputs(":runtime_stages"), [ "*.iplr" ])
89-
deps = [ ":runtime_stages" ]
88+
filter_include(get_target_outputs(":runtime_stages"), [ "*.iplr" ]) +
89+
filter_include(get_target_outputs(":scene_fixtures"), [ "*.ipscene" ])
90+
deps = [
91+
":runtime_stages",
92+
":scene_fixtures",
93+
]
9094
}
9195

9296
group("fixtures") {
9397
testonly = true
9498

9599
public_deps = [
96100
":file_fixtures",
97-
":geometry_fixtures",
101+
":scene_fixtures",
98102
":shader_fixtures",
99103
]
100104
}

impeller/scene/BUILD.gn

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impeller_component("scene") {
2626

2727
public_deps = [
2828
"../renderer",
29+
"importer:importer_flatbuffers",
2930
"shaders",
3031
]
3132

@@ -42,7 +43,5 @@ impeller_component("scene_unittests") {
4243
"../fixtures",
4344
"../playground:playground_test",
4445
"//flutter/testing:testing_lib",
45-
46-
#"//third_party/tinygltf",
4746
]
4847
}

impeller/scene/geometry.cc

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44

55
#include "impeller/scene/geometry.h"
66

7+
#include <iostream>
78
#include <memory>
9+
#include <ostream>
810

911
#include "impeller/geometry/point.h"
1012
#include "impeller/geometry/vector.h"
13+
#include "impeller/renderer/device_buffer_descriptor.h"
1114
#include "impeller/renderer/formats.h"
15+
#include "impeller/renderer/vertex_buffer.h"
1216
#include "impeller/renderer/vertex_buffer_builder.h"
17+
#include "impeller/scene/importer/scene_flatbuffers.h"
1318
#include "impeller/scene/shaders/geometry.vert.h"
19+
#include "third_party/flatbuffers/include/flatbuffers/vector.h"
1420

1521
namespace impeller {
1622
namespace scene {
@@ -19,16 +25,78 @@ namespace scene {
1925
/// Geometry
2026
///
2127

28+
Geometry::~Geometry() = default;
29+
2230
std::shared_ptr<CuboidGeometry> Geometry::MakeCuboid(Vector3 size) {
2331
auto result = std::make_shared<CuboidGeometry>();
2432
result->SetSize(size);
2533
return result;
2634
}
2735

36+
std::shared_ptr<VertexBufferGeometry> Geometry::MakeVertexBuffer(
37+
VertexBuffer vertex_buffer) {
38+
auto result = std::make_shared<VertexBufferGeometry>();
39+
result->SetVertexBuffer(std::move(vertex_buffer));
40+
return result;
41+
}
42+
43+
std::shared_ptr<VertexBufferGeometry> Geometry::MakeFromFBMesh(
44+
const fb::StaticMesh& mesh,
45+
Allocator& allocator) {
46+
IndexType index_type;
47+
switch (mesh.indices()->type()) {
48+
case fb::IndicesType::k16Bit:
49+
index_type = IndexType::k16bit;
50+
break;
51+
case fb::IndicesType::k32Bit:
52+
index_type = IndexType::k32bit;
53+
break;
54+
}
55+
56+
const size_t vertices_bytes = mesh.vertices()->size() * sizeof(fb::Vertex);
57+
const size_t indices_bytes = mesh.indices()->data()->size();
58+
if (vertices_bytes == 0 || indices_bytes == 0) {
59+
return nullptr;
60+
}
61+
62+
DeviceBufferDescriptor buffer_desc;
63+
buffer_desc.size = vertices_bytes * indices_bytes;
64+
buffer_desc.storage_mode = StorageMode::kHostVisible;
65+
66+
auto buffer = allocator.CreateBuffer(buffer_desc);
67+
buffer->SetLabel("Mesh vertices+indices");
68+
69+
const uint8_t* vertices_start =
70+
reinterpret_cast<const uint8_t*>(mesh.vertices()->Get(0));
71+
const uint8_t* indices_start =
72+
reinterpret_cast<const uint8_t*>(mesh.indices()->data()->Data());
73+
74+
if (!buffer->CopyHostBuffer(vertices_start, Range(0, vertices_bytes))) {
75+
return nullptr;
76+
}
77+
if (!buffer->CopyHostBuffer(indices_start, Range(0, indices_bytes),
78+
vertices_bytes)) {
79+
return nullptr;
80+
}
81+
82+
VertexBuffer vertex_buffer = {
83+
.vertex_buffer = {.buffer = buffer, .range = Range(0, vertices_bytes)},
84+
.index_buffer = {.buffer = buffer,
85+
.range = Range(vertices_bytes, indices_bytes)},
86+
.index_count = mesh.indices()->count(),
87+
.index_type = index_type,
88+
};
89+
return MakeVertexBuffer(std::move(vertex_buffer));
90+
}
91+
2892
//------------------------------------------------------------------------------
2993
/// CuboidGeometry
3094
///
3195

96+
CuboidGeometry::CuboidGeometry() = default;
97+
98+
CuboidGeometry::~CuboidGeometry() = default;
99+
32100
void CuboidGeometry::SetSize(Vector3 size) {
33101
size_ = size;
34102
}
@@ -38,15 +106,37 @@ VertexBuffer CuboidGeometry::GetVertexBuffer(Allocator& allocator) const {
38106
// Layout: position, normal, tangent, uv
39107
builder.AddVertices({
40108
// Front.
41-
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0)},
42-
{Vector3(1, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 0)},
43-
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1)},
44-
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1)},
45-
{Vector3(0, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 1)},
46-
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0)},
109+
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
110+
Color::White()},
111+
{Vector3(1, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 0),
112+
Color::White()},
113+
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
114+
Color::White()},
115+
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
116+
Color::White()},
117+
{Vector3(0, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 1),
118+
Color::White()},
119+
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
120+
Color::White()},
47121
});
48122
return builder.CreateVertexBuffer(allocator);
49123
}
50124

125+
//------------------------------------------------------------------------------
126+
/// VertexBufferGeometry
127+
///
128+
129+
VertexBufferGeometry::VertexBufferGeometry() = default;
130+
131+
VertexBufferGeometry::~VertexBufferGeometry() = default;
132+
133+
void VertexBufferGeometry::SetVertexBuffer(VertexBuffer vertex_buffer) {
134+
vertex_buffer_ = std::move(vertex_buffer);
135+
}
136+
137+
VertexBuffer VertexBufferGeometry::GetVertexBuffer(Allocator& allocator) const {
138+
return vertex_buffer_;
139+
}
140+
51141
} // namespace scene
52142
} // namespace impeller

impeller/scene/geometry.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,67 @@
66

77
#include <memory>
88

9+
#include "flutter/fml/macros.h"
910
#include "impeller/geometry/vector.h"
1011
#include "impeller/renderer/allocator.h"
12+
#include "impeller/renderer/device_buffer.h"
1113
#include "impeller/renderer/vertex_buffer.h"
14+
#include "impeller/scene/importer/scene_flatbuffers.h"
1215

1316
namespace impeller {
1417
namespace scene {
1518

1619
class CuboidGeometry;
20+
class VertexBufferGeometry;
1721

1822
class Geometry {
1923
public:
24+
virtual ~Geometry();
25+
2026
static std::shared_ptr<CuboidGeometry> MakeCuboid(Vector3 size);
2127

28+
static std::shared_ptr<VertexBufferGeometry> MakeVertexBuffer(
29+
VertexBuffer vertex_buffer);
30+
31+
static std::shared_ptr<VertexBufferGeometry> MakeFromFBMesh(
32+
const fb::StaticMesh& mesh,
33+
Allocator& allocator);
34+
2235
virtual VertexBuffer GetVertexBuffer(Allocator& allocator) const = 0;
2336
};
2437

2538
class CuboidGeometry final : public Geometry {
2639
public:
40+
CuboidGeometry();
41+
42+
~CuboidGeometry() override;
43+
2744
void SetSize(Vector3 size);
2845

46+
// |Geometry|
2947
VertexBuffer GetVertexBuffer(Allocator& allocator) const override;
3048

3149
private:
3250
Vector3 size_;
51+
52+
FML_DISALLOW_COPY_AND_ASSIGN(CuboidGeometry);
53+
};
54+
55+
class VertexBufferGeometry final : public Geometry {
56+
public:
57+
VertexBufferGeometry();
58+
59+
~VertexBufferGeometry() override;
60+
61+
void SetVertexBuffer(VertexBuffer vertex_buffer);
62+
63+
// |Geometry|
64+
VertexBuffer GetVertexBuffer(Allocator& allocator) const override;
65+
66+
private:
67+
VertexBuffer vertex_buffer_;
68+
69+
FML_DISALLOW_COPY_AND_ASSIGN(VertexBufferGeometry);
3370
};
3471

3572
} // namespace scene

impeller/scene/importer/importer_gltf.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,28 @@ static bool ProcessStaticMesh(const tinygltf::Model& gltf,
108108

109109
auto index_accessor = gltf.accessors[primitive.indices];
110110
auto index_view = gltf.bufferViews[index_accessor.bufferView];
111-
static_mesh.indices.resize(index_accessor.count);
111+
112+
auto indices = std::make_unique<fb::IndicesT>();
113+
114+
switch (index_accessor.componentType) {
115+
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
116+
indices->type = fb::IndicesType::k16Bit;
117+
break;
118+
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
119+
indices->type = fb::IndicesType::k32Bit;
120+
break;
121+
default:
122+
std::cerr << "Mesh primitive has unsupported index type "
123+
<< index_accessor.componentType << ". Skipping.";
124+
return false;
125+
}
126+
indices->count = index_accessor.count;
127+
indices->data.resize(index_view.byteLength);
112128
const auto* index_buffer =
113129
&gltf.buffers[index_view.buffer].data[index_view.byteOffset];
114-
std::memcpy(static_mesh.indices.data(), index_buffer, index_view.byteLength);
130+
std::memcpy(indices->data.data(), index_buffer, indices->data.size());
131+
132+
static_mesh.indices = std::move(indices);
115133

116134
return true;
117135
}

impeller/scene/importer/importer_unittests.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ TEST(ImporterTest, CanParseGLTF) {
2828

2929
ASSERT_EQ(node.meshes.size(), 1u);
3030
auto& mesh = *node.meshes[0];
31-
ASSERT_EQ(mesh.indices.size(), 918u);
31+
ASSERT_EQ(mesh.indices->count, 918u);
32+
33+
uint16_t first_index =
34+
*reinterpret_cast<uint16_t*>(mesh.indices->data.data());
35+
ASSERT_EQ(first_index, 45u);
3236

3337
ASSERT_EQ(mesh.vertices.size(), 260u);
3438
auto& vertex = mesh.vertices[0];

impeller/scene/importer/scene.fbs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ struct Matrix {
3333
m: [float:16];
3434
}
3535

36+
// This attribute layout is expected to be identical to that within
37+
// `impeller/scene/shaders/geometry.vert`.
3638
struct Vertex {
3739
position: Vec3;
3840
normal: Vec3;
@@ -41,6 +43,17 @@ struct Vertex {
4143
color: Color;
4244
}
4345

46+
enum IndicesType:byte {
47+
k16Bit,
48+
k32Bit,
49+
}
50+
51+
table Indices {
52+
data: [ubyte];
53+
count: uint32;
54+
type: IndicesType;
55+
}
56+
4457
table Texture {
4558
// TODO(bdero): Allow optional image data embedding.
4659
uri: string;
@@ -54,7 +67,7 @@ table Material {
5467

5568
table StaticMesh {
5669
vertices: [Vertex];
57-
indices: [uint32];
70+
indices: Indices;
5871
material: Material;
5972
}
6073

impeller/scene/importer/scenec_main.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "impeller/base/strings.h"
1414
#include "impeller/compiler/utilities.h"
1515
#include "impeller/scene/importer/importer.h"
16+
#include "impeller/scene/importer/scene_flatbuffers.h"
1617
#include "impeller/scene/importer/switches.h"
1718
#include "impeller/scene/importer/types.h"
1819

@@ -74,7 +75,7 @@ bool Main(const fml::CommandLine& command_line) {
7475
}
7576

7677
flatbuffers::FlatBufferBuilder builder;
77-
builder.Finish(fb::Scene::Pack(builder, &scene));
78+
builder.Finish(fb::Scene::Pack(builder, &scene), fb::SceneIdentifier());
7879

7980
auto output_file_name = std::filesystem::absolute(
8081
std::filesystem::current_path() / switches.output_file_name);

0 commit comments

Comments
 (0)