2
votes

This is the defination of glColorPointer from opengl.org :

void glColorPointer(GLint size,GLenum type, GLsizei stride, const GLvoid * pointer); Parameters

size Specifies the number of components per color. Must be 3 or 4. The initial value is 4.

type Specifies the data type of each color component in the array. Symbolic constants GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, and GL_DOUBLE are accepted. The initial value is GL_FLOAT.

stride Specifies the byte offset between consecutive colors. If stride is 0, the colors are understood to be tightly packed in the array. The initial value is 0.

pointer Specifies a pointer to the first component of the first color element in the array. The initial value is 0.

In simple words, we can say that size and type parameters specify number of bytes of one color unit, and stride specifies the byte offset between consecutive color units.

But, how does this function know the total number of units ? As we all know, if an array is passed as a pointer to a function, it is impossible to get the size of array by using sizeof() inside the function. So how does glColorPointer know the size of the array, when the pointer parameter is only a GLvoid* pointer ?

4
In short, it doesn't know... it's perfectly possible to crash your application by drawing out-of-bound indices (or not, if you're unlucky). However, it does know in case a buffer object is bound. In this case, the size of the buffer element as reserved by glBufferData is the maximum allowable size (yet again, it's perfectly possible to draw indices outside that range, likely crashing your app).Damon
@BrendanLong: Why are you speculating? OpenGL is well specified and the gl*Pointer functions don't dereference the pointer.datenwolf

4 Answers

8
votes

Because the function by itself does not access the array. It merely saves the given parameters in OpenGL internal state machine. The data in the array are only accessed when you call glDrawArrays or glDrawElements. Only then is the color of each drawn vertex read from the location you give in glColorPointer.

glDrawArrays on the other hand does contain count parameter that specifies the number of vertices. Needless to say there has to be enough data in your color array to supply every vertex drawn.

The same applies to any other gl*Pointer function like glNormalPointer or glTexCoordPointer

3
votes

It knows because you specify the number of indices to be used in a glDraw* function.

1
votes

From that same page:

glColorPointer specifies the location and data format of an array of color components to use when rendering. size specifies the number of components per color, and must be 3 or 4. type specifies the data type of each color component, and stride specifies the byte stride from one color to the next, allowing vertices and attributes to be packed into a single array or stored in separate arrays. (Single-array storage may be more efficient on some implementations; see glInterleavedArrays.)

If a non-zero named buffer object is bound to the GL_ARRAY_BUFFER target (see glBindBuffer) while a color array is specified, pointer is treated as a byte offset into the buffer object's data store. Also, the buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as color vertex array client-side state (GL_COLOR_ARRAY_BUFFER_BINDING).

...

glColorPointer is available only if the GL version is 1.1 or greater.

My speculation is that pointer describes a region of memory for subsequent openGL functions to use for colors, and when those functions refer to those colors by index, they will use the memory (if any) pointed at by the function. This means since you're controlling both the memory and indecies, they simply say that any out-of-bounds access is your fault, and so it has no need to know the length of the buffer. It doesn't care.

1
votes

It doesn't need it. The following glDrawElement (or related) call will need it, and then it will have the size.

This can also lead to nice errors seeming to originate from a draw call, at a moment when the offending piece of code was executed in a far and grey past where the debugger can not look.