Generating a terrain from a grayscale heightmap image

I’m using stb_image to load in a heightmap, which gives me an array where each element is an int between 0 and 255, depending on the darkness of the pixel, also storing the width and length of the image in their respective variables.

In loading the vertex array, I’m using the following code:

 GLfloat vertices[x*y*3]; //initialize vertex array, where each pixel has 3 coordinates
    float x_step = 1.0/x;
    float y_step = 1.0/y;
    float z_step = 1.0/255;

    int arrayPos = 0;
    std::vector<GLfloat> vertex_values;
    for(int i = 0; i<y; i++){
        for(int k=0;k<x;k++){
            vertex_values.push_back((GLfloat)k*x_step); //x
            vertex_values.push_back((GLfloat)i*y_step); //y
            vertex_values.push_back((GLfloat)int(data[arrayPos++] & 0xff)*z_step); //z

    for(int i=0;i<vertex_values.size(); i++){
        vertices[i] = vertex_values[i];

I bring the values of X, Y, Z between 0 and 1, as openGL expects, by dividing them by their max value (the image’s width and length, and 255, the maximum value for Z).

I then bind the buffers, as standard:

    glGenVertexArrays( 1, &VAO );
    glGenBuffers( 1, &VBO );
    glGenBuffers(1, &VBO_COLOR);
    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
    glBindVertexArray( VAO );

    glBindBuffer( GL_ARRAY_BUFFER, VBO );
    glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );

    // Position attribute
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( GLfloat ), ( GLvoid * ) 0 );
    glEnableVertexAttribArray( 0 );

    // Color attribute
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);

    glBindBuffer(GL_ARRAY_BUFFER, 0); //Unbind Color
    glBindVertexArray( 0 ); // Unbind VAO

and this is my main loop:

 while ( !glfwWindowShouldClose( window ) )
        // Set frame time
        GLfloat currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        // Check and call events

        // Render
        // Clear the colorbuffer
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

        // Camera and View transformation
        glm::mat4 model;
        model = glm::mat4(1.0f);

        glm::mat4 projection;
        projection = glm::perspective(camera.GetZoom(), (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 1000.0f);

        // Create camera transformation
        glm::mat4 view;
        view = camera.GetViewMatrix();

        // Get their uniform location
        GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
        GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
        GLint projLoc = glGetUniformLocation(shaderProgram, "projection");

        // Pass the matrices to the shader
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

        glDrawArrays(GL_LINE_LOOP, 0, sizeof(vertices));

        // Swap the screen buffers

I’m not sure why this isn’t working, as I have a blank window open when I run it.