data.push_back(i);
}
-void Batch::upload_data() const
-{
- get_buffer()->sub_data(get_offset(), data.size(), &data[0]);
-}
-
unsigned Batch::get_index_size() const
{
if(data_type==UNSIGNED_SHORT)
private:
void append_index(unsigned);
virtual unsigned get_data_size() const { return data.size(); }
- virtual void upload_data() const;
+ virtual const void *get_data_pointer() const { return &data[0]; }
unsigned get_index_size() const;
public:
unsigned size() const { return data.size()/get_index_size(); }
the buffer is actually used. */
}
-void Bufferable::update_buffer() const
+bool Bufferable::resize_buffer() const
{
- BindRestore bind(buffer, buffer->get_type());
if(offset+get_data_size()>=buffer->get_size())
{
const Bufferable *last = this;
if(total_size>buffer->get_size())
{
buffer->data(total_size, 0);
- /* Resizing the buffer invalidates its contents. Non-dirty data may
- be in use, so reupload it. */
- for(const Bufferable *b=last; b; b=b->prev_in_buffer)
- if(!b->dirty)
- b->upload_data();
+ return true;
}
}
+ return false;
+}
+
+void Bufferable::update_buffer() const
+{
+ BindRestore bind(buffer, buffer->get_type());
+ if(resize_buffer())
+ {
+ /* Resizing the buffer invalidates its contents. Non-dirty data may
+ be in use, so reupload it. */
+ for(const Bufferable *b=prev_in_buffer; b; b=b->prev_in_buffer)
+ if(!b->dirty)
+ b->upload_data();
+ for(const Bufferable *b=next_in_buffer; b; b=b->next_in_buffer)
+ if(!b->dirty)
+ b->upload_data();
+ }
+
upload_data();
dirty = false;
}
+void Bufferable::upload_data() const
+{
+ buffer->sub_data(offset, get_data_size(), get_data_pointer());
+}
+
} // namespace GL
} // namespace Msp
/** Returns the amount of data to be stored in the buffer, in bytes. */
virtual unsigned get_data_size() const = 0;
+ /** Returns a pointer to the start of data in client memory. */
+ virtual const void *get_data_pointer() const = 0;
+
/** Returns the alignment required for the data, in bytes. The offset is
guaranteed to be a multiple of this. */
virtual unsigned get_alignment() const { return 1; }
/** Called when the offset for the data has changed. */
virtual void offset_changed() { }
+private:
+ bool resize_buffer() const;
+
+protected:
/** Resizes the buffer if necessary and calls upload_data(). */
void update_buffer() const;
/** Uploads data to the buffer. */
- virtual void upload_data() const = 0;
+ virtual void upload_data() const;
};
} // namespace GL
private:
virtual unsigned get_data_size() const { return size; }
+ virtual const void *get_data_pointer() const { return &data[0]; }
virtual unsigned get_alignment() const;
virtual void offset_changed();
virtual void upload_data() const;
return data.size()*sizeof(float);
}
-void VertexArray::upload_data() const
-{
- get_buffer()->sub_data(get_offset(), get_data_size(), &data[0]);
-}
-
void VertexArray::apply() const
{
if(format.empty())
float *modify(unsigned);
private:
virtual unsigned get_data_size() const;
- virtual void upload_data() const;
+ virtual const void *get_data_pointer() const { return &data[0]; }
public:
unsigned size() const { return data.size()/stride; }