GL_TRIANGLE_STRIP vs GL_TRIANGLE_FAN

Learn gl_triangle_strip vs gl_triangle_fan with practical examples, diagrams, and best practices. Covers opengl, gl-triangle-strip development techniques with visual explanations.

GL_TRIANGLE_STRIP vs. GL_TRIANGLE_FAN: Optimizing Your OpenGL Geometry

Abstract representation of triangles forming a strip and a fan, illustrating OpenGL primitive types.

Explore the differences between GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN in OpenGL, understand their use cases, and learn how to choose the right primitive for efficient rendering.

When rendering 3D graphics with OpenGL, understanding how to efficiently define and draw geometry is crucial for performance. OpenGL provides several primitive types for drawing triangles, the most fundamental building blocks of 3D models. Among these, GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN are particularly useful for reducing vertex data redundancy and draw calls. This article will delve into the mechanics of these two primitives, compare their advantages and disadvantages, and guide you on when to use each.

Understanding GL_TRIANGLE_STRIP

GL_TRIANGLE_STRIP is a primitive type that allows you to draw a series of connected triangles by specifying only a sequence of vertices. Each new vertex added after the first two creates another triangle, sharing two vertices with the previously drawn triangle. This method significantly reduces the amount of vertex data you need to send to the GPU, as many vertices are reused implicitly.

graph TD
    V1 --> T1
    V2 --> T1
    V3 --> T1
    V2 --> T2
    V3 --> T2
    V4 --> T2
    V3 --> T3
    V4 --> T3
    V5 --> T3

    subgraph Vertices
        V1(Vertex 1)
        V2(Vertex 2)
        V3(Vertex 3)
        V4(Vertex 4)
        V5(Vertex 5)
    end

    subgraph Triangles
        T1("Triangle 1 (V1, V2, V3)")
        T2("Triangle 2 (V2, V4, V3)")
        T3("Triangle 3 (V3, V4, V5)")
    end

    style V1 fill:#f9f,stroke:#333,stroke-width:2px
    style V2 fill:#f9f,stroke:#333,stroke-width:2px
    style V3 fill:#f9f,stroke:#333,stroke-width:2px
    style V4 fill:#f9f,stroke:#333,stroke-width:2px
    style V5 fill:#f9f,stroke:#333,stroke-width:2px
    style T1 fill:#ccf,stroke:#333,stroke-width:2px
    style T2 fill:#ccf,stroke:#333,stroke-width:2px
    style T3 fill:#ccf,stroke:#333,stroke-width:2px

How GL_TRIANGLE_STRIP forms triangles from a sequence of vertices.

For a GL_TRIANGLE_STRIP with N vertices, N-2 triangles are rendered. The order of vertices is crucial: for the first triangle, vertices are V0, V1, V2. For the second, it's V1, V3, V2 (note the swap to maintain consistent winding order). For the third, it's V2, V3, V4, and so on. This alternating pattern ensures that all triangles have the same winding order (e.g., counter-clockwise) for proper back-face culling.

glBegin(GL_TRIANGLE_STRIP);
    glVertex3f(0.0f, 0.0f, 0.0f); // V0
    glVertex3f(0.0f, 1.0f, 0.0f); // V1
    glVertex3f(1.0f, 0.0f, 0.0f); // V2 (Forms T1: V0, V1, V2)
    glVertex3f(1.0f, 1.0f, 0.0f); // V3 (Forms T2: V1, V3, V2)
    glVertex3f(2.0f, 0.0f, 0.0f); // V4 (Forms T3: V2, V3, V4)
    glVertex3f(2.0f, 1.0f, 0.0f); // V5 (Forms T4: V3, V5, V4)
glEnd();

Example of drawing a GL_TRIANGLE_STRIP in immediate mode.

Understanding GL_TRIANGLE_FAN

GL_TRIANGLE_FAN is another efficient primitive type, particularly useful for drawing polygons that share a common central vertex. In a triangle fan, the first vertex specified (V0) acts as the central pivot. Each subsequent pair of vertices (Vn, Vn+1) forms a triangle with this central vertex (V0). This is ideal for shapes like circles, pie charts, or any convex polygon that can be triangulated from a central point.

graph TD
    V0 --> T1
    V1 --> T1
    V2 --> T1
    V0 --> T2
    V2 --> T2
    V3 --> T2
    V0 --> T3
    V3 --> T3
    V4 --> T3

    subgraph Vertices
        V0(Central Vertex)
        V1(Vertex 1)
        V2(Vertex 2)
        V3(Vertex 3)
        V4(Vertex 4)
    end

    subgraph Triangles
        T1("Triangle 1 (V0, V1, V2)")
        T2("Triangle 2 (V0, V2, V3)")
        T3("Triangle 3 (V0, V3, V4)")
    end

    style V0 fill:#f9f,stroke:#333,stroke-width:2px
    style V1 fill:#f9f,stroke:#333,stroke-width:2px
    style V2 fill:#f9f,stroke:#333,stroke-width:2px
    style V3 fill:#f9f,stroke:#333,stroke-width:2px
    style V4 fill:#f9f,stroke:#333,stroke-width:2px
    style T1 fill:#ccf,stroke:#333,stroke-width:2px
    style T2 fill:#ccf,stroke:#333,stroke-width:2px
    style T3 fill:#ccf,stroke:#333,stroke-width:2px

How GL_TRIANGLE_FAN forms triangles around a central vertex.

For a GL_TRIANGLE_FAN with N vertices, N-2 triangles are rendered. The first vertex V0 is the common vertex for all triangles. The first triangle is formed by V0, V1, V2. The second by V0, V2, V3, the third by V0, V3, V4, and so on. This structure is very efficient for drawing shapes that emanate from a single point.

glBegin(GL_TRIANGLE_FAN);
    glVertex3f(0.0f, 0.0f, 0.0f); // V0 (Central vertex)
    glVertex3f(1.0f, 0.0f, 0.0f); // V1
    glVertex3f(0.866f, 0.5f, 0.0f); // V2 (Forms T1: V0, V1, V2)
    glVertex3f(0.5f, 0.866f, 0.0f); // V3 (Forms T2: V0, V2, V3)
    glVertex3f(0.0f, 1.0f, 0.0f); // V4 (Forms T3: V0, V3, V4)
glEnd();

Example of drawing a GL_TRIANGLE_FAN to create a quarter circle.

Choosing Between GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN

The choice between GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN depends entirely on the geometry you are trying to render. Both are designed to reduce vertex data and draw calls compared to GL_TRIANGLES, but they achieve this through different connectivity patterns.

Visual comparison showing a rectangle rendered with GL_TRIANGLE_STRIP and a circle rendered with GL_TRIANGLE_FAN, highlighting their respective shapes.

GL_TRIANGLE_STRIP is ideal for rectangular or ribbon-like shapes, while GL_TRIANGLE_FAN excels at circular or radial shapes.

Here's a summary of their typical use cases:

  • GL_TRIANGLE_STRIP: Best for rendering surfaces that can be laid out as a continuous ribbon of quadrilaterals or triangles. Common examples include:

    • Rectangular planes
    • Sides of a cube or prism
    • Cylinders (unrolled)
    • Terrain patches
    • Any surface where adjacent triangles share an edge.
  • GL_TRIANGLE_FAN: Best for rendering shapes that have a single central point from which all triangles originate. Common examples include:

    • Circles and ellipses
    • Bases of cones or pyramids
    • The top/bottom caps of cylinders
    • Any convex polygon.