]> git.tdb.fi Git - libs/gl.git/blob - source/core/uniformblock.cpp
f114ea584d04b7ff35ef550348febd4f9c38585d
[libs/gl.git] / source / core / 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 DefaultUniformBlock::DefaultUniformBlock()
18 {
19         static Require _req(ARB_shader_objects);
20 }
21
22 void DefaultUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
23 {
24         if(info.block->bind_point>=0)
25                 throw invalid_argument("DefaultUniformBlock::attach");
26
27         attach(info.location, uni);
28 }
29
30 void DefaultUniformBlock::attach(int index, const Uniform &uni)
31 {
32         if(index<0)
33                 return;
34
35         if(static_cast<unsigned>(index)>=uniforms.size())
36                 uniforms.resize(index+1, 0);
37         uniforms[index] = &uni;
38 }
39
40 void DefaultUniformBlock::apply(int index) const
41 {
42         if(index>=0)
43                 throw invalid_argument("DefaultUniformBlock::apply");
44
45         for(unsigned i=0; i<uniforms.size(); ++i)
46                 if(uniforms[i])
47                         uniforms[i]->apply(i);
48 }
49
50
51 BufferBackedUniformBlock::BufferBackedUniformBlock(unsigned s):
52         size(s),
53         data(size),
54         buf_range(0)
55 {
56         static Require _req(ARB_shader_objects);
57         static Require _req2(ARB_uniform_buffer_object);
58
59         if(!size)
60                 throw invalid_argument("BufferBackedUniformBlock::BufferBackedUniformBlock");
61 }
62
63 BufferBackedUniformBlock::~BufferBackedUniformBlock()
64 {
65         delete buf_range;
66 }
67
68 unsigned BufferBackedUniformBlock::get_alignment() const
69 {
70         return BufferRange::get_uniform_buffer_alignment();
71 }
72
73 void BufferBackedUniformBlock::location_changed(Buffer *buf, unsigned off, unsigned) const
74 {
75         delete buf_range;
76         buf_range = buf->create_range(off, size);
77 }
78
79 void BufferBackedUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
80 {
81         if(info.block->bind_point<0)
82                 throw invalid_argument("BufferBackedUniformBlock::attach");
83
84         uni.store(info, &data[info.offset]);
85         dirty = true;
86 }
87
88 void BufferBackedUniformBlock::apply(int index) const
89 {
90         if(index<0)
91                 throw invalid_argument("BufferBackedUniformBlock::apply");
92         if(!get_buffer())
93                 throw invalid_operation("UniformBlock::apply");
94
95         refresh();
96         buf_range->bind_to(UNIFORM_BUFFER, index);
97 }
98
99 } // namespace GL
100 } // namespace Msp