Loading...
Searching...
No Matches
InstancedRenderableComponent.cpp
Go to the documentation of this file.
1// InstancedRenderableComponent.cpp
2#include "hellfire/ecs/InstancedRenderableComponent.h"
3#include <GL/glew.h>
4
5namespace hellfire {
7 std::shared_ptr<Mesh> mesh, size_t max_instances)
8 : mesh_(std::move(mesh)), max_instances_(max_instances),
11 instances_.reserve(max_instances_);
13 }
14
17 }
18
20 if (instances_.size() < max_instances_) {
21 instances_.push_back(instance);
22 needs_gpu_update_ = true;
23 }
24 }
25
26 void InstancedRenderableComponent::update_instance(size_t index, const InstanceData& instance) {
27 if (index < instances_.size()) {
28 instances_[index] = instance;
29 needs_gpu_update_ = true;
30 }
31 }
32
34 instances_.clear();
35 needs_gpu_update_ = true;
36 }
37
39 instances_.reserve((std::min)(count, max_instances_));
40 }
41
42 void InstancedRenderableComponent::set_instances(const std::vector<InstanceData>& instances) {
43 instances_ = instances;
44 if (instances_.size() > max_instances_) {
45 instances_.resize(max_instances_);
46 }
47 needs_gpu_update_ = true;
48 }
49
50 void InstancedRenderableComponent::add_instances(const std::vector<InstanceData>& instances) {
51 for (const auto& instance : instances) {
52 add_instance(instance);
53 }
54 }
55
59 needs_gpu_update_ = false;
60 }
61 }
62
66 }
67
70 }
71
73 glGenBuffers(1, &instance_vbo_);
74 glGenBuffers(1, &transform_buffer_);
75 glGenBuffers(1, &color_buffer_);
76 glGenBuffers(1, &scale_buffer_);
77 }
78
80 if (instance_vbo_) glDeleteBuffers(1, &instance_vbo_);
81 if (transform_buffer_) glDeleteBuffers(1, &transform_buffer_);
82 if (color_buffer_) glDeleteBuffers(1, &color_buffer_);
83 if (scale_buffer_) glDeleteBuffers(1, &scale_buffer_);
84
85 instance_vbo_ = 0;
86 transform_buffer_ = 0;
87 color_buffer_ = 0;
88 scale_buffer_ = 0;
89 }
90
92 if (instances_.empty()) return;
93
94 std::vector<glm::mat4> transforms;
95 std::vector<glm::vec3> colors;
96 std::vector<float> scales;
97
98 transforms.reserve(instances_.size());
99 colors.reserve(instances_.size());
100 scales.reserve(instances_.size());
101
102 for (const auto& instance : instances_) {
103 transforms.push_back(instance.transform);
104 colors.push_back(instance.color);
105 scales.push_back(instance.scale);
106 }
107
108 // Upload transforms (layout 4-7)
109 glBindBuffer(GL_ARRAY_BUFFER, transform_buffer_);
110 glBufferData(GL_ARRAY_BUFFER, transforms.size() * sizeof(glm::mat4),
111 transforms.data(), GL_DYNAMIC_DRAW);
112
113 // Upload colors (layout 8)
114 glBindBuffer(GL_ARRAY_BUFFER, color_buffer_);
115 glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3),
116 colors.data(), GL_DYNAMIC_DRAW);
117
118 // Upload scales (layout 9)
119 glBindBuffer(GL_ARRAY_BUFFER, scale_buffer_);
120 glBufferData(GL_ARRAY_BUFFER, scales.size() * sizeof(float),
121 scales.data(), GL_DYNAMIC_DRAW);
122
123 glBindBuffer(GL_ARRAY_BUFFER, 0);
124 }
125
127 if (vertex_attributes_setup_) return;
128
129 // Transform matrix (layouts 4-7)
130 glBindBuffer(GL_ARRAY_BUFFER, transform_buffer_);
131 for (int i = 0; i < 4; i++) {
132 glVertexAttribPointer(4 + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4),
133 (void*)(sizeof(glm::vec4) * i));
134 glVertexAttribDivisor(4 + i, 1);
135 }
136
137 // Color (layout 8)
138 glBindBuffer(GL_ARRAY_BUFFER, color_buffer_);
139 glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
140 glVertexAttribDivisor(8, 1);
141
142 // Scale (layout 9)
143 glBindBuffer(GL_ARRAY_BUFFER, scale_buffer_);
144 glVertexAttribPointer(9, 1, GL_FLOAT, GL_FALSE, sizeof(float), (void*)0);
145 glVertexAttribDivisor(9, 1);
146
148 }
149
151 glEnableVertexAttribArray(4);
152 glEnableVertexAttribArray(5);
153 glEnableVertexAttribArray(6);
154 glEnableVertexAttribArray(7);
155 glEnableVertexAttribArray(8);
156 glEnableVertexAttribArray(9);
157 }
158
160 glDisableVertexAttribArray(4);
161 glDisableVertexAttribArray(5);
162 glDisableVertexAttribArray(6);
163 glDisableVertexAttribArray(7);
164 glDisableVertexAttribArray(8);
165 glDisableVertexAttribArray(9);
166 }
167}
void update_instance(size_t index, const InstanceData &instance)
InstancedRenderableComponent(std::shared_ptr< Mesh > mesh, size_t max_instances=1000)
void add_instance(const InstanceData &instance)
void add_instances(const std::vector< InstanceData > &instances)
void set_instances(const std::vector< InstanceData > &instances)