#include <msp/gl/extensions/arb_buffer_storage.h>
#include <msp/gl/extensions/arb_direct_state_access.h>
#include <msp/gl/extensions/arb_map_buffer_range.h>
+#include <msp/gl/extensions/arb_vertex_buffer_object.h>
#include <msp/gl/extensions/khr_debug.h>
+#include <msp/gl/extensions/oes_mapbuffer.h>
#include <msp/strings/format.h>
#include "buffer.h"
-#include "deviceinfo.h"
#include "error.h"
-#include "misc.h"
-#include "vertexsetup.h"
using namespace std;
namespace Msp {
namespace GL {
+Buffer *Buffer::scratch_binding = 0;
+
Buffer::Buffer():
size(0),
allocated(false)
Buffer::~Buffer()
{
+ if(this==scratch_binding)
+ unbind_scratch();
glDeleteBuffers(1, &id);
}
glNamedBufferStorage(id, size, 0, flags);
else
{
- glBindBuffer(GL_ARRAY_BUFFER, id);
+ bind_scratch();
glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
}
allocated = true;
data(0);
}
-void Buffer::set_usage(BufferUsage)
-{
-}
-
void Buffer::data(const void *d)
{
if(size==0)
return sub_data(0, size, d);
if(ARB_direct_state_access)
- glNamedBufferData(id, size, d, STATIC_DRAW);
+ glNamedBufferData(id, size, d, GL_STATIC_DRAW);
else
{
- glBindBuffer(GL_ARRAY_BUFFER, id);
- glBufferData(GL_ARRAY_BUFFER, size, d, STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ bind_scratch();
+ glBufferData(GL_ARRAY_BUFFER, size, d, GL_STATIC_DRAW);
}
allocated = true;
}
-void Buffer::data(unsigned sz, const void *d)
-{
- if(size==0)
- storage(sz);
- else if(sz!=size)
- throw incompatible_data("Buffer::data");
-
- data(d);
-}
-
void Buffer::sub_data(unsigned off, unsigned sz, const void *d)
{
if(size==0)
glNamedBufferSubData(id, off, sz, d);
else
{
- glBindBuffer(GL_ARRAY_BUFFER, id);
+ bind_scratch();
glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
else
{
- glBindBuffer(GL_ARRAY_BUFFER, id);
+ bind_scratch();
void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return result;
}
}
return glUnmapNamedBuffer(id);
else if(OES_mapbuffer)
{
- glBindBuffer(GL_ARRAY_BUFFER, id);
+ bind_scratch();
bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return result;
}
else
#endif
}
+void Buffer::bind_scratch()
+{
+ if(scratch_binding!=this)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, id);
+ scratch_binding = this;
+ }
+}
+
+void Buffer::unbind_scratch()
+{
+ if(scratch_binding)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ scratch_binding = 0;
+ }
+}
+
} // namespace GL
} // namespace Msp