11#ifndef CSCI441_UNIFORM_BUFFER_OBJECT_HPP
12#define CSCI441_UNIFORM_BUFFER_OBJECT_HPP
17#ifdef CSCI441_USE_GLEW
65 [[maybe_unused]]
UniformBufferObject(const
char* UNIFORM_BLOCK_NAME, std::initializer_list<const
char*> uniformNamesList);
87 [[maybe_unused]]
void setupWithShaderProgram(
ShaderProgram *shaderProgram, GLuint bindingPoint );
94 [[maybe_unused]]
void bindToShaderProgram(
ShaderProgram *shaderProgram );
102 [[maybe_unused]]
void copyToOffset(
unsigned int offset, const
void * src,
size_t len );
110 [[maybe_unused]]
void copyToBuffer( const
char* UNIFORM_NAME, const
void * src,
size_t len );
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 );
166 void bindBuffer() const;
171 [[maybe_unused]]
void bufferSubData() const;
175 std::vector<
char*> _uniformNames;
179 GLuint* _uniformIndices;
180 GLint* _uniformOffsets;
182 GLuint _bindingPoint;
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';
197 _numUniforms = uniformNamesList.size();
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);
206 _uniformIndices =
new GLuint[_numUniforms];
207 _uniformOffsets =
new GLint[_numUniforms];
216 _moveFromSource(src);
222 _moveFromSource(src);
234 _buffer =
new GLubyte[ _blockSize ];
236 glGetUniformIndices(shaderProgram->
getShaderProgramHandle(), _numUniforms, &_uniformNames[0], _uniformIndices);
237 glGetActiveUniformsiv(shaderProgram->
getShaderProgramHandle(), _numUniforms, _uniformIndices, GL_UNIFORM_OFFSET, _uniformOffsets);
239 glGenBuffers(1, &_ubod);
241 glBufferData(GL_UNIFORM_BUFFER, _blockSize,
nullptr, GL_DYNAMIC_DRAW);
243 _bindingPoint = bindingPoint;
244 glBindBufferBase(GL_UNIFORM_BUFFER, _bindingPoint, _ubod);
255 if(offset < _numUniforms) {
256 memcpy(_buffer + _uniformOffsets[offset], src, len);
258 fprintf(stderr,
"[ERROR]: Offset %d exceeds size of Uniform Block %s which is %d\n", offset, _blockName, _numUniforms);
265 for(GLuint i = 0; i < _numUniforms; i++) {
266 if( strcmp(_uniformNames[i], UNIFORM_NAME) == 0 ) {
267 memcpy( _buffer + _uniformOffsets[i], src, len );
273 fprintf(stderr,
"[ERROR]: Uniform Name \"%s\" not found within Uniform Block \"%s\"\n", UNIFORM_NAME, _blockName);
279 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLboolean));
284 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLint));
289 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLfloat));
294 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec),
sizeof(glm::vec3));
299 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec),
sizeof(glm::vec4));
304 copyToBuffer(UNIFORM_NAME, glm::value_ptr(mtx),
sizeof(glm::mat4));
309 copyToBuffer(UNIFORM_NAME, pArray,
sizeof(GLint) * count);
314 copyToBuffer(UNIFORM_NAME, pArray,
sizeof(glm::ivec4) * count);
318 glBindBuffer(GL_UNIFORM_BUFFER, _ubod);
323 glBufferSubData(GL_UNIFORM_BUFFER, 0, _blockSize, _buffer);
326inline void CSCI441::UniformBufferObject::_cleanupSelf() {
327 glDeleteBuffers(1, &_ubod);
330 for(GLuint i = 0; i < _numUniforms; i++) {
331 delete[] _uniformNames[i];
333 _uniformNames.clear();
335 delete[] _uniformIndices;
336 _uniformIndices =
nullptr;
338 delete[] _uniformOffsets;
339 _uniformOffsets =
nullptr;
345 _blockName =
nullptr;
353inline void CSCI441::UniformBufferObject::_moveFromSource(UniformBufferObject &src) {
354 _blockName = src._blockName;
355 src._blockName =
nullptr;
357 _numUniforms = src._numUniforms;
358 src._numUniforms = 0;
360 _uniformNames = std::move(src._uniformNames);
361 src._uniformNames.clear();
363 _uniformIndices = src._uniformIndices;
364 src._uniformIndices =
nullptr;
366 _uniformOffsets = src._uniformOffsets;
367 src._uniformOffsets =
nullptr;
369 _blockSize = src._blockSize;
372 _buffer = src._buffer;
373 src._buffer =
nullptr;
375 _bindingPoint = src._bindingPoint;
376 src._bindingPoint = 0;
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
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17