PDA

View Full Version : Pipeline with multiple primitive types



theold
09-04-2016, 08:17 PM
Let's say the normal pipeline is rendering filled Triangles in 3d, where each vertex has an associated normal, and the Geometry Shader is bypassed.

Now I want the user to press a key that toggles "draw normals" as Lines: (vertex position -> vertex position + normal offset). In that case, a Geometry Shader could be used to generate the Line primitives: the Geometry Shader takes in a Triangle emitted from Vertex Shader and emits a Line "normal" for each vertex in that Triangle. However, it seems now that only the Lines will be passed on to the Rasterization, not the original Triangles.

Do I need to make two draw commands with different pipelines? One draw command to draw Triangles, another draw command to draw the normal Lines. It seems wasteful to re-submit the vertex + normal data or is that how its normally done?

Edit: So I've started looking at Transform Feedback and I think this is what I need. Create the empty Transform Feedback buffer, issue the first draw command and capture the vertices. Then, after glEndTransformFeedback, I can change programs and submit the filled buffer?

Silence
09-05-2016, 05:07 AM
With TF, you'll get all your computations back (so I suppose vertices, and vertices+normals), so you will still have to use another draw command to move from triangles to lines with the result of the TF computation.

The easiest way to my opinion would be to compute this at start along with your triangles, and just draw it if necessary. You can reuse the same VBO or have another one dedicated to the normals.

You can of course use the GS, but the feedback I received in this forum about them here are that they are unnecessarily slow.

So if your main intend is to keep a single call to the shader, then compute these lines, fill them in your VBO and draw them if necessary.

GClements
09-05-2016, 06:11 AM
Now I want the user to press a key that toggles "draw normals" as Lines: (vertex position -> vertex position + normal offset). In that case, a Geometry Shader could be used to generate the Line primitives: the Geometry Shader takes in a Triangle emitted from Vertex Shader and emits a Line "normal" for each vertex in that Triangle. However, it seems now that only the Lines will be passed on to the Rasterization, not the original Triangles.

That's correct. You can't draw multiple primitive types with a single draw call.



Do I need to make two draw commands with different pipelines? One draw command to draw Triangles, another draw command to draw the normal Lines.

Yes. The second command would use GL_POINTS, as the GS only needs individual vertices.



Edit: So I've started looking at Transform Feedback and I think this is what I need. Create the empty Transform Feedback buffer, issue the first draw command and capture the vertices. Then, after glEndTransformFeedback, I can change programs and submit the filled buffer?
In this case, you'd probably want three programs: one used with GL_POINTS to perform the vertex transformations which are then captured with transform feedback, then the programs for GL_TRIANGLES and GL_LINES to draw the triangles and normals. If you just use transform feedback to capture the GL_TRIANGLES output, you'll get each vertex repeated for each triangle which uses it (a typical closed, smooth triangle mesh uses each vertex for an average of six triangles).

But you don't need a geometry shader. If the vertex position and normal-line endpoint are interleaved within the buffer, the GL_LINES draw call can just re-interpret the buffer as 2*N vertices with a single attribute.

Silence
09-05-2016, 06:32 AM
If you just use transform feedback to capture the GL_TRIANGLES output, you'll get each vertex repeated for each triangle which uses it (a typical closed, smooth triangle mesh uses each vertex for an average of six triangles).


Generally each of these repeated vertex will have a different normal depending on the triangle it belongs too. So this is not an issue. Or did I missed some point ?



But you don't need a geometry shader. If the vertex position and normal-line endpoint are interleaved within the buffer, the GL_LINES draw call can just re-interpret the buffer as 2*N vertices with a single attribute.

That's an interesting use of interleaved data in arrays ! I never thought of using them like this.

GClements
09-05-2016, 11:19 AM
Generally each of these repeated vertex will have a different normal depending on the triangle it belongs too. So this is not an issue. Or did I missed some point ?
If you aren't sharing vertices (or are only rarely sharing vertices), then that isn't an issue. But even a mesh consisting of flat quads each split into two triangles will have 50% sharing, i.e. rendering triangles will generate six vertices for each quad rather than four.