matus-chochlik / oglplus

OGLplus is a collection of open-source, cross-platform libraries which implement an object-oriented facade over the OpenGL® (version 3 and higher) and also OpenAL® (version 1.1) and EGL (version 1.4) C-language APIs. It provides wrappers which automate resource and object management and make the use of these libraries in C++ safer and more convenient.
http://oglplus.org/
Boost Software License 1.0
491 stars 72 forks source link

Buffer::SubData has no mechanism for storing more than one type in the buffer #72

Closed jherico closed 10 years ago

jherico commented 10 years ago

In some instances I'd like to store both vertices and indices in a single buffer. I thought I'd be able to do so like this:

Buffer::SubData(BufferTarget::Array, 0, num_vertices, vertices); Buffer::SubData(BufferTarget::Array, indexOffset, num_indices, indices);

where vertices is the vertex type pointer, indices is a pointer to a bunch of ints, and indexOffset is sizeof(Vertex) * num_vertices.

This doesn't work, because SubData assumes that the offset value is a count of whatever type is being passed in. This is handy for homogenous buffers, but not for buffers containing heterogeneous types. It would be nice if the API provided additional calls that allow you to specify the exact byte offset for a buffer for use in situations like these.

matus-chochlik commented 10 years ago

I've added the BufferSize class storing the size of a GPU buffer in bytes and updated the Buffer and DSABuffer classes in the following way:

The BufferSize can be constructed in the following ways:

// default construction
BufferSize s0; // size 0[B]
// implicit construction from integral value
BufferSize s1(123); // 123[B]
// Size of N instances of T
BufferSize s2 = BufferSize::Of<GLfloat>(234); // 234*sizeof(GLfloat)[B]
// More complex sizes
BufferSize s3 = s0.Add<GLint>(10).Add<GLfloat>(20); // 10*sizeof(GLint) + 20*sizeof(GLfloat) [B]

I'll probably add some syntax sugar if I find something suitable and less verbose. The changes were made in commit 83c9d31978544407a7a81ab26695eb406d10edaa on the develop branch.

HTH

matus-chochlik commented 10 years ago

B.T.W. there is one other constructor usable in your case:

GLfloat* items = ...
unsigned num_items = ...
BufferSize s4(num_items, items);
// or
BufferSize s5<GLfloat>(num_items);

Now You should be able to rewrite your code like this:

Buffer::SubData(
    BufferTarget::Array,
    0,
    num_vertices,
    vertices
 );
Buffer::SubData(
    BufferTarget::Array,
    BufferSize(num_vertices, vertices),
    num_indices, indices
);