-
Notifications
You must be signed in to change notification settings - Fork 449
Expand file tree
/
Copy pathUniformBlockArray.h
More file actions
102 lines (76 loc) · 2.39 KB
/
UniformBlockArray.h
File metadata and controls
102 lines (76 loc) · 2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef UNIFORM_BLOCK_ARRAY_H
#define UNIFORM_BLOCK_ARRAY_H
//To use this file, you must include one of the glload headers before including this.
#include <string.h>
#include <vector>
namespace Framework
{
//This object can only be constructed after an OpenGL context has been created and initialized.
template<typename UniformBlockObject, int arrayCount>
class UniformBlockArray
{
public:
UniformBlockArray()
: m_storage()
, m_blockOffset(0)
{
int uniformBufferAlignSize = 0;
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniformBufferAlignSize);
m_blockOffset = sizeof(UniformBlockObject);
m_blockOffset += uniformBufferAlignSize -
(m_blockOffset % uniformBufferAlignSize);
int sizeMaterialUniformBuffer = m_blockOffset * arrayCount;
m_storage.resize(arrayCount * m_blockOffset, 0);
}
int size() const {return arrayCount;}
//The array offset should be multiplied by the array index to get the offset
//for a particular element.
int GetArrayOffset() const {return m_blockOffset;}
class BlockMemberReference
{
private:
BlockMemberReference(UniformBlockArray &uboArray, int blockIndex)
: m_array(uboArray)
, m_blockIndex(blockIndex)
{}
public:
~BlockMemberReference() {}
operator UniformBlockObject () const
{
UniformBlockObject theObject;
memcpy(&theObject,
&m_array.m_storage[m_blockIndex * m_array.m_blockOffset],
sizeof(UniformBlockObject));
return theObject;
}
BlockMemberReference & operator=(const UniformBlockObject &input)
{
memcpy(&m_array.m_storage[m_blockIndex * m_array.m_blockOffset],
&input, sizeof(UniformBlockObject));
return *this;
}
private:
UniformBlockArray &m_array;
int m_blockIndex;
friend class UniformBlockArray;
};
BlockMemberReference operator[] (size_t index)
{
assert(index < arrayCount);
return BlockMemberReference(*this, index);
}
GLuint CreateBufferObject()
{
GLuint bufferObject;
glGenBuffers(1, &bufferObject);
glBindBuffer(GL_UNIFORM_BUFFER, bufferObject);
glBufferData(GL_UNIFORM_BUFFER, m_storage.size(), &m_storage[0], GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
return bufferObject;
}
private:
std::vector<GLubyte> m_storage;
int m_blockOffset;
};
}
#endif //UNIFORM_BLOCK_ARRAY_H