PDA

View Full Version : glGetVertexAttribPointerv usage



ionas_
01-31-2016, 05:33 AM
I want to use this function to get data back from vbo to a pointer, where p[0]=x p[2]=y p[3]=z and so on.



...
glEnableVertexAttribArray(0);
GLfloat *ptr = (float*)calloc(vcount* 3, sizeof(float)); //pointer with preallocated memory.
GIvoid *vptr;
glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER,&vptr);
ptr = (GLfloat*)&vptr;


Shouldn't ptr[0] be the x value of the first vertex??

Thanks

GClements
01-31-2016, 06:27 AM
I want to use this function to get data back from vbo to a pointer
It's probably the wrong function. To read data from a buffer, either use glGetBufferSubData() or map the buffer then read from the mapped region.





glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER,&vptr);
ptr = (GLfloat*)&vptr;


Shouldn't ptr[0] be the x value of the first vertex??

vptr will only be a pointer if you're using a client-side array rather than a VBO. For a VBO, vptr will be the offset into the buffer.

ionas_
01-31-2016, 06:44 AM
in the notes section it says:
The state returned is retrieved from the currently bound vertex array object.

The initial value for each pointer is 0.

isn't it supposed to return the address of the specified generic vertex attribute pointer?

Alfonse Reinheart
01-31-2016, 07:12 AM
in the notes section it says:
The state returned is retrieved from the currently bound vertex array object.

The initial value for each pointer is 0.

isn't it supposed to return the address of the specified generic vertex attribute pointer?

It does. It returns exactly what you set.

You call glVertexAttribPointer, which is a function that takes a pointer. glGetVertexAttribPointer returns the pointer you set with the first call.

Now you will probably say, "Wait! glVertexAttribPointer doesn't take a pointer; it takes an offset into a buffer object." Yes, kinda. But OpenGL pretends that this offset is the value of a pointer. Therefore, glGetVertexAttribPointer returns the pointer value set by glVertexAttribPointer, even though it's not actually a pointer.

Just look at the docs for glGetVertexAttribPointer (https://www.opengl.org/sdk/docs/man/html/glGetVertexAttribPointerv.xhtml). It says right there what it returns:


The pointer returned is a byte offset into the data store of the buffer object that was bound to the GL_ARRAY_BUFFER target (see glBindBuffer) when the desired pointer was previously specified.

If you want to access data in a buffer object, you use the standard tools for accessing data in a buffer object. Namely, must use map the buffer (https://www.opengl.org/wiki/Buffer_Object#Mapping) or use glGetBufferSubData. Just because the buffer object is used for vertex data does not make it special.

ionas_
01-31-2016, 08:52 AM
so in order to retrieve data on client side we do the following?



GLfloat *pointer = (GLfloat*)calloc(numOfvertices* 3, sizeof(GLfloat));
glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER,&vptr);
glGetBufferSubData(GL_ARRAY_BUFFER,vptr,3*sizeof(f loat)*numOfvertices, pointer );

GClements
01-31-2016, 12:12 PM
so in order to retrieve data on client side we do the following?



GLfloat *pointer = (GLfloat*)calloc(numOfvertices* 3, sizeof(GLfloat));
glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER,&vptr);
glGetBufferSubData(GL_ARRAY_BUFFER,vptr,3*sizeof(f loat)*numOfvertices, pointer );


Yes, roughly. The above assumes that the buffer holding the attribute data is already bound to GL_ARRAY_BUFFER. A slightly more thorough version might use glGetVertexAttribIuiv(GL_VERTEX_ATTRIB_ARRAY_BUFFE R_BINDING) to obtain the buffer name then bind it (or use glGetNamedBufferSubData()).

Beyond that, it's generally better to keep track of this information yourself than to use glGet* to retrieve it from OpenGL.

ionas_
01-31-2016, 02:04 PM
Thanks a lot for your answers. I will try it out. :)