@@ -16,7 +16,7 @@ namespace openage::renderer::opengl {
1616
1717GlUniformBuffer::GlUniformBuffer (const std::shared_ptr<GlContext> &context,
1818 size_t size,
19- std::unordered_map<std::string, GlInBlockUniform> uniforms,
19+ std::vector< GlInBlockUniform> uniforms,
2020 GLuint binding_point,
2121 GLenum usage) :
2222 GlSimpleObject (context,
@@ -33,6 +33,12 @@ GlUniformBuffer::GlUniformBuffer(const std::shared_ptr<GlContext> &context,
3333 this ->bind ();
3434 glBufferData (GL_UNIFORM_BUFFER, this ->data_size , NULL , usage);
3535
36+ uniform_id_t unif_id = 0 ;
37+ for (auto &uniform : uniforms) {
38+ this ->uniforms_by_name .insert (std::make_pair (uniform.name , unif_id));
39+ unif_id += 1 ;
40+ }
41+
3642 glBindBufferRange (GL_UNIFORM_BUFFER, this ->binding_point , *this ->handle , 0 , this ->data_size );
3743
3844 log::log (MSG (dbg) << " Created OpenGL uniform buffer (size: "
@@ -51,23 +57,35 @@ void GlUniformBuffer::set_binding_point(GLuint binding_point) {
5157
5258void GlUniformBuffer::update_uniforms (std::shared_ptr<UniformBufferInput> const &unif_in) {
5359 auto glunif_in = std::dynamic_pointer_cast<GlUniformBufferInput>(unif_in);
54- ENSURE (glunif_in->get_buffer () == this -> shared_from_this () , " Uniform input passed to different buffer than it was created with." );
60+ ENSURE (glunif_in->get_buffer (). get () == this , " Uniform input passed to different buffer than it was created with." );
5561
5662 this ->bind ();
5763
64+ const auto &update_offs = glunif_in->update_offs ;
65+ const auto &used_uniforms = glunif_in->used_uniforms ;
66+ const auto &uniforms = this ->uniforms ;
5867 uint8_t const *data = glunif_in->update_data .data ();
59- for (auto const &pair : glunif_in->update_offs ) {
60- uint8_t const *ptr = data + pair.second ;
61- auto unif_def = this ->uniforms [pair.first ];
62- auto loc = unif_def.offset ;
63- auto size = unif_def.size ;
68+
69+ size_t unif_count = used_uniforms.size ();
70+ for (size_t i = 0 ; i < unif_count; ++i) {
71+ uniform_id_t unif_id = used_uniforms[i];
72+ auto offset = update_offs[unif_id];
73+
74+ uint8_t const *ptr = data + offset.offset ;
75+ auto &unif = uniforms[unif_id];
76+ auto loc = unif.offset ;
77+ auto size = unif.size ;
6478
6579 glBufferSubData (GL_UNIFORM_BUFFER, loc, size, ptr);
6680 }
6781}
6882
69- bool GlUniformBuffer::has_uniform (const char *unif) {
70- return this ->uniforms .count (unif) != 0 ;
83+ const std::vector<GlInBlockUniform> &GlUniformBuffer::get_uniforms () const {
84+ return this ->uniforms ;
85+ }
86+
87+ bool GlUniformBuffer::has_uniform (const char *name) {
88+ return this ->uniforms_by_name .contains (name);
7189}
7290
7391void GlUniformBuffer::bind () const {
@@ -80,14 +98,14 @@ std::shared_ptr<UniformBufferInput> GlUniformBuffer::new_unif_in() {
8098 return in;
8199}
82100
83- void GlUniformBuffer::set_unif (std::shared_ptr< UniformBufferInput> const &in, const char *unif, void const *val, GLenum type) {
84- auto unif_in = std::dynamic_pointer_cast <GlUniformBufferInput>(in);
101+ void GlUniformBuffer::set_unif (UniformBufferInput &in, const char *unif, void const *val, GLenum type) {
102+ auto & unif_in = dynamic_cast <GlUniformBufferInput & >(in);
85103
86- auto uniform = this ->uniforms .find (unif);
87- ENSURE (uniform != std::end ( this ->uniforms ),
88- " Tried to set uniform " << unif << " that does not exist in the shader program. " );
104+ auto unif_id = this ->uniforms_by_name .find (unif)-> second ;
105+ ENSURE (unif_id < this ->uniforms . size ( ),
106+ " Tried to set uniform with invalid ID " << unif_id );
89107
90- auto const &unif_data = uniform-> second ;
108+ auto const &unif_data = this -> uniforms [unif_id] ;
91109
92110 ENSURE (type == unif_data.type ,
93111 " Tried to set uniform " << unif << " to a value of the wrong type." );
@@ -96,83 +114,80 @@ void GlUniformBuffer::set_unif(std::shared_ptr<UniformBufferInput> const &in, co
96114 ENSURE (size == unif_data.size ,
97115 " Tried to set uniform " << unif << " to a value of the wrong size." );
98116
99- auto update_off = unif_in->update_offs .find (unif);
100- if (update_off != std::end (unif_in->update_offs )) [[likely]] { // always used after the uniform value is written once
101- // already wrote to this uniform since last upload
102- size_t off = update_off->second ;
103- memcpy (unif_in->update_data .data () + off, val, size);
104- }
105- else {
106- // first time writing to this uniform since last upload, so
107- // extend the buffer before storing the uniform value
108- size_t prev_size = unif_in->update_data .size ();
109- unif_in->update_data .resize (prev_size + size);
110- memcpy (unif_in->update_data .data () + prev_size, val, size);
111- unif_in->update_offs .emplace (unif, prev_size);
117+ auto &update_off = unif_in.update_offs [unif_id];
118+ auto offset = update_off.offset ;
119+ memcpy (unif_in.update_data .data () + offset, val, size);
120+ if (not update_off.used ) [[unlikely]] { // only true if the uniform value was not set before
121+ auto lower_bound = std::lower_bound (
122+ std::begin (unif_in.used_uniforms ),
123+ std::end (unif_in.used_uniforms ),
124+ unif_id);
125+ unif_in.used_uniforms .insert (lower_bound, unif_id);
126+ update_off.used = true ;
112127 }
113128}
114129
115- void GlUniformBuffer::set_i32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, int32_t val) {
130+ void GlUniformBuffer::set_i32 (UniformBufferInput &in, const char *unif, int32_t val) {
116131 this ->set_unif (in, unif, &val, GL_INT);
117132}
118133
119- void GlUniformBuffer::set_u32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, uint32_t val) {
134+ void GlUniformBuffer::set_u32 (UniformBufferInput &in, const char *unif, uint32_t val) {
120135 this ->set_unif (in, unif, &val, GL_UNSIGNED_INT);
121136}
122137
123- void GlUniformBuffer::set_f32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, float val) {
138+ void GlUniformBuffer::set_f32 (UniformBufferInput &in, const char *unif, float val) {
124139 this ->set_unif (in, unif, &val, GL_FLOAT);
125140}
126141
127- void GlUniformBuffer::set_f64 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, double val) {
142+ void GlUniformBuffer::set_f64 (UniformBufferInput &in, const char *unif, double val) {
128143 this ->set_unif (in, unif, &val, GL_DOUBLE);
129144}
130145
131- void GlUniformBuffer::set_bool (std::shared_ptr< UniformBufferInput> const &in, const char *unif, bool val) {
146+ void GlUniformBuffer::set_bool (UniformBufferInput &in, const char *unif, bool val) {
132147 this ->set_unif (in, unif, &val, GL_BOOL);
133148}
134149
135- void GlUniformBuffer::set_v2f32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector2f const &val) {
150+ void GlUniformBuffer::set_v2f32 (UniformBufferInput &in, const char *unif, Eigen::Vector2f const &val) {
136151 this ->set_unif (in, unif, val.data (), GL_FLOAT_VEC2);
137152}
138153
139- void GlUniformBuffer::set_v3f32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector3f const &val) {
154+ void GlUniformBuffer::set_v3f32 (UniformBufferInput &in, const char *unif, Eigen::Vector3f const &val) {
140155 this ->set_unif (in, unif, val.data (), GL_FLOAT_VEC3);
141156}
142157
143- void GlUniformBuffer::set_v4f32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector4f const &val) {
158+ void GlUniformBuffer::set_v4f32 (UniformBufferInput &in, const char *unif, Eigen::Vector4f const &val) {
144159 this ->set_unif (in, unif, val.data (), GL_FLOAT_VEC4);
145160}
146161
147- void GlUniformBuffer::set_v2i32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector2i const &val) {
162+ void GlUniformBuffer::set_v2i32 (UniformBufferInput &in, const char *unif, Eigen::Vector2i const &val) {
148163 this ->set_unif (in, unif, val.data (), GL_INT_VEC2);
149164}
150165
151- void GlUniformBuffer::set_v3i32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector3i const &val) {
166+ void GlUniformBuffer::set_v3i32 (UniformBufferInput &in, const char *unif, Eigen::Vector3i const &val) {
152167 this ->set_unif (in, unif, val.data (), GL_INT_VEC3);
153168}
154169
155- void GlUniformBuffer::set_v4i32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector4i const &val) {
170+ void GlUniformBuffer::set_v4i32 (UniformBufferInput &in, const char *unif, Eigen::Vector4i const &val) {
156171 this ->set_unif (in, unif, val.data (), GL_INT_VEC4);
157172}
158173
159- void GlUniformBuffer::set_v2ui32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector2<uint32_t > const &val) {
174+ void GlUniformBuffer::set_v2ui32 (UniformBufferInput &in, const char *unif, Eigen::Vector2<uint32_t > const &val) {
160175 this ->set_unif (in, unif, val.data (), GL_UNSIGNED_INT_VEC2);
161176}
162177
163- void GlUniformBuffer::set_v3ui32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector3<uint32_t > const &val) {
178+ void GlUniformBuffer::set_v3ui32 (UniformBufferInput &in, const char *unif, Eigen::Vector3<uint32_t > const &val) {
164179 this ->set_unif (in, unif, val.data (), GL_UNSIGNED_INT_VEC3);
165180}
166181
167- void GlUniformBuffer::set_v4ui32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Vector4<uint32_t > const &val) {
182+ void GlUniformBuffer::set_v4ui32 (UniformBufferInput &in, const char *unif, Eigen::Vector4<uint32_t > const &val) {
168183 this ->set_unif (in, unif, val.data (), GL_UNSIGNED_INT_VEC4);
169184}
170185
171- void GlUniformBuffer::set_m4f32 (std::shared_ptr< UniformBufferInput> const &in, const char *unif, Eigen::Matrix4f const &val) {
186+ void GlUniformBuffer::set_m4f32 (UniformBufferInput &in, const char *unif, Eigen::Matrix4f const &val) {
172187 this ->set_unif (in, unif, val.data (), GL_FLOAT_MAT4);
173188}
174189
175- void GlUniformBuffer::set_tex (std::shared_ptr< UniformBufferInput> const &in, const char *unif, std::shared_ptr<Texture2d> const &val) {
190+ void GlUniformBuffer::set_tex (UniformBufferInput &in, const char *unif, std::shared_ptr<Texture2d> const &val) {
176191 auto tex = std::dynamic_pointer_cast<GlTexture2d>(val);
177192 GLuint handle = tex->get_handle ();
178193 this ->set_unif (in, unif, &handle, GL_SAMPLER_2D);
0 commit comments