@@ -19,36 +19,43 @@ struct DirLightSSBO {
19
19
};
20
20
} // namespace
21
21
22
+ void SceneRenderer::Instances::rotate () {
23
+ for (auto & buffer : buffers) { buffer.rotate (); }
24
+ index = 0 ;
25
+ }
26
+
22
27
SceneRenderer::SceneRenderer (Gfx const & gfx)
23
28
: m_gfx(gfx), m_sampler(gfx), m_view_proj(gfx, Buffer::Type::eUniform), m_dir_lights(gfx, Buffer::Type::eStorage),
24
29
m_white (gfx, m_sampler.sampler(), Bmp1x1{0xff_B, 0xff_B, 0xff_B, 0xff_B}.view(), Texture::CreateInfo{.mip_mapped = false }),
25
30
m_black (gfx, m_sampler.sampler(), Bmp1x1{0x0_B, 0x0_B, 0x0_B, 0xff_B}.view(), Texture::CreateInfo{.mip_mapped = false }) {}
26
31
27
32
void SceneRenderer::render (Scene const & scene, Ptr<Skybox const > skybox, Renderer& renderer, vk::CommandBuffer cb) {
28
33
m_scene = &scene;
34
+ m_info = {};
29
35
write_view (renderer.framebuffer_extent ());
30
36
if (skybox) { render (renderer, cb, *skybox); }
31
37
for (auto const & node : m_scene->roots ()) { render (renderer, cb, m_scene->resources ().nodes [node]); }
38
+ m_instances.rotate ();
32
39
}
33
40
34
41
void SceneRenderer::write_view (glm::vec2 const extent) {
35
42
auto const & cam_node = m_scene->camera ();
36
43
auto const cam_id = cam_node.find <Camera>();
37
44
assert (cam_id);
38
45
auto const & cam = m_scene->resources ().cameras [*cam_id];
39
- struct {
46
+ struct ViewSSBO {
40
47
glm::mat4x4 mat_v;
41
48
glm::mat4x4 mat_p;
42
49
glm::vec4 vpos_exposure;
43
- } vp {
50
+ } view {
44
51
.mat_v = cam.view (cam_node.transform ),
45
52
.mat_p = cam.projection (extent),
46
53
.vpos_exposure = {cam_node.transform .position (), cam.exposure },
47
54
};
48
- m_view_proj.write (&vp, sizeof (vp) );
55
+ m_view_proj.write <ViewSSBO>({&view, 1 } );
49
56
auto dir_lights = FlexArray<DirLightSSBO, 4 >{};
50
57
for (auto const & light : m_scene->lights .dir_lights .span ()) { dir_lights.insert (DirLightSSBO::make (light)); }
51
- m_dir_lights.write (dir_lights.span (). data (), dir_lights. span (). size_bytes () );
58
+ m_dir_lights.write (dir_lights.span ());
52
59
}
53
60
54
61
void SceneRenderer::update_view (Pipeline& out_pipeline) const {
@@ -58,7 +65,7 @@ void SceneRenderer::update_view(Pipeline& out_pipeline) const {
58
65
out_pipeline.bind (set0);
59
66
}
60
67
61
- std::span<glm::mat4x4 const > SceneRenderer::make_instances (Node const & node, glm::mat4x4 const & parent) const {
68
+ std::span<glm::mat4x4 const > SceneRenderer::make_instance_mats (Node const & node, glm::mat4x4 const & parent) {
62
69
m_instance_mats.clear ();
63
70
if (node.instances .empty ()) {
64
71
m_instance_mats.reserve (1 );
@@ -70,40 +77,63 @@ std::span<glm::mat4x4 const> SceneRenderer::make_instances(Node const& node, glm
70
77
return m_instance_mats;
71
78
}
72
79
73
- void SceneRenderer::render (Renderer& renderer, vk::CommandBuffer cb, Skybox const & skybox) const {
74
- auto state = m_scene->pipeline_state ;
75
- state.depth_test = false ;
76
- auto pipeline = renderer.bind_pipeline (cb, state, " skybox" );
80
+ void SceneRenderer::render (Renderer& renderer, vk::CommandBuffer cb, Skybox const & skybox) {
81
+ auto pipeline = renderer.bind_pipeline (cb, {.depth_test = false }, " skybox" );
77
82
pipeline.set_line_width (1 .0f );
78
83
update_view (pipeline);
79
84
auto & set1 = pipeline.next_set (1 );
80
85
set1.update (0 , skybox.cubemap ().descriptor_image ());
81
86
pipeline.bind (set1);
82
- auto const instance = glm::translate (matrix_identity_v, m_scene->camera ().transform .position ());
83
- renderer. draw (pipeline , skybox.static_mesh (), {&instance, 1 });
87
+ auto const mat = glm::translate (matrix_identity_v, m_scene->camera ().transform .position ());
88
+ draw (cb , skybox.static_mesh (), {&mat, 1u });
84
89
}
85
90
86
- void SceneRenderer::render (Renderer& renderer, vk::CommandBuffer cb, Node const & node, glm::mat4 parent) const {
91
+ void SceneRenderer::render (Renderer& renderer, vk::CommandBuffer cb, Node const & node, glm::mat4 parent) {
87
92
auto const & resources = m_scene->resources ();
88
93
if (auto mesh_id = node.find <Mesh>()) {
89
94
static auto const s_default_material = Material{std::make_unique<LitMaterial>()};
90
95
auto const & mesh = resources.meshes [*mesh_id];
91
96
for (auto const & primitive : mesh.primitives ) {
92
97
auto const & material = primitive.material ? resources.materials [primitive.material ->value ()] : static_cast <Material const &>(s_default_material);
93
- auto pipeline = renderer.bind_pipeline (cb, m_scene->pipeline_state , material.shader_id ());
94
- pipeline.set_line_width (m_scene->pipeline_state .line_width );
98
+ auto const & static_mesh = resources.static_meshes [primitive.static_mesh ];
99
+
100
+ auto const mode = m_scene->render_mode .type == RenderMode::Type::eWireframe ? vk::PolygonMode::eLine : vk::PolygonMode::eFill;
101
+ auto pipeline = renderer.bind_pipeline (cb, {.mode = mode, .topology = static_mesh.topology ()}, material.shader_id ());
102
+ pipeline.set_line_width (m_scene->render_mode .line_width );
95
103
96
104
update_view (pipeline);
97
105
auto const store = TextureStore{resources.textures , m_white, m_black};
98
106
material.write_sets (pipeline, store);
99
107
100
- auto const & static_mesh = resources.static_meshes [primitive.static_mesh ];
101
- auto const instances = make_instances (node, parent);
102
- renderer.draw (pipeline, static_mesh, instances);
108
+ auto const mats = make_instance_mats (node, parent);
109
+ draw (cb, static_mesh, mats);
103
110
}
104
111
}
105
112
106
113
parent = parent * node.transform .matrix ();
107
114
for (auto const & id : node.children ) { render (renderer, cb, m_scene->resources ().nodes [id], parent); }
108
115
}
116
+
117
+ void SceneRenderer::draw (vk::CommandBuffer cb, StaticMesh const & static_mesh, std::span<glm::mat4x4 const > mats) {
118
+ auto const instances = next_instances (mats);
119
+ cb.bindVertexBuffers (1u , instances.buffer , vk::DeviceSize{0 });
120
+ static_mesh.draw (cb, mats.size ());
121
+ m_info.triangles_drawn += static_mesh.info ().vertices / 3 ;
122
+ ++m_info.draw_calls ;
123
+ }
124
+
125
+ BufferView SceneRenderer::next_instances (std::span<glm::mat4x4 const > mats) {
126
+ auto & buffer = [&]() -> Buffer& {
127
+ auto ret = Ptr<Buffer>{};
128
+ if (m_instances.index < m_instances.buffers .size ()) {
129
+ ret = &m_instances.buffers [m_instances.index ++];
130
+ } else {
131
+ ++m_instances.index ;
132
+ ret = &m_instances.buffers .emplace_back (m_gfx, Buffer::Type::eInstance);
133
+ }
134
+ return *ret;
135
+ }();
136
+ buffer.write (mats);
137
+ return buffer.view ();
138
+ }
109
139
} // namespace facade
0 commit comments