From 85c82f93f4874bcf0b04332c9abb62cd2a5b181b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 17 Dec 2010 20:55:26 +0000 Subject: [PATCH] Restore old buffer binding when setting data Rename buffer binding functions to be more in line with others Use a RefPtr to store buffer in VertexArray Use vertex buffer by default Track VertexArray dirty state internally Remove the deprecated vertexbuffer.h --- source/buffer.cpp | 43 +++++++++++++-------- source/buffer.h | 24 ++++++------ source/immediate.cpp | 4 +- source/vertexarray.cpp | 70 +++++++++++++++++++---------------- source/vertexarray.h | 13 ++++--- source/vertexarraybuilder.cpp | 5 --- source/vertexarraybuilder.h | 1 - source/vertexbuffer.h | 31 ---------------- 8 files changed, 90 insertions(+), 101 deletions(-) delete mode 100644 source/vertexbuffer.h diff --git a/source/buffer.cpp b/source/buffer.cpp index 17ae494f..51f4873f 100644 --- a/source/buffer.cpp +++ b/source/buffer.cpp @@ -28,18 +28,6 @@ Buffer::~Buffer() glDeleteBuffersARB(1, &id); } -void Buffer::bind(BufferType t) const -{ - glBindBufferARB(t, id); - binding(t) = this; -} - -void Buffer::maybe_bind() const -{ - if(binding(type)!=this) - bind(); -} - void Buffer::set_usage(BufferUsage u) { usage = u; @@ -47,17 +35,31 @@ void Buffer::set_usage(BufferUsage u) void Buffer::data(unsigned size, const void *d) { - maybe_bind(); + const Buffer *old = current(type); + bind(); glBufferDataARB(type, size, d, usage); + restore(old, type); } void Buffer::sub_data(unsigned offset, unsigned size, const void *d) { - maybe_bind(); + const Buffer *old = current(type); + bind(); glBufferSubDataARB(type, offset, size, d); + restore(old, type); +} + +void Buffer::bind_to(BufferType t) const +{ + const Buffer *&ptr = binding(t); + if(ptr!=this) + { + glBindBufferARB(t, id); + ptr = this; + } } -void Buffer::unbind(BufferType type) +void Buffer::unbind_from(BufferType type) { const Buffer *&ptr = binding(type); if(ptr) @@ -79,6 +81,17 @@ const Buffer *&Buffer::binding(BufferType type) } } +void Buffer::restore(const Buffer *buf, BufferType type) +{ + if(buf!=current(type)) + { + if(buf) + buf->bind_to(type); + else + unbind_from(type); + } +} + const Buffer *Buffer::bound[4] = { 0, 0, 0, 0 }; } // namespace GL diff --git a/source/buffer.h b/source/buffer.h index 7e57cf02..7aea9665 100644 --- a/source/buffer.h +++ b/source/buffer.h @@ -52,19 +52,10 @@ public: Buffer(BufferType); ~Buffer(); - /** Binds the buffer in its default slot. */ - void bind() const { bind(type); } - - /** Binds the buffer in an alternate slot. */ - void bind(BufferType) const; - private: - void maybe_bind() const; + const Buffer *maybe_bind() const; public: - /** Unbinds the buffer from its default slot. */ - void unbind() const { unbind(type); } - /** Sets the usage hint of the buffer. It will take effect the next time the buffer's contents are defined. */ void set_usage(BufferUsage); @@ -77,9 +68,20 @@ public: not be changed with this call. */ void sub_data(unsigned, unsigned, const void *); - static void unbind(BufferType); + /** Binds the buffer in its default slot. */ + void bind() const { bind_to(type); } + + /** Binds the buffer in an alternate slot. */ + void bind_to(BufferType) const; + + /** Unbinds the buffer from its default slot. */ + void unbind() const { unbind_from(type); } + + static const Buffer *current(BufferType t) { return binding(t); } + static void unbind_from(BufferType); private: static const Buffer *&binding(BufferType); + static void restore(const Buffer *, BufferType); }; } // namespace GL diff --git a/source/immediate.cpp b/source/immediate.cpp index a387d71b..3d808d32 100644 --- a/source/immediate.cpp +++ b/source/immediate.cpp @@ -13,7 +13,9 @@ namespace GL { Immediate::Immediate(VertexFormat f): PrimitiveBuilder(array), array(f) -{ } +{ + array.use_vertex_buffer(0); +} void Immediate::reset() { diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index 395f217a..54de0c0d 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -6,50 +6,46 @@ Distributed under the LGPL */ #include "arb_vertex_program.h" +#include "buffer.h" #include "extension.h" #include "gl.h" #include "version_1_2.h" #include "version_1_3.h" #include "vertexarray.h" -#include "vertexbuffer.h" using namespace std; namespace Msp { namespace GL { +VertexArray::ArrayMask VertexArray::enabled_arrays; + VertexArray::VertexArray(const VertexFormat &f): - vbuf(0), - own_vbuf(false) + defer_vbuf(true), + dirty(false) { reset(f); } VertexArray::~VertexArray() -{ - if(own_vbuf) - delete vbuf; -} +{ } void VertexArray::use_vertex_buffer() { - if(vbuf && own_vbuf) + if(vbuf) return; vbuf = new Buffer(ARRAY_BUFFER); - own_vbuf = true; - - update_data(); + defer_vbuf = false; + dirty = true; } void VertexArray::use_vertex_buffer(Buffer *b) { - if(own_vbuf) - delete vbuf; vbuf = b; - own_vbuf = false; - - update_data(); + vbuf.keep(); + defer_vbuf = false; + dirty = true; } void VertexArray::reserve(unsigned n) @@ -89,9 +85,16 @@ void VertexArray::apply() const throw InvalidState("Trying to apply a vertex array with no data"); if(vbuf) - vbuf->bind(); + { + vbuf->bind_to(ARRAY_BUFFER); + if(dirty) + { + vbuf->data(data.size()*sizeof(float), &data[0]); + dirty = false; + } + } - const float *base = vbuf?0:&data[0]; + const float *base = (vbuf ? 0 : &data[0]); unsigned offset = 0; ArrayMask found; unsigned bpv = stride*sizeof(float); @@ -170,28 +173,31 @@ void VertexArray::apply() const glClientActiveTexture(GL_TEXTURE0); if(vbuf) - vbuf->unbind(); + Buffer::unbind_from(ARRAY_BUFFER); } -/** -Updates the VertexArray data to the VertexBuffer tied to the array, if any. -*/ -void VertexArray::update_data() +float *VertexArray::append() { - if(vbuf) - { - vbuf->data(data.size()*sizeof(float), &data[0]); - vbuf->unbind(); - } + data.insert(data.end(), stride, 0.0f); + set_dirty(); + return &*(data.end()-stride); } -float *VertexArray::append() +float *VertexArray::modify(unsigned i) { - data.insert(data.end(), stride, 0.0f); - return &*data.end()-stride; + set_dirty(); + return &data[0]+i*stride; } -VertexArray::ArrayMask VertexArray::enabled_arrays; +void VertexArray::set_dirty() +{ + dirty = true; + if(defer_vbuf) + { + vbuf = new Buffer(ARRAY_BUFFER); + defer_vbuf = false; + } +} VertexArray::ArrayMask::ArrayMask() diff --git a/source/vertexarray.h b/source/vertexarray.h index c7609afe..079c2234 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -51,8 +51,11 @@ private: VertexFormat format; std::vector data; unsigned stride; - Buffer *vbuf; - bool own_vbuf; + RefPtr vbuf; + bool defer_vbuf; + mutable bool dirty; + + static ArrayMask enabled_arrays; VertexArray(const VertexArray &); VertexArray &operator=(const VertexArray &); @@ -69,13 +72,13 @@ public: void clear(); void reset(const VertexFormat &); void apply() const; - void update_data(); float *append(); - float *operator[](unsigned i) { return &data[0]+i*stride; } + float *modify(unsigned); + float *operator[](unsigned i) { return modify(i); } const float *operator[](unsigned i) const { return &data[0]+i*stride; } private: - static ArrayMask enabled_arrays; + void set_dirty(); }; void array_element(int); diff --git a/source/vertexarraybuilder.cpp b/source/vertexarraybuilder.cpp index c31a60a6..44b677f0 100644 --- a/source/vertexarraybuilder.cpp +++ b/source/vertexarraybuilder.cpp @@ -15,11 +15,6 @@ VertexArrayBuilder::VertexArrayBuilder(VertexArray &a): array(a) { } -VertexArrayBuilder::~VertexArrayBuilder() -{ - array.update_data(); -} - void VertexArrayBuilder::vertex_(const Vector4 &v) { float *ptr = array.append(); diff --git a/source/vertexarraybuilder.h b/source/vertexarraybuilder.h index b6af0b95..04cd5a27 100644 --- a/source/vertexarraybuilder.h +++ b/source/vertexarraybuilder.h @@ -25,7 +25,6 @@ private: VertexArrayBuilder(const VertexArrayBuilder &); public: VertexArrayBuilder(VertexArray &); - ~VertexArrayBuilder(); private: virtual void vertex_(const Vector4 &); diff --git a/source/vertexbuffer.h b/source/vertexbuffer.h deleted file mode 100644 index b0963fb3..00000000 --- a/source/vertexbuffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#ifndef MSP_GL_VERTEXBUFFER_H_ -#define MSP_GL_VERTEXBUFFER_H_ - -#include "buffer.h" - -namespace Msp { -namespace GL { - -/** -Deprecated. Equivalent to Buffer of type ARRAY_BUFFER. Retained for backwards -compatibility only. -*/ -class VertexBuffer: public Buffer -{ -public: - VertexBuffer(): Buffer(ARRAY_BUFFER) { } - - static void unbind() { Buffer::unbind(ARRAY_BUFFER); } -}; - -} // namespace GL -} // namespace Msp - -#endif -- 2.43.0