Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
mesh_skinned_renderer.h
1#ifndef OE_RENDER_MESH_SKINNED_RENDERER_H
2#define OE_RENDER_MESH_SKINNED_RENDERER_H
3
4#include "mesh_renderer.h"
5#include "../scene/skin.h"
6
7#include "texture.h"
8
9namespace oe::render
10{
14 struct MeshSkinnedRenderer : public MeshRenderer
15 {
16 constexpr const static oe::render::GeometryPass geometry_pass = oe::render::GeometryPass::SKINNED;
17
18 template <typename BaseMeshType>
19 MeshSkinnedRenderer(oe::scene::NodePtr& root_node, const BaseMeshType& scene_mesh, const oe::scene::skin::Armature& param_armature = {}):
20 MeshRenderer(root_node, scene_mesh),
21 armature(param_armature)
22 {
23 // If no armature or missing root node, use the one provided
24 if (!param_armature.root_node)
25 {
26 armature.root_node = root_node;
27 }
28
29 _bones_count = armature.bones.size();
30
31 _bones_texture = std::make_shared<Texture>(
32 _bones_count * 16, 1, nullptr,
33 4,
34 GL_RGBA32F, GL_RGBA, GL_FLOAT
35 );
36 }
37
41 bool fillRenderCommands(const scene::Camera& camera, const bool is_blending_pass, std::vector<render::DrawCommand>& result)
42 {
43 // Update the armature (also updates bones BBOX for frustum culling)
44 armature.update();
45
46 // Check if the mesh will be rendered (no need to uselessly fill bones / blendshapes if no render)
47 bool has_rendering = MeshRenderer::fillRenderCommands(camera, is_blending_pass, result);
48
49 if (has_rendering)
50 {
51 // Fill bones texture
52 std::vector<glm::vec4> bones_lut;
53
54 const auto& bones_matrices = armature.bones_matrices;
55
56 for (const auto& mat : bones_matrices)
57 {
58 bones_lut.push_back(mat[0]);
59 bones_lut.push_back(mat[1]);
60 bones_lut.push_back(mat[2]);
61 bones_lut.push_back(mat[3]);
62 }
63
64 ByteSpan encoded_bones_lut{reinterpret_cast<std::byte*>(bones_lut.data()), bones_lut.size() * 16};
65
66 _bones_texture->fillTextureData(encoded_bones_lut, 0, 0);
67 }
68
69 return has_rendering;
70 }
71
77 void fillShader(ShaderBase* shader, const oe::scene::Camera& camera)
78 {
79 // Send Bones data
80 _bones_texture->use(6);
81 shader->setInt("uBonesMatrices", 6);
82
83 MeshRenderer::fillShader(shader, camera);
84 }
85
87
88 std::shared_ptr<Texture> _bones_texture;
89
90 uint32_t _bones_count = 0;
91
92 };
93}
94
95#endif
Shader class.
Definition shader_base.h:32
void setInt(const std::string &name, const int32_t value)
Send an int uniform to the shader.
The "eye of the scene".
Definition camera.h:31
Render related abstractions (Shader, Framebuffer, Cubemaps, Textures).
Definition opengl.h:12
GeometryPass
Vertex rendering passes.
Definition passes.h:12
@ SKINNED
Definition passes.h:17
void fillShader(ShaderBase *shader, const oe::scene::Camera &camera)
Send shader uniforms related to this mesh.
Definition mesh_renderer.h:104
bool fillRenderCommands(const scene::Camera &camera, const bool is_blending_pass, std::vector< render::DrawCommand > &result)
Generate a list of {primitives, Material*} to render this mesh.
Definition mesh_renderer.h:65
void fillShader(ShaderBase *shader, const oe::scene::Camera &camera)
Send shader uniforms related to this sknned mesh.
Definition mesh_skinned_renderer.h:77
bool fillRenderCommands(const scene::Camera &camera, const bool is_blending_pass, std::vector< render::DrawCommand > &result)
Update bones matrices then call base filler.
Definition mesh_skinned_renderer.h:41
Wrapper to a node reference to use pointers to node even if the actual node moves in memory.
Definition node_ptr.h:19
Skinned mesh skeleton.
Definition skin.h:120