Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
manager.h
1#ifndef OE_RENDER_MANAGER_H
2#define OE_RENDER_MANAGER_H
3
4#include <cstdint>
5#include <span>
6#include <utility>
7#include <vector>
8#include <variant>
9#include <atomic>
10
11#include "passes.h"
12#include "mesh.h"
13#include "shader_base.h"
14
15#include "mesh_renderer.h"
16#include "mesh_skinned_renderer.h"
17
18namespace oe::render
19{
28 {
29 using RenderNodeId = uint32_t;
30
32 {
33 RenderNodeId id;
34 std::variant<MeshRenderer, MeshSkinnedRenderer> mesh_renderer;
35 };
36
37 template <typename T>
38 using Container = std::vector<T>;
39 };
40
44 template <typename SettingsType = RenderManagerSettings>
46 {
47 using RenderNodeId = SettingsType::RenderNodeId;
48 using RenderNode = SettingsType::RenderNode;
49 using NodeContainerType = SettingsType::template Container<RenderNode>;
50
52 NodeContainerType opaque_nodes;
53
55 NodeContainerType blend_nodes;
56
62 NodeContainerType refractive_nodes;
63
64 RenderNode* getNodeById(const RenderNodeId id_node, std::span<const NodeContainerType> nodes)
65 {
66 auto it = find_if(nodes.begin(), nodes.end(), [&id_node](const NodeContainerType& node)
67 {
68 return node.id == id_node;
69 });
70
71 if (it != nodes.end())
72 {
73 return nullptr;
74 }
75
76 return &(*it);
77 }
78
79 void deleteNodeById(const RenderNodeId id_node)
80 {
81 auto node_lists = {&opaque_nodes, &blend_nodes, &refractive_nodes};
82
83 for (auto& node_list_ptr : node_lists)
84 {
85 auto& node_list = *node_list_ptr;
86
87 node_list.erase(std::remove_if(node_list.begin(), node_list.end(),
88 [id_node](auto& node) {
89 return node.id == id_node;
90 }), node_list.end()
91 );
92 }
93 }
94
95 template <typename T>
96 RenderNodeId addOpaqueNode(T&& component)
97 {
98 RenderNodeId id_node = _next_node_id++;
99
100 opaque_nodes.emplace_back(id_node, std::move(component));
101
102 return id_node;
103 }
104
105 template <typename T>
106 RenderNodeId addBlendNode(T&& component, bool is_glass = false)
107 {
108 RenderNodeId id_node = _next_node_id++;
109
110 if (is_glass)
111 {
112 refractive_nodes.emplace_back(id_node, std::move(component));
113 }
114 else
115 {
116 blend_nodes.emplace_back(id_node, std::move(component));
117 }
118
119 return id_node;
120 }
121
125 template <typename RenderNodeType, typename F>
126 void renderNode(RenderNodeType& renderer, const oe::scene::Camera& camera, const oe::render::RenderingPass render_pass, F&& fill_shader)
127 {
128 // Todo: be gentle with memory: first loop to get all "render_commands" then second loop to render each meshes
129 // Order each command by shader
130
131 bool is_blending_pass = render_pass == oe::render::RenderingPass::FORWARD;
132
133 std::vector<render::DrawCommand> render_commands;
134 bool can_render = renderer.fillRenderCommands(camera, is_blending_pass, render_commands);
135
136 if (!can_render)
137 {
138 return;
139 }
140
141 oe::render::Mesh& render_mesh = renderer.render_mesh;
142 oe::render::GeometryPass geometry_pass = renderer.geometry_pass;
143
144 for (auto &it : render_commands)
145 {
146 auto* material = it.material;
147 oe::render::ShaderBase* shader = material->shader;
148
149 shader->bind(geometry_pass, render_pass);
150
151 renderer.fillShader(shader, camera);
152
153 shader->fillTextures(material->textures);
154 shader->fillFromCamera(camera);
155 shader->fillFromMaterial(material);
156
157 fill_shader(shader);
158
159 render_mesh.render(it.enabled_primitives);
160 }
161 }
162
166 void renderOpaqueNodes(const oe::scene::Camera& camera, const oe::render::RenderingPass render_pass)
167 {
168 render(opaque_nodes, camera, render_pass);
169 }
170
174 template <typename F>
175 void renderBlendNodes(const oe::scene::Camera& camera, const oe::render::RenderingPass render_pass, F&& fill_shader)
176 {
177 render(blend_nodes, camera, render_pass, fill_shader);
178 }
179
183 template <typename F>
184 void render(std::span<RenderNode> nodes, const oe::scene::Camera& camera, const oe::render::RenderingPass render_pass, F&& fill_shader)
185 {
186 for (auto& render_node : nodes)
187 {
188 std::visit([&](auto& mesh_renderer)
189 {
190 renderNode(mesh_renderer, camera, render_pass, fill_shader);
191 }, render_node.mesh_renderer);
192 }
193 }
194
200 void render(std::span<RenderNode> nodes, const oe::scene::Camera& camera, const oe::render::RenderingPass render_pass)
201 {
202 for (auto& render_node : nodes)
203 {
204 std::visit([&](auto& mesh_renderer)
205 {
206 renderNode(mesh_renderer, camera, render_pass, [](void*) {});
207 }, render_node.mesh_renderer);
208 }
209 }
210
212 std::atomic<uint64_t> _next_node_id = 1;
213 };
214
219}
220
221#endif
Definition mesh.h:80
void render(const std::vector< bool > &activeprimitives, uint32_t mode=default_mesh_rendering_mode)
Ask the GPU to render specific primitives of the mesh.
Definition mesh.h:226
Shader class.
Definition shader_base.h:32
void fillTextures(std::span< const scene::TextureProperty > textures)
Fill textures uniforms + bind textures.
void bind(const GeometryPass vertex_pass, const RenderingPass fragment_pass)
Use the shader in graphic API.
void fillFromCamera(const scene::Camera &camera) noexcept
Fill uniforms from camera (mainly position + transform matrices).
void fillFromMaterial(const scene::Material *material)
Fill uniforms from material.
The "eye of the scene".
Definition camera.h:31
Render related abstractions (Shader, Framebuffer, Cubemaps, Textures).
Definition opengl.h:12
RenderingPass
Pipeline rendering passes.
Definition passes.h:24
@ FORWARD
Definition passes.h:29
GenericRenderManager< RenderManagerSettings > RenderManager
Render manager using a variant of MeshRenderer and MeshSkinnedRenderer.
Definition manager.h:218
GeometryPass
Vertex rendering passes.
Definition passes.h:12
Generic render manager.
Definition manager.h:46
NodeContainerType refractive_nodes
Definition manager.h:62
void renderNode(RenderNodeType &renderer, const oe::scene::Camera &camera, const oe::render::RenderingPass render_pass, F &&fill_shader)
Render node list using specified rendering.
Definition manager.h:126
NodeContainerType blend_nodes
Definition manager.h:55
void renderOpaqueNodes(const oe::scene::Camera &camera, const oe::render::RenderingPass render_pass)
Render opaque nodes list using specified rendering.
Definition manager.h:166
NodeContainerType opaque_nodes
Definition manager.h:52
void render(std::span< RenderNode > nodes, const oe::scene::Camera &camera, const oe::render::RenderingPass render_pass, F &&fill_shader)
Definition manager.h:184
void render(std::span< RenderNode > nodes, const oe::scene::Camera &camera, const oe::render::RenderingPass render_pass)
Render custom nodes list using specified rendering.
Definition manager.h:200
void renderBlendNodes(const oe::scene::Camera &camera, const oe::render::RenderingPass render_pass, F &&fill_shader)
Render blend nodes list using specified rendering.
Definition manager.h:175
Default Render manager settings.
Definition manager.h:28