Why does glDrawElements draw nothing?

OpenGL, known as Open Graphics Library, is a graphics API that allows us to create and render 2D and 3D graphics in our applications. It has a set of functions that assist us in creating our graphic objects.

glDrawElements function

The glDrawElements is a function in Open GL that allows us to draw shapes on the screen using vertices and indices. The vertices represent the corners of our shape while, indices represent the order in which vertices are connected in the shape.

Syntax

The syntax of the function is following:

void glDrawElements(GLenum renderMode, GLsizei elementCount, GLenum indexType, const void* indices);

Parameters

  • RenderMode : It is the type of geometry to be drawn or rendered. It can be points, lines, or triangles.

  • elementCount: It is the number of indices to be rendered.

  • indexType: It is the type of indices.

  • indices: These are the points to the array of indices that define the vertices to be rendered.

Reasons why glDrawElements draws nothing

There can be various reasons why our glDrawElements function draws nothing. These reasons include the following:

Incorrect shader setup

When we draw shapes in OpenGL, we use shaders. Shaders are small programs that run on the graphics card and define how each vertex and fragment of an object should be rendered. We have to ensure the correct setup of the shader program. If the shaders setup is incorrect, the objects may not appear on the screen.

Syntax

In the following code, we use glAttachShader function to attach the vertexShader and fragmentShader to our shaderProgram. Then we use the glLinkProgram function to link our shaderProgram to the code. The variable success checks if we encounter any errors.

// Attaching and linking shaders
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Checking for any errors
int success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (success==false) {
char errorMessage[512];
glGetProgramInfoLog(shaderProgram, 512, NULL, errorMessage);
cout << "Shader program linking error: " << errorMessage << endl;
// Handling the error appropriately
}
Setup of shader program

Incorrect buffer binding:

Before using glDrawElements function, we bind the vertex buffer objects (VBO) and element buffer objects (EBO) correctly.

  • VBO contains our vertex data or vertices.

  • EBO contains our index data or indices.

Syntax

In the following code, we use glBindBuffer function to bind our buffer objects.

// Binding the vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, Vetrex_buffer_objects);
// Binding the element buffer object
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_objects);
Buffer binding

Incorrect attribute pointers

Each vertex has its attributes, such as position and color. If the vertex attributes are not set up correctly, the vertices may not be interpreted correctly during rendering, which results in the glDrawElements function drawing nothing.

Syntax

In the following code, we set the attribute for a vertex with its attribute at position 0. The position of attributes starts from index 0. We use glVertexAttribPointer function to interpret the vertex data for a specific attribute. Then we use glEnableVertexAttribArray function to enable the attribute array for the specified attribute index so that it can be used during rendering.

// Specifying the vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
Specifying the vertex attribute

Invalid view or projection matrices

In OpenGL, our view and projection matrices help us define how to transform our 3D objects onto a 2D screen.

  • View matrix: It represents the orientation and position of our camera.

  • Projection matrix: It defines how the 3D scene is projected onto a 2D screen.

If these matrices are not set up correctly, our objects will be positioned incorrectly or become completely invisible when we call the glDrawElements function.

Syntax

The function glm::lookAt is used for the creation of the view matrix. Moreover, the function glm::perspective is used to generate the projection matrix. We use these two functions for the creation of both our matrices. Then after the creation of our matrices, we use glUniformMatrix4fv function to send our matrices to the shader program.

// Setting the view matrix
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(viewUniformLocation, 1, GL_FALSE, glm::value_ptr(view));
// Setting the projection matrix
glm::mat4 projection = glm::perspective(glm::radians(45.0f), screenWidth / screenHeight, 0.1f, 100.0f);
glUniformMatrix4fv(projectionUniformLocation, 1, GL_FALSE, glm::value_ptr(projection));
Set up of view and projection matrices

Depth testing and face culling

To check the proper working of our getIdrawElements, we ensure that depth testing is enabled and face culling is disabled in our code. Depth testing and face culling are techniques used in 3D rendering to determine which objects should be visible on the screen.

Syntax

We can enable depth testing and disable face culling using the following functions.

// Enabling depth testing
glEnable(GL_DEPTH_TEST);
// Disabling face culling
glDisable(GL_CULL_FACE);
Enable depth testing and disable face culling

Incorrect drawing parameters

Before calling the glDrawElements function, we have to ensure we send correct data in the parameters of our function.

Syntax

We have to ensure that the numIndices and the indexType matches our data. Moreover, we must check that we set the correct drawing mode to draw our desired shape. The offset specifies the starting point from where the indices should be read.

// Drawing using glDrawElements
glDrawElements(renderMode, numIndices, indexType, offset);
Call gIDrawElements with correct parameters

Code example of the correct working of glDrawElements

In the following code, we set up a basic OpenGL application that creates a window and renders a triangle on the screen.

#include <GL/glew.h>
#include <GLFW/glfw3.h>

int main()
{
    // Initializing GLFW
    glfwInit();
    
    // Creating a window
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", NULL, NULL);
    if (window == NULL)
    {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    
    // Initializing GLEW
    if (glewInit() != GLEW_OK)
    {
        glfwTerminate();
        return -1;
    }
    
    // Setting up vertex data
    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // Vertex 1
        0.5f, -0.5f, 0.0f,  // Vertex 2
        0.0f, 0.5f, 0.0f    // Vertex 3
    };
    
    // Setting up index data
    unsigned int indices[] = {
        0, 1, 2 // Indices for drawing a triangle
    };
    
    // Creating vertex buffer object (VBO)
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    // Creating element buffer object (EBO)
    GLuint EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    // Setting up vertex attributes
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    
    // Rendering loop
    while (!glfwWindowShouldClose(window))
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        
        // Draw the triangle using glDrawElements
        glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
        
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    
    // Cleaning up
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    
    // Terminate GLFW
    glfwTerminate();
    return 0;
}
Coding example that creates a triangle

Conclusion

When the glDrawElements function in OpenGL draws nothing, there can be various negligence and inconsistencies causing the error. It is crucial to investigate each potential cause to identify the specific problem.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved