Home > Net >  What happens when glDraw*Instanced() is called with primcount greater than how many times a vertex a
What happens when glDraw*Instanced() is called with primcount greater than how many times a vertex a

Time:10-28

In my opengl program (opengl 3.3 core profile) i have an array with N float elements in it. I pass the array to a VBO and specify it as an array of vertex attributes at index 0. Here data is the array:

glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float), (void*)0);

I want the attribute to update once per instance, so

glVertexAttribDivisor(0, 1);

The question is what happens when the program is told to draw N * N instances of an object with a call to glDraw*Instanced()?

There are only N elements in the array so I guess the first N instances will be drawn as expected. But what happens after that? Will it cycle through the array again to draw another set of N instances and then again to draw another one and then another one and so on until it draws all of them? Or will it just treat attribute 0 as if it was set to NULL or something for the remaining N * (N - 1) instances? If so, is there a way to make it cycle through the array as described above?

The only solution i can think of is not making the array instanced and changing its size to N * N with values inside repeating N times but that would take up unnecessary amount of memory.

CodePudding user response:

You get the exact same thing that happens if you render more vertices than there is storage in the buffer objects: out-of-bound reads. If robust memory accesses are enabled in your context, then this value will be either zero or some other value within the storage of the buffer object. Without robust accesses however, out-of-bound reads result in undefined behavior and "may result in GL interruption or termination".

So... don't do that.

If so, is there a way to make it cycle through the array as described above?

Does it have to be that way exactly?

The divisor you passed to glVertexAttribDivisor is a divisor. If it isn't zero, it takes the instance index and divides it by the divisor, and that result is used as the index into the instance array. So if you pass N as the divisor, Which means that the first N instances get the value from index 0, the next N instances get the value from index 1, etc.

This will iterate in a different order from the "cycling" behavior you want, but it ultimately does the same thing.

Note that, unless there is some other instance array involved with a different divisor or your vertex shader uses gl_InstanceID, all this will do is render the same thing N times. Which probably isn't useful.

  • Related