]> git.tdb.fi Git - libs/gl.git/blob - source/uniformblock.cpp
Remove separate element_buffer from Renderer, get it from mesh instead
[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         size(0),
19         buf_range(0)
20 {
21         static Require _req(ARB_shader_objects);
22 }
23
24 UniformBlock::UniformBlock(unsigned s):
25         size(s),
26         buf_range(0)
27 {
28         static Require _req(ARB_uniform_buffer_object);
29
30         if(!size)
31                 throw invalid_argument("UniformBlock::UniformBlock");
32         data.resize(size);
33 }
34
35 UniformBlock::~UniformBlock()
36 {
37         delete buf_range;
38 }
39
40 unsigned UniformBlock::get_alignment() const
41 {
42         return BufferRange::get_uniform_buffer_alignment();
43 }
44
45 void UniformBlock::offset_changed()
46 {
47         delete buf_range;
48         buf_range = 0;
49 }
50
51 void UniformBlock::upload_data(char *target) const
52 {
53         if(!buf_range)
54                 buf_range = new BufferRange(*get_buffer(), get_offset(), size);
55
56         if(target)
57                 copy(data.begin(), data.end(), target);
58         else
59                 buf_range->data(&data[0]);
60 }
61
62 void UniformBlock::attach(int index, const Uniform &uni)
63 {
64         if(size)
65                 throw invalid_operation("UniformBlock::attach");
66
67         uniforms[index] = &uni;
68 }
69
70 void UniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
71 {
72         if(size)
73         {
74                 uni.store(info, &data[info.location]);
75                 dirty = true;
76         }
77         else
78                 uniforms[info.location] = &uni;
79 }
80
81 void UniformBlock::apply(int index) const
82 {
83         if((index>=0) != (size>0))
84                 throw invalid_operation("UniformBlock::apply");
85
86         if(size)
87         {
88                 if(!get_buffer())
89                         throw invalid_operation("UniformBlock::apply");
90
91                 if(dirty)
92                         update_buffer();
93                 buf_range->bind_to(UNIFORM_BUFFER, index);
94         }
95         else
96         {
97                 for(map<int, const Uniform *>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
98                         i->second->apply(i->first);
99         }
100 }
101
102 } // namespace GL
103 } // namespace Msp