# Using same buffer for vertex and index data?

Is it possible to use the same buffer for both GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER?

I load both vertex data and index data into a big slab of memory, so it would be easier for me to just load it all into a single buffer. So naturally, I do like this

glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, dataSize, data, usage);
glBindBuffer(GL_ARRAY_BUFFER, 0);


Is it legal to – during rendering – simply use it as both?

glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId);
glVertexAttribPointer(...);
...
glDrawElements(mode, count, dataType, (void*)indexOffset);


I can't find anything in the spec saying it's ok to do so, but I can't find anything that says that I can't either. Googling doesn't turn up much either, but I might be looking in the wrong places.

• How about trying it and seeing what happens? Let us know how it turns out! – Panda Pajama May 12 '14 at 8:57
• @PandaPajama I've considered that, but if it works it only means it works on my set up; undefined behavior is undefined you know. :) And I figured before I implement it either way, someone might already know. – falstro May 12 '14 at 8:59
• It is a starting point, trying it on your setup... – Panda Pajama May 12 '14 at 9:00

The GL_ARB_vertex_buffer_object specification (which all buffer objects are based on) notes:

Note that it is expected that implementations may have different memory type requirements for efficient storage of indices and vertices. For example, some systems may prefer indices in AGP memory and vertices in video memory, or vice versa; or, on systems where DMA of index data is not supported, index data must be stored in (cacheable) system memory for acceptable performance. As a result, applications are strongly urged to put their models' vertex and index data in separate buffers, to assist drivers in choosing the most efficient locations.

In other words you certainly can, but you shouldn't because you may interfere with any optimizations the driver may make based on the initial binding-point used for the object.

A related, and slightly subtle because it may not be immediately obvious, point is that this behaviour can be expected to be different on different hardware or even different drivers from the same manufacturer. So you may test and find it's OK for you, but then get horrible performance when you ship it to a customer.

• Excellent, thank you! Last paragraph is also exactly why I asked a question and didn't just test and see if it works. – falstro May 12 '14 at 13:18
• John Carmack says this is "outdated technique " (tweeter) twitter.com/ID_AA_Carmack/status/955853793207320581 – Michael IV Jan 23 '18 at 23:05
• John Carmack has a bad habit of making statements in the context of whatever he's currently working on, but without providing that context. – Maximus Minimus Jan 24 '18 at 1:34

(Edited my question as I now read that your input is one big slab of data)

If your input is one big slab of data like [vertexvertexvertex... indexindexindex] you're better off calculating the pointers to the start of the vertex data and the start of the index data and passing those as buffers to OpenGL then to load the entire thing. OpenGL might wish to separate the data when it is uploaded to the GPU. And messing with offsets and strides for non-uniform data can only cause problems, especially when data is layed out differently than you might expect. For example if it is aligned.

• I certainly would not mix vertex and index data (ending up with non-uniform data), it's just laid out sequentially the way you're saying (padded for proper alignment of course). But I guess you're right. I'll get working on doing separate uploads. – falstro May 12 '14 at 9:11

For further reference, I came through the exact same problem and added the answer to this with code here:

https://stackoverflow.com/questions/24910929/use-of-gldrawelements-i-dont-understand