Reputation: 995
Ok,after a longer break I am a bit on a loss here. I am trying to use a persistent mapped buffer, split to 2 buffers to improve performance. If using it as one buffer, everything works fine, once using it as 2, it fails miserably. I am not sure what I am missing, but maybe someone can enlighten me. I read quite some tutorials and descriptions, but so far no luck understanding it any better or finding the answer to these questions.
To my setup, I have the following data:
Buffer[0] = Point.X;
Buffer[1] = Point.Y;
Buffer[2] = Point.Z;
Buffer[3] = U;
Buffer[4] = V;
Buffer[5] = Color.X;
Buffer[6] = Color.Y;
Buffer[7] = Color.Z;
Buffer[8] = Color.W;
in my approach without persistent buffers, I do this:
...
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * TotalSize, Buffer, GL_STREAM_DRAW);
...
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, StrideSize, 0);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, StrideSize, (void*)VertFloatSize);
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, StrideSize, (void*)(VertFloatSize+TexFloatSize));
...
glDrawArrays(Mode, 0, (BufferData.VertSize / FloatsPerVertex));
...
Now to the persistent part (I am leaving out fences and sync stuff here, since this doesn't seem to be a problem.):
GLbitfield PersistentBufferFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
GLsizeiptr BufferSize=(2 * BUFFER_SIZE);
glBindBuffer(GL_ARRAY_BUFFER, PMB);
glBufferStorage(GL_ARRAY_BUFFER, BufferSize, 0, PersistentBufferFlags);
Buffer = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, BufferSize, PersistentBufferFlags);
Now this already my first question- is this the right approach? Map it with one and use the offset of the size of the first buffer run to continue then from there with the data of the 2nd or should it be rather 2 mappings of the same storage like this? :
glBindBuffer(GL_ARRAY_BUFFER, PMB);
glBufferStorage(GL_ARRAY_BUFFER, BufferSize, 0, PersistentBufferFlags);
Buffer[0] = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, BUFFER_SIZE, PersistentBufferFlags)
Buffer[1] = (float*)glMapBufferRange(GL_ARRAY_BUFFER, BUFFER_SIZE, BUFFER_SIZE, PersistentBufferFlags)
I found no hint whats to be preferred or what's right or even wrong. How is it correctly split?
Then trying to draw with
glDrawArrays(Mode, 0, (BufferData.VertSize / FloatsPerVertex)); //Draw "first" buffer, everything works if only this one.
...next round...
glDrawArrays(Mode, offset_of_datasize_first_buffer, (BufferData.VertSize / FloatsPerVertex)); //Second part of the buffer, fails.
Not entirely sure here about the 2nd parameter, I find the explanation of it confusing:
Specifies the starting index in the enabled arrays.
Am I right that this should be too the offset size of the first buffer then in the second run?
Other than that I use the same setup as above, just without the glBufferData. So anyway, no matter which version above I use, it works if I use it only as 1 buffer, but if using it as 2, it very much looks like it ignores the data in the second part of the buffer. So this is my next question- is it even allowed to use a persistent buffer like this? Does it respect the interleaved setup done with glVertexAttribPointer or is it plain for verts only and solely?
Let me know if you need any more information or if something is not clear. Many thanks.
Upvotes: 0
Views: 507
Reputation: 2380
Second parameter is almost definitely giving you trouble. Is offset_of_datasize_first_buffer
an index or byte offset? Try offset_of_datasize_first_buffer / FloatsPerVertex
.
Also, you can rebind your attribute pointers and add BUFFER_SIZE
to the last parameter to set 0
index at the start of the second buffer.
Try to make sure that offset_of_datasize_first_buffer
is an index type and not byte offset first before trying to switch your attribute pointers. That should be faster.
Upvotes: 1
Reputation: 733
The second parameter of glDrawArrays()
isn't an offset, but an index to the first vertex, like when using indexed rendering with glDrawElements()
. Use offset_in_bytes/stride_in_bytes
to get the correct value, or actually compute BUFFER_SIZE
has a function of stride and use that value for glDrawArrays()
.
Upvotes: 2