There are two OpenGL documentation pages which have slightly different descriptions of the "index" parameter of the glDrawElements function. On www.opengl.org/sdk/docs/man4/ it says:
Specifies a pointer to the location where the indices are stored.
Specifies a byte offset (cast to a pointer type) into the buffer bound
to GL_ELEMENT_ARRAY_BUFFER to start reading indices from. If no buffer
is bound, specifies a pointer to the location where the indices are stored.
As per OpenGL 4.5 reading from client memory is unsupported (§10.3.10 OpenGL 4.5 core spec):
DrawElements, DrawRangeElements, and DrawElementsInstanced source their indices from the buffer object whose name is bound to
ELEMENT_ARRAY_BUFFER, using their indices parameters as offsets into the buffer object in the same fashion as described in section 10.3.9. [...] If zero is bound to
ELEMENT_ARRAY_BUFFER, the result of these drawing commands is undefined.
So your approach of creating an EBO is correct. Except if your 0th index is located at offset zero then the 3rd index is located at offset
As for your second quotation: in the older OpenGL versions you could pass a pointer to the client memory (in your process virtual address space, not the physical address) and leave