2 #include <msp/gl/extensions/arb_buffer_storage.h>
3 #include <msp/gl/extensions/arb_direct_state_access.h>
4 #include <msp/gl/extensions/arb_map_buffer_range.h>
5 #include <msp/gl/extensions/arb_vertex_buffer_object.h>
6 #include <msp/gl/extensions/khr_debug.h>
7 #include <msp/gl/extensions/oes_mapbuffer.h>
8 #include <msp/strings/format.h>
17 Buffer *Buffer::scratch_binding = 0;
22 static Require _req(ARB_vertex_buffer_object);
24 if(ARB_direct_state_access)
25 glCreateBuffers(1, &id);
32 if(this==scratch_binding)
34 glDeleteBuffers(1, &id);
37 void Buffer::storage(unsigned sz)
42 throw incompatible_data("Buffer::storage");
46 throw invalid_argument("Buffer::storage");
50 if(ARB_buffer_storage)
52 static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
53 if(ARB_direct_state_access)
54 glNamedBufferStorage(id, size, 0, flags);
58 glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
61 else if(ARB_direct_state_access)
62 glNamedBufferData(id, size, 0, GL_STATIC_DRAW);
66 glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);
70 void Buffer::data(const void *d)
72 return sub_data(0, size, d);
75 void Buffer::sub_data(unsigned off, unsigned sz, const void *d)
78 throw invalid_operation("Buffer::sub_data");
80 if(ARB_direct_state_access)
81 glNamedBufferSubData(id, off, sz, d);
85 glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
89 void Buffer::require_size(unsigned req_sz) const
92 throw buffer_too_small(format("buffer has %d bytes; %d required", size, req_sz));
97 static Require _req(ARB_map_buffer_range);
99 if(ARB_direct_state_access)
100 return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
104 void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
111 // TODO check if it's mapped
112 if(ARB_direct_state_access)
113 return glUnmapNamedBuffer(id);
114 else if(OES_mapbuffer)
117 bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
124 void Buffer::set_debug_name(const string &name)
128 glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
134 void Buffer::bind_scratch()
136 if(scratch_binding!=this)
138 glBindBuffer(GL_ARRAY_BUFFER, id);
139 scratch_binding = this;
143 void Buffer::unbind_scratch()
147 glBindBuffer(GL_ARRAY_BUFFER, 0);