glMultiDraw functions and gl_InstanceID - opengl

When I look at the documentation of glMultiDrawElementsIndirect (or in the Wiki) it says that a single call to glMultiDrawElementsIndirect is equivalent to repeatedly calling glDrawElementsIndirect (just with different parameters).
Does that mean that gl_InstanceID will reset for each of these "internal" calls? And if so, how am I able to tell all these calls apart in my vertex shader?
Background: I'm trying to draw all my different meshes all at once. But I need some way to know to which mesh the vertex, I'm processing in my vertex shader, belongs.

The documentation says "similarly to". "Equivalent" isn't the same thing. It also points to glDrawElementsInstancedBaseVertexBaseInstance, not glDrawElementsInstanced.
But yes, gl_InstanceId for any draw will start at zero, no matter what base instance you provide. That's how gl_InstanceId works, unfortunately.
Besides, that's not the question you want answered. You're not looking to ask which instance you're rendering, since each draw in the multi-draw can be rendering multiple instances. You're asking which draw in the multi-draw you are in. An instance ID isn't going to help.
And if so, how am I able to tell all these calls apart in my vertex shader?
Unless you have OpenGL 4.6 or ARB_shader_draw_parameters, you can't. Well, not directly.
That is, multidraw operations are expected to produce different results based on rendering from different parts of the current buffer objects, not based on computations in the shader. You're rendering with a different base vertex that selects different vertices from the arrays, or you're using different ranges of indices or whatever.
The typical pre-shader_draw_parameters solution would have been to use a unique base instance on each of the individual draws. Of course, since gl_InstanceId doesn't track the base instance (as previously stated), you would need to employ instanced arrays instead. So you'd get the mesh index from that.
Of course, 4.6/shader_draw_parameters gives you gl_DrawId, which just tells you what the index is within the multidraw command. It's also dynamically uniform, so you can use it to access arrays of opaque types in shaders.

Related

glMultiDrawArraysIndirect and trying to find which draw call it is

So I have one huge VBO where all my models are stored, and a bunch of draw calls ready to submit to glMultiDrawArraysIndirect.
I also have a uniform block full of matrices so ship A goes to position A, ship B goes to position B, etc.
My question is - how does one make glsl aware which draw call is which? I tried changing the baseInstance variable but that doesn't seem to affect gl_InstanceID, which also starts at 0 for every draw call. After reading further on the khronos page, it seems like this variable won't affect anything.
So what is the proper way to include matrices so each draw call draws things at different positions?
If you have GL 4.6/ARB_shader_draw_parameters, then you have access to gl_DrawID, which is exactly what it sounds like: the zero-based index of the draw in any multi-draw command. It's also guaranteed to be dynamically uniform, so you can use it to access texture arrays (that is, sampler2D texarray[5];, not sampler2DArray texarray;) and other things that require dynamically uniform values.
If you don't... then your best bet is to create an instance array that contains indices, starting with 0. Your VS will have an input corresponding to this value. gl_InstanceID is not affected by the base instance, but the value fetched from an instance array is affected by it. So it will give you a proper index, at the cost of having a seemingly pointless value lying around.
Also, such a value will not be dynamically uniform. But that's usually not a big deal. It's only a problem if you want to access texture arrays.

Does OpenGL allow you to provide array attributes when using glMultiDrawArrays?

I'm drawing a bunch of primitives (in my case lines) using the glMultiDrawArrays command. Each of these arrays (lines) have some additional attribute(s) specific to that array.
I would essentially like to pass these "array attributes" as separate uniforms specific to each array.
The two ways I can think of now is:
Draw each array (line) in separate draw calls and specify the attribute as a uniform.
Pass these attributes as vertex attributes. This would require me to store as many copies of the same value as I have vertices (I can have up to a 100k in the arrays). Not an option if I do have to store them!
Is there a smarter way of doing this in OpenGL?
Say I have n number of primitives to draw.
The glMultiDrawArrays command already requires me to pass along two arrays of size n. One array (lineStartIndex) of start indices and one array (lineCount) storing how many vertices each array contains .
To me it seems as it should be possible to specify vertex array attributes in a similar manner. E.g. a arrayAttributes vector of size n that could also be passed along with the draw call.
So instead of vertexAttribArray I'd like something like vertexArrayAttribArray ;)
Btw, I am only using one VAO and one VBO.
To me it seems as it should be possible to specify vertex array attributes in a similar manner.
Why? Vertex attributes are for things that change per-vertex; why would you expect to be able to use them for things that don't change per-vertex?
Well, you can (as I will explain), but I don't know why you think it should be possible.
The instancing and base instance feature can be (ab)used to provide a uniform-like value to a shader in a draw call.
You need to set up the attribute you want to provide "per-line" as an instanced array attribute. So you would use glVertexAttribDivisor with a value of 1 for that attribute.
Then, for each line, you would call glDrawArraysInstancedBaseInstance. Each call represents a single line, so you would provide an instance count of 1. But the base instance represents the index in the attribute array for that line's "per-line" value.
Yes, you're not using multi-draw. But OpenGL's draw call overhead is minimal; it's combining draw calls with state changes that get you. And you're not changing state between calls, so there's no problem.
However, if you're concerned about this minor overhead, and have access to multi-draw indirect functionality, you can always use that. Each line is a separate draw in the multi-draw call.
Of course, base instance requires GL 4.2 or ARB_base_instance. If you don't have access to hardware of this nature, then you're going to have to stick with the uniform variable method.

Occlusion Queries and Instanced Rendering

I'm facing a problem where the use of an occlusion query in combination with instanced rendering would be desirable.
As far as I understood, something like
glBeginQuery(GL_ANY_SAMPLES_PASSED, occlusionQuery);
glDrawArraysInstanced(mode, i, j, countInstances);
glEndQuery(GL_ANY_SAMPLES_PASSED);
will only tell me, if any of the instances were drawn.
What I would need to know is, what set of instances has been drawn (giving me the IDs of all visible instances). Drawing each instance in an own call is no option for me.
An alternative would be to color-code the instances and detect the visible instances manually.
But is there really no way to solve this problem with a query command and why would it not be possible?
It's not possible for several reasons.
Query objects only contain a single counter value. What you want would require a separate sample passed count for each instance.
Even if query objects stored arrays of sample counts, you can issue more than one draw call in the begin/end scope of a query. So how would OpenGL know which part of which draw call belonged to which query value in the array? You can even change other state within the query scope; uniform bindings, programs, pretty much anything.
The samples-passed count is determined entirely by the rasterizer hardware on the GPU. And the rasterizer neither knows nor cares which instance generated a triangle.
Instancing is a function of the vertex processing and/or vertex specification stages; by the time the rasterizer sees it, that information is gone. Notice that fragment shaders don't even get an instance ID as input, unless you explicitly create one by passing it from your vertex processing stage(s).
However, if you truly want to do this you could use image load/store and its atomic operations. That is, pass the fragment shader the instance in question (as an int data type, with flat interpolation). This FS also uses a uimageBuffer buffer texture, which uses the GL_R32UI format (or you can use an SSBO unbounded array). It then performs an imageAtomicAdd, using the instance value passed in as the index to the buffer. Oh, and you'll need to have the FS explicitly require early tests, so that samples which fail the fragment tests will not execute.
Then use a compute shader to build up a list of rendering commands for the instances which have non-zero values in the array. Then use an indirect rendering call to draw the results of this computation. Now obviously, you will need to properly synchronize access between these various operations. So you'll need to use appropriate glMemoryBarrier calls between each one.
Even if queries worked the way you want them to, this would be overall far more preferable than using a query object. Unless you're reading a query into a buffer object, reading a query object requires a GPU/CPU synchronization of some form. Whereas the above requires some synchronization and barrier operations, but they're all on-GPU operations, rather than synchronizing with the CPU.

Multiple meshes or multiple objects in a single mesh?

I'm trying to load multiple objects into a vbo in opengl. If I want to be able to move these objects independently should I use a mesh for each object or should I load all the objects to a single mesh?
Also in my code I have...
loc1 = glGetAttribLocation(shaderP, "vertex_position");
Now I understand that this gets the vertex positions in my current program but if I want to load another object I load the mesh and then how can I get the vertex positions again but for only that mesh?
The answer is, as often, "it depends". Having one "mesh" (i.e. one buffer) per object is arguably "cleaner" but it is also likely slower. One buffer per object will make you bind a different buffer much more often. Tiny vertex buffer objects (a few dozen vertices) are as bad as huge ones (gigabytes of data). You should try to find a "reasonable" thing in between
The as of version 3.2 readily available glDrawElementsBaseVertex (also exists as instanced version) will allow you to seamlessly draw several objects or pieces from one buffer without having to fiddle with renumbering indices, and without having to switch buffers.
You should preferrably (presuming OpenGL 3.3 availability) not use glGetAttribLocation at all, but assign the attribute to a location using the layout specifier. That way you know the location, you don't need to ask every time, and you don't have to worry that "weird, unexpected stuff" might happen.
If you can't do it in the shader, use glBindAttribLocation (available since version 2.0) instead. It is somewhat less comfortable, but does the same thing. You get to decide the location instead of asking for it and worrying that the compiler hopefully didn't change the order for two different shaders.
It's generally cleaner if you use different buffers for different objects.
According to:
http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
This will only returned the pointer to the location of the data. You use this to bind you vertex info to the program. When you render your other object you will bind to the vbo that stores the other vertices.

OpenGL multiple VBO

If I have two different primitive types which are drawn dynamically according to user input, should I use 2 separate VBOs or is there a way of using one and of somehow identifying where the different primitive vertices begin and end?
The primitive types are triangle strips and points
Either method works. If using a VBO the data parameter of the gl…Pointer functions is interpreted as a numeric byte offset into the VBO. It's perfectly possible to put seveal batches of vertex attributes into a single VBO and point OpenGL to the sections within the VBO by their offsets.
So before each glDraw… call use the right gl…Pointer calls to set the right offsets. Or even better yet (if supported, i.e. you've got a new enough OpenGL version): Use Vertex Array Objects to encapsulate whole set of gl…Pointer settings into one abstract object that can be bound by a single OpenGL call.