CSCI441 OpenGL Library 5.17.0
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
86 [[maybe_unused]] void setupWithShaderProgram( ShaderProgram *shaderProgram, GLuint bindingPoint );
87
94 [[maybe_unused]] void copyToOffset( unsigned int offset, void* addr, size_t len );
95
102 [[maybe_unused]] void copyToBuffer( const char* UNIFORM_NAME, void* addr, size_t len );
103
107 void bindBuffer() const;
108
112 [[maybe_unused]] void bufferSubData() const;
113
114 private:
115 char* _blockName;
116 std::vector<char*> _uniformNames;
117 GLint _blockSize;
118 GLubyte* _buffer;
119 GLuint _numUniforms;
120 GLuint* _uniformIndices;
121 GLint* _uniformOffsets;
122 GLuint _ubod;
123 GLuint _bindingPoint;
124
125 void _cleanupSelf();
126 void _moveFromSource(UniformBufferObject&);
127 };
128}
129
130//******************************************************************************
131
132[[maybe_unused]]
133inline CSCI441::UniformBufferObject::UniformBufferObject(const char* UNIFORM_BLOCK_NAME, std::initializer_list<const char*> uniformNamesList) {
134 _blockName = new char[strlen(UNIFORM_BLOCK_NAME) + 1];
135 strncpy(_blockName, UNIFORM_BLOCK_NAME, strlen(UNIFORM_BLOCK_NAME));
136
137 _numUniforms = uniformNamesList.size();
138
139 for(const auto &uniformName : uniformNamesList ) {
140 const auto un = new char[ strlen(uniformName) + 1];
141 strncpy(un, uniformName, strlen(uniformName));
142 _uniformNames.push_back(un);
143 }
144
145 _uniformIndices = new GLuint[_numUniforms];
146 _uniformOffsets = new GLint[_numUniforms];
147
148 _blockSize = 0;
149 _buffer = nullptr;
150 _bindingPoint = 0;
151 _ubod = 0;
152}
153
155 _moveFromSource(src);
156}
157
159 if (this != &src) { // guard against self movement
160 _cleanupSelf(); // cleanup existing UBO
161 _moveFromSource(src); // move source UBO
162 }
163 return *this; // return ourselves
164}
165
167 _cleanupSelf();
168}
169
170[[maybe_unused]]
171inline void CSCI441::UniformBufferObject::setupWithShaderProgram( ShaderProgram *shaderProgram, GLuint bindingPoint ) {
172 _blockSize = shaderProgram->getUniformBlockSize( _blockName );
173 _buffer = new GLubyte[ _blockSize ];
174
175 glGetUniformIndices(shaderProgram->getShaderProgramHandle(), _numUniforms, &_uniformNames[0], _uniformIndices);
176 glGetActiveUniformsiv(shaderProgram->getShaderProgramHandle(), _numUniforms, _uniformIndices, GL_UNIFORM_OFFSET, _uniformOffsets);
177
178 glGenBuffers(1, &_ubod);
179 bindBuffer();
180 glBufferData(GL_UNIFORM_BUFFER, _blockSize, nullptr, GL_DYNAMIC_DRAW);
181
182 _bindingPoint = bindingPoint;
183 glBindBufferBase(GL_UNIFORM_BUFFER, _bindingPoint, _ubod);
184 shaderProgram->setUniformBlockBinding(_blockName, _bindingPoint);
185}
186
187[[maybe_unused]]
188inline void CSCI441::UniformBufferObject::copyToOffset( const unsigned int offset, void* addr, const size_t len ) {
189 if(offset < _numUniforms) {
190 memcpy(_buffer + _uniformOffsets[offset], addr, len);
191 } else {
192 fprintf(stderr, "[ERROR]: Offset %d exceeds size of Uniform Block %s which is %d\n", offset, _blockName, _numUniforms);
193 }
194}
195
196[[maybe_unused]]
197inline void CSCI441::UniformBufferObject::copyToBuffer( const char* UNIFORM_NAME, void* addr, const size_t len ) {
198 bool found = false;
199 for(GLuint i = 0; i < _numUniforms; i++) {
200 if( strcmp(_uniformNames[i], UNIFORM_NAME) == 0 ) {
201 memcpy( _buffer + _uniformOffsets[i], addr, len );
202 found = true;
203 break;
204 }
205 }
206 if(!found) {
207 fprintf(stderr, "[ERROR]: Uniform Name \"%s\" not found within Uniform Block \"%s\"\n", UNIFORM_NAME, _blockName);
208 }
209}
210
212 glBindBuffer(GL_UNIFORM_BUFFER, _ubod);
213}
214
215[[maybe_unused]]
217 glBufferSubData(GL_UNIFORM_BUFFER, 0, _blockSize, _buffer);
218}
219
220inline void CSCI441::UniformBufferObject::_cleanupSelf() {
221 glDeleteBuffers(1, &_ubod);
222 _ubod = 0;
223
224 for(GLuint i = 0; i < _numUniforms; i++) {
225 delete[] _uniformNames[i];
226 }
227 _uniformNames.clear();
228
229 delete[] _uniformIndices;
230 _uniformIndices = nullptr;
231
232 delete[] _uniformOffsets;
233 _uniformOffsets = nullptr;
234
235 delete[] _buffer;
236 _buffer = nullptr;
237
238 delete[] _blockName;
239 _blockName = nullptr;
240
241 _numUniforms = 0;
242 _blockSize = 0;
243 _bindingPoint = 0;
244}
245
246
247inline void CSCI441::UniformBufferObject::_moveFromSource(UniformBufferObject &src) {
248 _blockName = src._blockName;
249 src._blockName = nullptr;
250
251 _numUniforms = src._numUniforms;
252 src._numUniforms = 0;
253
254 _uniformNames = std::move(src._uniformNames);
255 src._uniformNames.clear();
256
257 _uniformIndices = src._uniformIndices;
258 src._uniformIndices = nullptr;
259
260 _uniformOffsets = src._uniformOffsets;
261 src._uniformOffsets = nullptr;
262
263 _blockSize = src._blockSize;
264 src._blockSize = 0;
265
266 _buffer = src._buffer;
267 src._buffer = nullptr;
268
269 _bindingPoint = src._bindingPoint;
270 src._bindingPoint = 0;
271
272 _ubod = src._ubod;
273 src._ubod = 0;
274}
275
276#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:1380
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1526
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1334
Storage of UBO related data.
Definition: UniformBufferObject.hpp:34
void bindBuffer() const
binds UBO object to UBO buffer
Definition: UniformBufferObject.hpp:211
~UniformBufferObject()
Deletes the UBO from the GPU and frees all memory on the CPU.
Definition: UniformBufferObject.hpp:166
UniformBufferObject(UniformBufferObject &unused)=delete
void copyToOffset(unsigned int offset, void *addr, 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:188
void copyToBuffer(const char *UNIFORM_NAME, void *addr, 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:197
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:171
void bufferSubData() const
transfers UBO data to UBO buffer
Definition: UniformBufferObject.hpp:216
UniformBufferObject & operator=(UniformBufferObject &unused)=delete
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17