CSCI441 OpenGL Library 6.0.1.1
CS@Mines CSCI441 Computer Graphics Course Library
Loading...
Searching...
No Matches
UniformBufferObject.hpp
Go to the documentation of this file.
1
11#ifndef CSCI441_UNIFORM_BUFFER_OBJECT_HPP
12#define CSCI441_UNIFORM_BUFFER_OBJECT_HPP
13
14#include "constants.h"
15#include "ShaderProgram.hpp"
16
17#ifdef CSCI441_USE_GLEW
18 #include <GL/glew.h>
19#else
20 #include <glad/gl.h>
21#endif
22
23#include <cstdio>
24#include <vector>
25
26//******************************************************************************
27
28namespace CSCI441 {
29
34 class [[maybe_unused]] UniformBufferObject final {
35 public:
40
49
58 UniformBufferObject& operator=(UniformBufferObject&&) noexcept;
59
65 [[maybe_unused]] UniformBufferObject(const char* UNIFORM_BLOCK_NAME, std::initializer_list<const char*> uniformNamesList);
70
78 UniformBufferObject& operator=(const UniformBufferObject&) = delete;
79
87 [[maybe_unused]] void setupWithShaderProgram( ShaderProgram *shaderProgram, GLuint bindingPoint );
88
94 [[maybe_unused]] void bindToShaderProgram( ShaderProgram *shaderProgram );
95
102 [[maybe_unused]] void copyToOffset( unsigned int offset, const void * src, size_t len );
103
110 [[maybe_unused]] void copyToBuffer( const char* UNIFORM_NAME, const void * src, size_t len );
111
117 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, GLboolean value );
123 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, GLint value );
129 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, GLfloat value );
135 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, glm::vec3 vec );
141 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, glm::vec4 vec );
147 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, glm::mat4 mtx );
154 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, const GLint* pArray, GLint count );
161 [[maybe_unused]] void setUniform( const char* UNIFORM_NAME, const glm::ivec4* pArray, GLint count );
162
166 void bindBuffer() const;
167
171 [[maybe_unused]] void bufferSubData() const;
172
173 private:
174 char* _blockName;
175 std::vector<char*> _uniformNames;
176 GLint _blockSize;
177 GLubyte* _buffer;
178 GLuint _numUniforms;
179 GLuint* _uniformIndices;
180 GLint* _uniformOffsets;
181 GLuint _ubod;
182 GLuint _bindingPoint;
183
184 void _cleanupSelf();
185 void _moveFromSource(UniformBufferObject&);
186 };
187}
188
189//******************************************************************************
190
191[[maybe_unused]]
192inline CSCI441::UniformBufferObject::UniformBufferObject(const char* UNIFORM_BLOCK_NAME, const std::initializer_list<const char*> uniformNamesList) {
193 _blockName = new char[strlen(UNIFORM_BLOCK_NAME) + 1];
194 strncpy(_blockName, UNIFORM_BLOCK_NAME, strlen(UNIFORM_BLOCK_NAME));
195 _blockName[ strlen(UNIFORM_BLOCK_NAME) ] = '\0';
196
197 _numUniforms = uniformNamesList.size();
198
199 for(const auto &uniformName : uniformNamesList ) {
200 const auto un = new char[ strlen(uniformName) + 1];
201 strncpy(un, uniformName, strlen(uniformName));
202 un[strlen(uniformName)] = '\0';
203 _uniformNames.push_back(un);
204 }
205
206 _uniformIndices = new GLuint[_numUniforms];
207 _uniformOffsets = new GLint[_numUniforms];
208
209 _blockSize = 0;
210 _buffer = nullptr;
211 _bindingPoint = 0;
212 _ubod = 0;
213}
214
216 _moveFromSource(src);
217}
218
220 if (this != &src) { // guard against self movement
221 _cleanupSelf(); // cleanup existing UBO
222 _moveFromSource(src); // move source UBO
223 }
224 return *this; // return ourselves
225}
226
228 _cleanupSelf();
229}
230
231[[maybe_unused]]
232inline void CSCI441::UniformBufferObject::setupWithShaderProgram( ShaderProgram * shaderProgram, const GLuint bindingPoint ) {
233 _blockSize = shaderProgram->getUniformBlockSize( _blockName );
234 _buffer = new GLubyte[ _blockSize ];
235
236 glGetUniformIndices(shaderProgram->getShaderProgramHandle(), _numUniforms, &_uniformNames[0], _uniformIndices);
237 glGetActiveUniformsiv(shaderProgram->getShaderProgramHandle(), _numUniforms, _uniformIndices, GL_UNIFORM_OFFSET, _uniformOffsets);
238
239 glGenBuffers(1, &_ubod);
240 bindBuffer();
241 glBufferData(GL_UNIFORM_BUFFER, _blockSize, nullptr, GL_DYNAMIC_DRAW);
242
243 _bindingPoint = bindingPoint;
244 glBindBufferBase(GL_UNIFORM_BUFFER, _bindingPoint, _ubod);
245 shaderProgram->setUniformBlockBinding(_blockName, _bindingPoint);
246}
247
248[[maybe_unused]]
250 shaderProgram->setUniformBlockBinding(_blockName, _bindingPoint);
251}
252
253[[maybe_unused]]
254inline void CSCI441::UniformBufferObject::copyToOffset( const unsigned int offset, const void * src, const size_t len ) {
255 if(offset < _numUniforms) {
256 memcpy(_buffer + _uniformOffsets[offset], src, len);
257 } else {
258 fprintf(stderr, "[ERROR]: Offset %d exceeds size of Uniform Block %s which is %d\n", offset, _blockName, _numUniforms);
259 }
260}
261
262[[maybe_unused]]
263inline void CSCI441::UniformBufferObject::copyToBuffer( const char* UNIFORM_NAME, const void * src, const size_t len ) {
264 bool found = false;
265 for(GLuint i = 0; i < _numUniforms; i++) {
266 if( strcmp(_uniformNames[i], UNIFORM_NAME) == 0 ) {
267 memcpy( _buffer + _uniformOffsets[i], src, len );
268 found = true;
269 break;
270 }
271 }
272 if(!found) {
273 fprintf(stderr, "[ERROR]: Uniform Name \"%s\" not found within Uniform Block \"%s\"\n", UNIFORM_NAME, _blockName);
274 }
275}
276
277[[maybe_unused]]
278inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const GLboolean value ) {
279 copyToBuffer(UNIFORM_NAME, &value, sizeof(GLboolean));
280}
281
282[[maybe_unused]]
283inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const GLint value ) {
284 copyToBuffer(UNIFORM_NAME, &value, sizeof(GLint));
285}
286
287[[maybe_unused]]
288inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const GLfloat value ) {
289 copyToBuffer(UNIFORM_NAME, &value, sizeof(GLfloat));
290}
291
292[[maybe_unused]]
293inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const glm::vec3 vec ) {
294 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec), sizeof(glm::vec3));
295}
296
297[[maybe_unused]]
298inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const glm::vec4 vec ) {
299 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec), sizeof(glm::vec4));
300}
301
302[[maybe_unused]]
303inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const glm::mat4 mtx ) {
304 copyToBuffer(UNIFORM_NAME, glm::value_ptr(mtx), sizeof(glm::mat4));
305}
306
307[[maybe_unused]]
308inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const GLint * const pArray, const GLint count ) {
309 copyToBuffer(UNIFORM_NAME, pArray, sizeof(GLint) * count);
310}
311
312[[maybe_unused]]
313inline void CSCI441::UniformBufferObject::setUniform( const char* UNIFORM_NAME, const glm::ivec4 * const pArray, const GLint count ) {
314 copyToBuffer(UNIFORM_NAME, pArray, sizeof(glm::ivec4) * count);
315}
316
318 glBindBuffer(GL_UNIFORM_BUFFER, _ubod);
319}
320
321[[maybe_unused]]
323 glBufferSubData(GL_UNIFORM_BUFFER, 0, _blockSize, _buffer);
324}
325
326inline void CSCI441::UniformBufferObject::_cleanupSelf() {
327 glDeleteBuffers(1, &_ubod);
328 _ubod = 0;
329
330 for(GLuint i = 0; i < _numUniforms; i++) {
331 delete[] _uniformNames[i];
332 }
333 _uniformNames.clear();
334
335 delete[] _uniformIndices;
336 _uniformIndices = nullptr;
337
338 delete[] _uniformOffsets;
339 _uniformOffsets = nullptr;
340
341 delete[] _buffer;
342 _buffer = nullptr;
343
344 delete[] _blockName;
345 _blockName = nullptr;
346
347 _numUniforms = 0;
348 _blockSize = 0;
349 _bindingPoint = 0;
350}
351
352
353inline void CSCI441::UniformBufferObject::_moveFromSource(UniformBufferObject &src) {
354 _blockName = src._blockName;
355 src._blockName = nullptr;
356
357 _numUniforms = src._numUniforms;
358 src._numUniforms = 0;
359
360 _uniformNames = std::move(src._uniformNames);
361 src._uniformNames.clear();
362
363 _uniformIndices = src._uniformIndices;
364 src._uniformIndices = nullptr;
365
366 _uniformOffsets = src._uniformOffsets;
367 src._uniformOffsets = nullptr;
368
369 _blockSize = src._blockSize;
370 src._blockSize = 0;
371
372 _buffer = src._buffer;
373 src._buffer = nullptr;
374
375 _bindingPoint = src._bindingPoint;
376 src._bindingPoint = 0;
377
378 _ubod = src._ubod;
379 src._ubod = 0;
380}
381
382#endif //CSCI441_UNIFORM_BUFFER_OBJECT_HPP
Class to work with OpenGL 4.0+ Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:36
virtual void setUniformBlockBinding(const GLchar *uniformBlockName, GLuint binding) const final
Set the binding point for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1382
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1528
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1336
Storage of UBO related data.
Definition: UniformBufferObject.hpp:34
void bindBuffer() const
binds UBO object to UBO buffer
Definition: UniformBufferObject.hpp:317
~UniformBufferObject()
Deletes the UBO from the GPU and frees all memory on the CPU.
Definition: UniformBufferObject.hpp:227
void bindToShaderProgram(ShaderProgram *shaderProgram)
sets the shader programs binding point to match this uniform buffer object
Definition: UniformBufferObject.hpp:249
void setUniform(const char *UNIFORM_NAME, GLboolean value)
sets the uniform value within the uniform buffer block
Definition: UniformBufferObject.hpp:278
UniformBufferObject(UniformBufferObject &unused)=delete
void copyToBuffer(const char *UNIFORM_NAME, const void *src, size_t len)
copies the value pointed to by addr to the corresponding location within the UBO as denoted by the un...
Definition: UniformBufferObject.hpp:263
void copyToOffset(unsigned int offset, const void *src, size_t len)
copies the value pointed to by addr to the corresponding location within the UBO as denoted by the of...
Definition: UniformBufferObject.hpp:254
void setupWithShaderProgram(ShaderProgram *shaderProgram, GLuint bindingPoint)
creates the UBO and allocates memory on both the CPU & GPU. binds the UBO and the uniform block for t...
Definition: UniformBufferObject.hpp:232
void bufferSubData() const
transfers UBO data to UBO buffer
Definition: UniformBufferObject.hpp:322
UniformBufferObject & operator=(UniformBufferObject &unused)=delete
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17