Rendering Geometry in OpenGL ES 3.0 Using glDrawArrays

OpenGL ES 3.0 Primitive Drawing API Overview

OpenGL ES 3.0 offers five primary API functions for rendering geometric primitives. While glDrawElements and its variations are common for indexed rendering, glDrawArrays serves as the fundamental method for rendering non-indexed geometry directly from vertex buffer data.

The glDrawArrays Function

This command constructs sequences of geometric primitives using data currently bound to the vertex arrays. It supports various rendering modes, including points, lines, and triangles, allowing developers to define how vertices are interpreted.

Triangle Primitive Modes

When rendering triangles, the mode parameter dictates how the vertex data is assembled. The three most distinct modes are GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_TRIANGLE_FAN.

  • GL_TRIANGLES: Each group of three vertices defines a single, independent triangle. For a vertex count of n, this mode generates n/3 triangles.
  • GL_TRIANGLE_STRIP: Creates a connected chain of triangles. Starting from the third vertex, each new vertex forms a triangle with the previous two. For n vertices, it yields n-2 triangles. Note that the winding order typically alternates to maintain consistent surface normals.
  • GL_TRIANGLE_FAN: Defines a series of triangles sharing a common pivot point (the first vertex). Subsequent vertices form triangles with the pivot and the preceding vertex, also resulting in n-2 triangles.

Code Implementation Examples

The following examples demonstrate how to render a quadrilateral using the different assembly modes. The code assumes a standard EGL context has been initialized.

1. Using GL_TRIANGLES

Since GL_TRIANGLES does not share vertices between adjacent faces, we must explicitly define six vertices to form two triangles composing a rectangle.

GLfloat rectVertices[] = {
        // x     y     z
        -0.5f,  0.5f, 0.0f, // Top-Left (v0)
        -0.5f, -0.5f, 0.0f, // Bottom-Left (v1)
         0.5f, -0.5f, 0.0f, // Bottom-Right (v2)
        -0.5f,  0.5f, 0.0f, // Top-Left (v0) - Repeat
         0.5f, -0.5f, 0.0f, // Bottom-Right (v2) - Repeat
         0.5f,  0.5f, 0.0f  // Top-Right (v3)
    };

    // Set the viewport and clear the screen
    glViewport(0, 0, kScreenWidth, kScreenHeight);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Enable and specify the vertex attribute array
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, rectVertices);

    // Issue the draw call
    glDrawArrays(GL_TRIANGLES, 0, 6);

2. Using GL_TRIANGLE_STRIP

This mode optimizes memory usage by reusing vertices. Only four vertices are needed to construct the same rectangle.

GLfloat stripVertices[] = {
        // x     y     z
        -0.5f,  0.5f, 0.0f, // v0
        -0.5f, -0.5f, 0.0f, // v1
         0.5f,  0.5f, 0.0f, // v2
         0.5f, -0.5f, 0.0f  // v3
    };

    glViewport(0, 0, kScreenWidth, kScreenHeight);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, stripVertices);

    // 4 vertices yield 2 triangles
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

3. Using GL_TRIANGLE_FAN

To render the rectangle as a fan, we select one corner as the origin (v0) and traverse the perimeter.

GLfloat fanVertices[] = {
        // x     y     z
        -0.5f,  0.5f, 0.0f, // Center/Origin (v0)
        -0.5f, -0.5f, 0.0f, // v1
         0.5f, -0.5f, 0.0f, // v2
         0.5f,  0.5f, 0.0f  // v3
    };

    glViewport(0, 0, kScreenWidth, kScreenHeight);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, fanVertices);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Tags: OpenGL ES Graphics Programming Mobile Development C++ 3D Rendering

Posted on Sat, 16 May 2026 22:49:01 +0000 by dabaR