Saturday, July 30, 2016

glVertexAttribPointer

Official



Name

glVertexAttribPointer
    define an array of generic vertex attribute data.


C Specification

void glVertexAttribPointer(
  GLuint index
  , GLint size
  , GLenum type
  , GLboolean normalized
  , GLsizei stride
  , const GLvoid * pointer
);

  index \specifies the index of the generic vertex attribute to be modified.


  size \specifies the number of components per generic vertex attribute.must be 1, 2, 3, 4.


  type \specifies the data type of each component in the array.the symbolic constants gl_byte, gl_unsigned_byte, gl_short, gl_unsigned_short, gl_int, gl_unsigned_int are accepted.


  normalized \specifies whether fixed-point data values should be normalized or converted directly as fixed-point value when they are accessed.


  stride \specifies the byte offset between consecutive generic vertex attrbutes. if stride is 0, the generic vertex attribtues are understood to be tightly packed in the array. the initial value is 0..


  pointer \specifies an offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. the initial value is 0...



Description

glVertexAttribPointerglVertexAttribIPointer and glVertexAttribLPointer specify the location and data format of the array of generic vertex attributes at index index to use when rendering. >>> size specifies the number of components per attribute and must be 1, 2, 3, 4, or GL_BGRAtype specifies the data type of each component, and >>> stride specifies the byte stride from one attribute to the next, allowing vertices and attributes to be packed into a single array or stored in separate arrays.
For glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.
For glVertexAttribIPointer, only the integer types GL_BYTEGL_UNSIGNED_BYTEGL_SHORTGL_UNSIGNED_SHORTGL_INTGL_UNSIGNED_INT are accepted. Values are always left as integer values.
glVertexAttribLPointer specifies state for a generic vertex attribute array associated with a shader attribute variable declared with 64-bit double precision components. type must be GL_DOUBLEindexsize, and stride behave as described for glVertexAttribPointer and glVertexAttribIPointer.
If pointer is not NULL, a non-zero named buffer object must be bound to the GL_ARRAY_BUFFER target (see glBindBuffer), otherwise an error is generated. pointer is treated as a byte offset into the buffer object's data store. The buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index.
When a generic vertex attribute array is specified, sizetypenormalizedstride, and pointer are saved as vertex array state, in addition to the current vertex array buffer object binding.
To enable and disable a generic vertex attribute array, call glEnableVertexAttribArray and glDisableVertexAttribArray with index. If enabled, the generic vertex attribute array is used when glDrawArraysglMultiDrawArraysglDrawElementsglMultiDrawElements, or glDrawRangeElements is called.

Notes

Each generic vertex attribute array is initially disabled and isn't accessed when glDrawElementsglDrawRangeElementsglDrawArraysglMultiDrawArrays, or glMultiDrawElementsis called.
GL_UNSIGNED_INT_10F_11F_11F_REV is accepted for type only if the GL version is 4.4 or higher.              


So it looks like this :-)

You can safely unbind a VBO after making the calls to gl…Pointer, the association with the VBO bound at the time of the call of the gl…Pointer function is not lost.
--By datenwolf

@datenwolf already covered the key aspect in a comment above. To elaborate some more:
You do not have to bind GL_ARRAY_BUFFER again before the glDrawElements() call. What matters is that the buffer you want to source a given attribute from is bound when you make the glVertexAttribPointer() call for that attribute.
The best way to picture this is that when you make this call:
glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
you're specifying all the state needed to tell OpenGL where to get the data for attribute 0 (first argument) from, and how to read it. Most of that state is given directly by the arguments:
  • it has 3 components
  • the components are float values
  • vertices are read with a stride of 20 bytes...
  • ... and starting at byte 0 of the buffer
But there's an additional implied piece of state that is also stored away for attribute 0 when you make the call:
  • the data is read from the buffer currently bound to GL_ARRAY_BUFFER
In other words, the state associated with each attribute includes the id of the buffer the attribute data is sourced from. This can be the same buffer for multiple/all attributes, or it can be a different buffer for each attribute.

Note that the same is not true for GL_ELEMENT_ARRAY_BUFFER. That one needs to be bound at the time of the glDrawElements() call. While it seems somewhat inconsistent, this is necessary because there's no equivalent to glVertexAttribPointer() for the index array. The API could have been defined to have this kind of call, but... it was not. The reason is most likely that it was simply not necessary, since only one index array can be used for a draw call, while multiple vertex buffers can be used.


Demo Code

Examples[0]
Render an indexed vertex array (not loaded into OpenGL) using texture UV and normal vertex attribtues.

//attribute indexes were received from calls to glGetAttribLocation,//or passed into glBindAttribLocationglEnableVertexAttribArray(texcoord_attrib_index);glEnableVertexAttribArray(normal_attrib_index);glEnableVertexAttribArray(position_attrib_index); 

//texcoords_data is a float* [2-per-vertex] representing UV coordinates.//normal_data is a float* [3-per-vertex] representing normal vectors.//vertex_data is a float* [3-per-vertex] representing the poition of each vertex.glVertexAttribPointer(texcoord_attrib_index, 2, GL_FLOAT, false, 0, texcoords_data);glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, false, 0, normals_data);glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, false, 0, vertex_data); 

//num_vertices is the number of verts in your vertex_data.//index_data is an array of unsigned int offsets in bytes into vertex_data.glDrawElements(GL_TRIANGLES, num_vertices, GL_UNSIGNED_INT, index_data);
glDisableVertexAttribArray(position_attrib_index);glDisableVertexAttribArray(texcoord_attrib_index);glDisableVertexAttribArray(normal_attrib_index);


Examples[1]
Render an indexed buffer object using texture UV and normal vertex attributes.

//vertex_buffer is retrieved from glGenBuffers//index_buffer is retrieved from glGenBuffers//attribute indexes were received from calls to glGetAttribLocationglEnableVertexAttribArray(texcoord_attrib_index);glEnableVertexAttribArray(normal_attrib_index);glEnableVertexAttribArray(position_attrib_index); 

//vertex_stride is the size of bytes of each vertex in the buffer object..//vertex_position_offset and kin are the offset in bytes of the position data..//in each vertex, E.g. if your vertex structure is//[positionF3,texcoordF2,normalF3]//then position vertex_position_offset will have offset 0..//and  vertex_texcoord_offset have offset 12//(I.e. position is 3*sizeof(float) bytes large, and texcoord comes just after)//and  vertex_normal_offset is 20 (3*sizeof(float)+2*sizeof(float))GLintptr vertex_texcoord_offset = (3*sizeof(float));GLintptr vertex_normal_offset = (5*sizeof(float);GLintptr vertex_position_offset = (0*sizeof(float)); 

glVertexAttribPointer(texcoord_attrib_index, 2, GL_FLOAT, false, vertex_stride, (GLvoid*)vertex_texcoord_offset);glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, false, vertex_stride, (GLvoid*)vertex_normal_offset);glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, false, vertex_stride, (GLvoid*)vertex_position_offset); 

//num_vertices is the number of verts in your vertex_data..
//index_data is an array of unsigned int offsets into vertex_data..glDrawElements(GL_TRIANGLES, num_vertices, GL_UNSIGNED_INT, NULL);
glDisableVertexAttribArray(position_attrib_index);glDisableVertexAttribArray(texcoord_attrib_index);glDisableVertexAttribArray(normal_attrib_index);

________
Done :-)
End.
________



No comments:

Post a Comment