<p>If the end of your cylinder is <strong>convex</strong>, with vertices <span class="math-container">$V_0, V_1, V_2,...V_{N-1}$</span> then just replace your fan order (i.e. as above) with this strip <span class="math-container">$V_0, V_1, V_{N-1}, V_2, V_{N-2}, V_3...$</span>, i.e. just zig-zag across the polygon.</p>

CC BY-SA 4.0
2019-12-23T09:54:50.367Z
2020-01-24T09:51:46.233Z
2020-01-24T09:51:46.233Z
Simon F
<p>I know how to generate the walls of a cylinder with triangle strips and the caps with triangle fans, but since I am working inside a geometry shader, I can only output triangle strips, so I am kind of lost here.</p>

<p>This here is my current code, which only generates the hull of the cylinder based on a line segment:</p>

<pre><code>#version 330 core

    layout(lines) in;
    layout(triangle_strip, max_vertices = 32) out;

    uniform mat4 projection;
    uniform mat4 view;
    uniform mat4 model;

    in Vertex 
    {
        vec4 color;
        float width;
    } vertex[];

    out vec4 vertex_color;
    out vec3 normal_vector;

    vec3 createPerp(vec3 p1, vec3 p2)
    {
        vec3 invec = normalize(p2 - p1);
        vec3 ret = cross( invec, vec3(0.0, 0.0, 1.0) );
        if ( length(ret) == 0.0 )
        {
            ret = cross(invec, vec3(0.0, 1.0, 0.0) );
        }
        return ret;
    }


    void main()
    {
        mat4 mvp = projection * view * model;

        vec3 axis = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;

        vec3 perpx = normalize(createPerp(gl_in[1].gl_Position.xyz, gl_in[0].gl_Position.xyz));
        vec3 perpy = cross(normalize(axis), perpx);

        float r1 = vertex[0].width / 1000.0;
        float r2 = vertex[0].width / 1000.0;

        int segs = 16;
        for(int i=0; i&lt;segs; i++) {
            float a = i/float(segs-1) * 2.0 * 3.14159;
            float ca = cos(a); float sa = sin(a);
            vec3 normal = vec3( ca*perpx.x + sa*perpy.x,
                            ca*perpx.y + sa*perpy.y,
                            ca*perpx.z + sa*perpy.z );



            vec3 p1 = gl_in[0].gl_Position.xyz + r1*normal;
            vec3 p2 = gl_in[1].gl_Position.xyz + r2*normal;

            gl_Position = mvp * vec4(p1, 1.0);
            vertex_color = vertex[0].color;
            normal_vector = normal;
            EmitVertex();

            gl_Position = mvp * vec4(p2, 1.0);
            vertex_color = vertex[0].color;
            normal_vector = normal;
            EmitVertex();       
        }
        EndPrimitive();   
    }
</code></pre>

<p>Is there some simple way to integrate the generation of the endcaps here?</p>

CC BY-SA 4.0
2019-12-23T06:39:59.593Z
Make point in middle of cylinder cap
joojaa
CC BY-SA 4.0
2020-02-27T19:09:01.767Z
@joojaa That wouldn't really change much about the problem of emulating a triangle fan with a strip that the question is facing. In fact it would make answer by Simon inapplicable even.
Christian Rau
<opengl><computational-geometry><mesh><geometry-shader>
Generating the end caps of a cylinder using triangle strips for use in a geometry shader
Katharina
# Generating the end caps of a cylinder using triangle strips for use in a geometry shader

(Asked by: username_0 on 2019-12-23)

I know how to generate the walls of a cylinder with triangle strips and the caps with triangle fans, but since I am working inside a geometry shader, I can only output triangle strips, so I am kind of lost here.

This here is my current code, which only generates the hull of the cylinder based on a line segment:

```
#version 330 core

    layout(lines) in;
    layout(triangle_strip, max_vertices = 32) out;

    uniform mat4 projection;
    uniform mat4 view;
    uniform mat4 model;

    in Vertex 
    {
        vec4 color;
        float width;
    } vertex[];

    out vec4 vertex_color;
    out vec3 normal_vector;

    vec3 createPerp(vec3 p1, vec3 p2)
    {
        vec3 invec = normalize(p2 - p1);
        vec3 ret = cross( invec, vec3(0.0, 0.0, 1.0) );
        if ( length(ret) == 0.0 )
        {
            ret = cross(invec, vec3(0.0, 1.0, 0.0) );
        }
        return ret;
    }

    void main()
    {
        mat4 mvp = projection * view * model;

        vec3 axis = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;

        vec3 perpx = normalize(createPerp(gl_in[1].gl_Position.xyz, gl_in[0].gl_Position.xyz));
        vec3 perpy = cross(normalize(axis), perpx);

        float r1 = vertex[0].width / 1000.0;
        float r2 = vertex[0].width / 1000.0;

        int segs = 16;
        for(int i=0; i<segs; i++) {
            float a = i/float(segs-1) * 2.0 * 3.14159;
            float ca = cos(a); float sa = sin(a);
            vec3 normal = vec3( ca*perpx.x + sa*perpy.x,
                            ca*perpx.y + sa*perpy.y,
                            ca*perpx.z + sa*perpy.z );

            vec3 p1 = gl_in[0].gl_Position.xyz + r1*normal;
            vec3 p2 = gl_in[1].gl_Position.xyz + r2*normal;

            gl_Position = mvp * vec4(p1, 1.0);
            vertex_color = vertex[0].color;
            normal_vector = normal;
            EmitVertex();

            gl_Position = mvp * vec4(p2, 1.0);
            vertex_color = vertex[0].color;
            normal_vector = normal;
            EmitVertex();       
        }
        EndPrimitive();   
    }

```

Is there some simple way to integrate the generation of the endcaps here?

**Tags:** opengl, computational-geometry, mesh, geometry-shader

> **Comments:**
> **username_1**: Make point in middle of cylinder cap  
> **username_2**: @username_1 That wouldn't really change much about the problem of emulating a triangle fan with a strip that the question is facing. In fact it would make answer by username_3 inapplicable even.  

---

## 1 answers

### Answer by username_3 on 2019-12-23. Score: 1

If the end of your cylinder is **convex**, with vertices $V\_0, V\_1, V\_2,...V\_{N-1}$ then just replace your fan order (i.e. as above) with this strip $V\_0, V\_1, V\_{N-1}, V\_2, V\_{N-2}, V\_3...$, i.e. just zig-zag across the polygon.


---

