]> git.tdb.fi Git - libs/gl.git/blob - source/uniformblock.cpp
Move extension requirements from ProgramData to UniformBlock
[libs/gl.git] / source / uniformblock.cpp
1 #include <stdexcept>
2 #include <msp/gl/extensions/arb_shader_objects.h>
3 #include <msp/gl/extensions/arb_uniform_buffer_object.h>
4 #include "buffer.h"
5 #include "color.h"
6 #include "error.h"
7 #include "matrix.h"
8 #include "uniform.h"
9 #include "uniformblock.h"
10 #include "vector.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 UniformBlock::UniformBlock():
18         buf_range(0)
19 {
20         static Require _req(ARB_shader_objects);
21 }
22
23 UniformBlock::UniformBlock(unsigned s):
24         size(s),
25         data(size),
26         buf_range(0)
27 {
28         static Require _req(ARB_uniform_buffer_object);
29 }
30
31 UniformBlock::~UniformBlock()
32 {
33         delete buf_range;
34 }
35
36 unsigned UniformBlock::get_alignment() const
37 {
38         return BufferRange::get_uniform_buffer_alignment();
39 }
40
41 void UniformBlock::offset_changed()
42 {
43         delete buf_range;
44         buf_range = 0;
45 }
46
47 void UniformBlock::upload_data() const
48 {
49         if(!buf_range)
50                 buf_range = new BufferRange(*get_buffer(), get_offset(), size);
51         buf_range->data(&data[0]);
52 }
53
54 void UniformBlock::attach(int index, const Uniform &uni)
55 {
56         uniforms[index] = &uni;
57 }
58
59 void UniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
60 {
61         uniforms[info.location] = &uni;
62         if(get_buffer())
63         {
64                 uni.store(info, &data[info.location]);
65                 dirty = true;
66         }
67 }
68
69 void UniformBlock::apply(int index) const
70 {
71         if((index>=0) != (get_buffer()!=0))
72                 throw invalid_operation("UniformBlock::apply");
73
74         if(get_buffer())
75         {
76                 if(dirty)
77                         update_buffer();
78                 buf_range->bind_to(UNIFORM_BUFFER, index);
79         }
80         else
81         {
82                 for(map<int, const Uniform *>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
83                         i->second->apply(i->first);
84         }
85 }
86
87 } // namespace GL
88 } // namespace Msp