11#ifndef CSCI441_UNIFORM_BUFFER_OBJECT_HPP
12#define CSCI441_UNIFORM_BUFFER_OBJECT_HPP
15#include "LogUtils.hpp"
18#ifdef CSCI441_USE_GLEW
66 [[maybe_unused]]
UniformBufferObject(const
char* UNIFORM_BLOCK_NAME, const std::initializer_list<const
char*> uniformNamesList);
88 [[maybe_unused]]
void setupWithShaderProgram(
ShaderProgram *shaderProgram, GLuint bindingPoint );
95 [[maybe_unused]]
void bindToShaderProgram(
ShaderProgram *shaderProgram );
103 [[maybe_unused]]
void copyToOffset(
unsigned int offset, const
void * src,
size_t len );
111 [[maybe_unused]]
void copyToBuffer( const
char* UNIFORM_NAME, const
void * src,
size_t len );
118 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, GLboolean value );
124 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, GLint value );
130 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, GLfloat value );
136 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, glm::vec3 vec );
142 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, glm::vec4 vec );
148 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, glm::mat4 mtx );
155 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, const GLint* pArray, GLint count );
162 [[maybe_unused]]
void setUniform( const
char* UNIFORM_NAME, const glm::ivec4* pArray, GLint count );
167 void bindBuffer() const;
172 [[maybe_unused]]
void bufferSubData() const;
176 std::vector<
char*> _uniformNames;
180 GLuint* _uniformIndices;
181 GLint* _uniformOffsets;
183 GLuint _bindingPoint;
194 _blockName =
new char[strlen(UNIFORM_BLOCK_NAME) + 1];
195 strncpy(_blockName, UNIFORM_BLOCK_NAME, strlen(UNIFORM_BLOCK_NAME));
196 _blockName[ strlen(UNIFORM_BLOCK_NAME) ] =
'\0';
198 _numUniforms = uniformNamesList.size();
200 for(
const auto &uniformName : uniformNamesList ) {
201 const auto un =
new char[ strlen(uniformName) + 1];
202 strncpy(un, uniformName, strlen(uniformName));
203 un[strlen(uniformName)] =
'\0';
204 _uniformNames.push_back(un);
207 _uniformIndices =
new GLuint[_numUniforms];
208 _uniformOffsets =
new GLint[_numUniforms];
217 _moveFromSource(src);
223 _moveFromSource(src);
235 _buffer =
new GLubyte[ _blockSize ];
237 glGetUniformIndices(shaderProgram->
getShaderProgramHandle(), _numUniforms, &_uniformNames[0], _uniformIndices);
238 glGetActiveUniformsiv(shaderProgram->
getShaderProgramHandle(), _numUniforms, _uniformIndices, GL_UNIFORM_OFFSET, _uniformOffsets);
240 glGenBuffers(1, &_ubod);
242 glBufferData(GL_UNIFORM_BUFFER, _blockSize,
nullptr, GL_DYNAMIC_DRAW);
244 _bindingPoint = bindingPoint;
245 glBindBufferBase(GL_UNIFORM_BUFFER, _bindingPoint, _ubod);
256 if(offset < _numUniforms) {
257 memcpy(_buffer + _uniformOffsets[offset], src, len);
259 CSCI441::LogUtils::logError(
"[ERROR]: Offset %d exceeds size of Uniform Block %s which is %d\n", offset, _blockName, _numUniforms);
266 for(GLuint i = 0; i < _numUniforms; i++) {
267 if( strcmp(_uniformNames[i], UNIFORM_NAME) == 0 ) {
268 memcpy( _buffer + _uniformOffsets[i], src, len );
280 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLboolean));
285 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLint));
290 copyToBuffer(UNIFORM_NAME, &value,
sizeof(GLfloat));
295 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec),
sizeof(glm::vec3));
300 copyToBuffer(UNIFORM_NAME, glm::value_ptr(vec),
sizeof(glm::vec4));
305 copyToBuffer(UNIFORM_NAME, glm::value_ptr(mtx),
sizeof(glm::mat4));
310 copyToBuffer(UNIFORM_NAME, pArray,
sizeof(GLint) * count);
315 copyToBuffer(UNIFORM_NAME, pArray,
sizeof(glm::ivec4) * count);
319 glBindBuffer(GL_UNIFORM_BUFFER, _ubod);
324 glBufferSubData(GL_UNIFORM_BUFFER, 0, _blockSize, _buffer);
327inline void CSCI441::UniformBufferObject::_cleanupSelf() {
328 glDeleteBuffers(1, &_ubod);
331 for(GLuint i = 0; i < _numUniforms; i++) {
332 delete[] _uniformNames[i];
334 _uniformNames.clear();
336 delete[] _uniformIndices;
337 _uniformIndices =
nullptr;
339 delete[] _uniformOffsets;
340 _uniformOffsets =
nullptr;
346 _blockName =
nullptr;
354inline void CSCI441::UniformBufferObject::_moveFromSource(UniformBufferObject &src) {
355 _blockName = src._blockName;
356 src._blockName =
nullptr;
358 _numUniforms = src._numUniforms;
359 src._numUniforms = 0;
361 _uniformNames = std::move(src._uniformNames);
362 src._uniformNames.clear();
364 _uniformIndices = src._uniformIndices;
365 src._uniformIndices =
nullptr;
367 _uniformOffsets = src._uniformOffsets;
368 src._uniformOffsets =
nullptr;
370 _blockSize = src._blockSize;
373 _buffer = src._buffer;
374 src._buffer =
nullptr;
376 _bindingPoint = src._bindingPoint;
377 src._bindingPoint = 0;
Class to work with OpenGL 4.0+ Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:37
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:1383
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1529
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1337
void logError(const char *MSG,...)
log a message to both the standard error stream and file
Definition: LogUtils.hpp:128
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17