mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
perf(render): batch model rendering with instancing
Replaces per-entity draw calls with instanced rendering for both main and shadow passes. Each model's node hierarchy is flattened once and instance matrices are updated per frame, reducing draw calls and CPU overhead.
This commit is contained in:
@@ -3,28 +3,50 @@
|
||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||
#include "Cubed/gameplay/model.hpp"
|
||||
#include "Cubed/render/model_node.hpp"
|
||||
#include "Cubed/shader.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <span>
|
||||
namespace Cubed {
|
||||
class Renderer;
|
||||
class Camera;
|
||||
class ModelRender {
|
||||
public:
|
||||
ModelRender(Renderer& renderer);
|
||||
void render_model(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera, const WalkPose& pose);
|
||||
struct InstanceData {
|
||||
glm::vec3 pos{0.0f};
|
||||
float yaw = 0.0f;
|
||||
WalkPose pose;
|
||||
};
|
||||
|
||||
void shadow_pass(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera, const WalkPose& pose);
|
||||
struct DrawEntry {
|
||||
const Mesh* mesh = nullptr;
|
||||
size_t node_slot = 0;
|
||||
};
|
||||
|
||||
struct ModelBatch {
|
||||
size_t node_count = 0;
|
||||
size_t capacity = 0;
|
||||
std::vector<DrawEntry> entries;
|
||||
std::vector<glm::mat4> instance_matrices;
|
||||
std::unique_ptr<VertexBuffer> instance_vbo;
|
||||
};
|
||||
|
||||
ModelRender(Renderer& renderer);
|
||||
|
||||
void render_instance(ModelID id, std::span<const InstanceData> instances,
|
||||
const Camera& camera, bool shadow);
|
||||
|
||||
private:
|
||||
Renderer& m_renderer;
|
||||
void render_node(const ModelNode& node, const glm::mat4& parent,
|
||||
const glm::mat4& view, const Shader& shader, bool shadow,
|
||||
const WalkPose& pose, const ModelAnimConfig& cfg);
|
||||
|
||||
std::unordered_map<ModelID, ModelBatch> m_batches;
|
||||
|
||||
size_t collect_matrices(const ModelNode& node, const glm::mat4& parent,
|
||||
const WalkPose& pose, const ModelAnimConfig& cfg,
|
||||
std::vector<glm::mat4>& out, size_t slot);
|
||||
glm::mat4 pose_node(const ModelNode& node, const ModelAnimConfig& cfg,
|
||||
const WalkPose& pose);
|
||||
void render_mesh(const Mesh& mesh, bool shadow);
|
||||
|
||||
ModelBatch& get_batch(ModelID id, const ModelNode& root);
|
||||
size_t flatten_nodes(const ModelNode& node, size_t slot, ModelBatch& batch);
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
|
||||
void attribute(GLuint index, GLint size, GLenum type, GLsizei stride,
|
||||
const void* ptr, bool normalized = false) const;
|
||||
void divisor(GLuint index, GLuint divisor = 1);
|
||||
|
||||
private:
|
||||
GLuint m_vao = 0;
|
||||
|
||||
@@ -26,6 +26,8 @@ public:
|
||||
GLuint id() const;
|
||||
void buffer_data(const void* data, GLsizeiptr size,
|
||||
BufferUsage usage = BufferUsage::STATIC_DRAW) const;
|
||||
void buffer_sub_data(const void* data, GLsizeiptr size,
|
||||
GLintptr offset) const;
|
||||
|
||||
private:
|
||||
GLuint m_vbo = 0;
|
||||
|
||||
Reference in New Issue
Block a user