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