]> git.tdb.fi Git - libs/gl.git/blob - source/bufferable.cpp
Add a class to negotiate the storage of multiple objects in a buffer
[libs/gl.git] / source / bufferable.cpp
1 #include <stdexcept>
2 #include "buffer.h"
3 #include "bufferable.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 Bufferable::Bufferable():
11         buffer(0),
12         buffer_offset(0),
13         next_in_buffer(0),
14         prev_in_buffer(0),
15         dirty(false)
16 { }
17
18 Bufferable::~Bufferable()
19 {
20         unlink_from_buffer();
21 }
22
23 void Bufferable::use_buffer(Buffer *buf, Bufferable *prev)
24 {
25         if(prev && buf!=prev->buffer)
26                 throw invalid_argument("Bufferable::use_buffer");
27
28         if(buffer)
29                 unlink_from_buffer();
30
31         buffer = buf;
32         if(buffer)
33         {
34                 prev_in_buffer = prev;
35                 if(prev_in_buffer)
36                         prev_in_buffer->next_in_buffer = this;
37         }
38
39         update_buffer_offsets();
40 }
41
42 void Bufferable::unlink_from_buffer()
43 {
44         if(prev_in_buffer)
45                 prev_in_buffer->next_in_buffer = next_in_buffer;
46         if(next_in_buffer)
47         {
48                 next_in_buffer->prev_in_buffer = prev_in_buffer;
49                 next_in_buffer->update_buffer_offsets();
50         }
51         prev_in_buffer = 0;
52         next_in_buffer = 0;
53 }
54
55 void Bufferable::update_buffer_offsets()
56 {
57         unsigned offset = 0;
58         if(prev_in_buffer)
59                 offset = prev_in_buffer->buffer_offset+prev_in_buffer->get_data_size();
60
61         if(offset!=buffer_offset)
62         {
63                 buffer_offset = offset;
64                 dirty = true;
65         }
66
67         if(next_in_buffer)
68                 next_in_buffer->update_buffer_offsets();
69 }
70
71 void Bufferable::update_buffer_data() const
72 {
73         const Bufferable *first = this;
74         for(; first->prev_in_buffer; first=first->prev_in_buffer) ;
75
76         unsigned total_size = 0;
77         for(const Bufferable *b=first; b; b=b->next_in_buffer)
78                 total_size += b->get_data_size();
79
80         buffer->data(total_size, 0);
81         for(const Bufferable *b=first; b; b=b->next_in_buffer)
82         {
83                 buffer->sub_data(b->buffer_offset, b->get_data_size(), b->get_data());
84                 b->dirty = false;
85         }
86 }
87
88 } // namespace GL
89 } // namespace Msp