The following diagram comes from the D3D10 documentation, but I feel it conveys primitive topology better than the diagrams in the OpenGL specification.
What you need to understand is that when you use a primitive type w/Adjacency (e.g. GL_LINE_STRIP_ADJACENCY
) you actually have to supply additional data in your index buffer.
Do you see the dotted lines in the diagram? Those are extra indices that you have to insert into your index buffer (or simply as extra vertices if you are not using indexed drawing commands).
You are only interested in a line strip, so your case is very simple to index.
You will add an extra index to the beginning and end of your line strip to provide adjacent vertex information (denoted as 0 and 5 in the diagram above).
Say for instance you have the following (indexed) line strip:
0,9,36,4,52,1,8 (7 indices, 6 lines)
Lines produced:
<0,9>
<9,36>
<36,4>
<4,52>
<52,1>
<1,8>
And you have determined the following end-adjacency:
L-hand: 45
R-hand: 63
Your line strip w/Adjacency would be indexed thus:
[45],0,9,36,4,52,1,8,[63] (9 indices, **still** 6 lines)
+ Vertices [45] and 36 are adjacent to line <0,9> (first line)
+ Vertices 52 and [63] are adjacent to line <1,8> (last line)
As you can see, 2 extra indices (denoted using [X]
) had to be added, because the first and last lines would otherwise have no vertex preceding or following them. Those indices do not form lines in the strip, they are just there to fill-in adjacency information where it would otherwise be undefined.
Pseudo-code to access adjacent vertices in a line strip with adjacency in a Geometry Shader:
#version 330
// 4 vertices per-primitive -- 2 for the line (1,2) and 2 for adjacency (0,3)
layout (lines_adjacency) in;
// Standard fare for drawing lines
layout (line_strip, max_vertices = 2) out;
void main (void) {
// The two vertices adjacent to the line that you are currently processing
vec4 prev_vtx = gl_in [0].gl_Position;
vec4 next_vtx = gl_in [3].gl_Position;
gl_Position = gl_in [1].gl_Position; // First vertex in the line
EmitVertex ();
gl_Position = gl_in [2].gl_Position; // Second vertex in the line
EmitVertex ();
}
The Geometry Shader follows the description given in the OpenGL specification:
A line segment is drawn from the i
+ 2nd vertex to the i
+ 3rd vertex for each i
= 0, 1, . . . , n
− 1, where there are n
+ 3 vertices passed. If there are fewer than four vertices, all vertices are ignored. For line segment i
, the i
+ 1st and i
+ 4th vertex are considered adjacent to the i
+ 2nd and i
+ 3rd vertices, respectively (see
figure 10.3)