Backported commits 145524a and 7785b4b from minor into default (Added SpriteBatch:flush, deprecated SpriteBatch:bind/unbind, SpriteBatch:flush is called implicitly when the spritebatch is drawn.)

This commit is contained in:
Alex Szpakowski
2014-06-17 21:52:56 -03:00
parent b9cd93e071
commit f0fa63ba47
6 changed files with 104 additions and 84 deletions
+33 -26
View File
@@ -46,8 +46,10 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
, size(size)
, next(0)
, color(0)
, array_buf(0)
, element_buf(0)
, array_buf(nullptr)
, element_buf(nullptr)
, buffer_used_offset(0)
, buffer_used_size(0)
{
if (size <= 0)
throw love::Exception("Invalid SpriteBatch size.");
@@ -160,18 +162,12 @@ void SpriteBatch::clear()
next = 0;
}
void *SpriteBatch::lock()
void SpriteBatch::flush()
{
VertexBuffer::Bind bind(*array_buf);
array_buf->unmap(buffer_used_offset, buffer_used_size);
return array_buf->map();
}
void SpriteBatch::unlock()
{
VertexBuffer::Bind bind(*array_buf);
array_buf->unmap();
buffer_used_offset = buffer_used_size = 0;
}
void SpriteBatch::setTexture(Texture *newtexture)
@@ -220,33 +216,31 @@ void SpriteBatch::setBufferSize(int newsize)
return;
// Map (lock) the old VertexBuffer to get a pointer to its data.
void *old_data = lock();
void *old_data = nullptr;
{
VertexBuffer::Bind bind(*array_buf);
old_data = array_buf->map();
}
size_t vertex_size = sizeof(Vertex) * 4 * newsize;
VertexBuffer *new_array_buf = 0;
VertexIndex *new_element_buf = 0;
void *new_data = 0;
VertexBuffer *new_array_buf = nullptr;
VertexIndex *new_element_buf = nullptr;
try
{
new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage());
new_element_buf = new VertexIndex(newsize);
// VBO::map can throw an exception. Also we want to scope the bind.
VertexBuffer::Bind bind(*new_array_buf);
new_data = new_array_buf->map();
}
catch (love::Exception &)
{
delete new_array_buf;
delete new_element_buf;
unlock();
throw;
}
// Copy as much of the old data into the new VertexBuffer as can fit.
memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size));
new_array_buf->fill(0, sizeof(Vertex) * 4 * std::min(newsize, size), old_data);
// We don't need to unmap the old VertexBuffer since we're deleting it.
delete array_buf;
@@ -258,8 +252,8 @@ void SpriteBatch::setBufferSize(int newsize)
next = std::min(next, newsize);
// But we should unmap (unlock) the new one!
unlock();
// The new VertexBuffer isn't mapped, so we should reset these variables.
buffer_used_offset = buffer_used_size = 0;
}
int SpriteBatch::getBufferSize() const
@@ -269,7 +263,7 @@ int SpriteBatch::getBufferSize() const
void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{
const size_t vertex_offset = offsetof(Vertex, x);
const size_t pos_offset = offsetof(Vertex, x);
const size_t texel_offset = offsetof(Vertex, s);
const size_t color_offset = offsetof(Vertex, r);
@@ -288,6 +282,10 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
VertexBuffer::Bind array_bind(*array_buf);
VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer());
// Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.)
array_buf->unmap(buffer_used_offset, buffer_used_size);
buffer_used_offset = buffer_used_size = 0;
Color curcolor = gl.getColor();
// Apply per-sprite color, if a color is set.
@@ -298,7 +296,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(vertex_offset));
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(pos_offset));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
@@ -322,9 +320,18 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
void SpriteBatch::addv(const Vertex *v, int index)
{
static const int sprite_size = 4 * sizeof(Vertex); // bytecount
static const size_t sprite_size = 4 * sizeof(Vertex); // bytecount
VertexBuffer::Bind bind(*array_buf);
// Always keep the VBO mapped when adding data for now (it'll be unmapped
// on draw.)
array_buf->map();
array_buf->fill(index * sprite_size, sprite_size, v);
buffer_used_offset = std::min(buffer_used_offset, index * sprite_size);
buffer_used_size = std::max(buffer_used_size, (index + 1) * sprite_size - buffer_used_offset);
}
void SpriteBatch::setColorv(Vertex *v, const Color &color)