lsJfGHkAq1y86nX0
lsJfGHkAq1y86nX0

Reputation: 58

When to delete buffer object?

I understand from this question that shader objects can be detached and deleted as soon as the program is linked.

Do buffer objects behave similarly with respect to the VAO? Can I delete them after the VAO been initialized (at the end of Scene::Scene() below) or should I leave my code as is, binding them every time I want to use them?

Scene.h:

class Scene
{
public:
    void render();
    Scene();
    ~Scene();
private:
    GLuint vertexArray;
    GLuint vertexBuffer;
    GLuint indexBuffer;
    GLuint program;
};

Scene.cpp:

#include <GL/glew.h>
#include <stdio.h>

#include "Scene.h"

namespace
{
    void printProgramInfoLog(GLuint program);
    void printShaderInfoLog(GLuint shader);
}

void Scene::render()
{
    glBindVertexArray(vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glUseProgram(program);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

    glUseProgram(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

Scene::Scene()
{
    const float vertices[] =
    {
        -1.0f, -1.0f, 0.0f,
         1.0f, -1.0f, 0.0f,
         1.0f,  1.0f, 0.0f,
        -1.0f,  1.0f, 0.0f,
    };

    const unsigned short indices[] =
    {
        0,
        1,
        2,
        0,
        2,
        3,
    };

    const char* vertexShaderSource[] =
    {
        "#version 330\n",
        "\n",
        "in vec3 position;\n",
        "\n",
        "out vec2 fspos;",
        "\n",
        "void main()\n",
        "{\n",
        "    gl_Position = vec4(position, 1.0);\n",
            "fspos = vec2(position.x, position.y);\n",
        "}\n",
    };

    const char* fragmentShaderSource[] =
    {
        "#version 330\n",
        "\n",
        "precision highp float;\n",
        "\n",
        "in vec2 fspos;",
        "\n",
        "out vec4 color;\n",
        "\n",
        "void main()\n",
        "{\n",
        "    color = vec4(abs(fspos.x), abs(fspos.y), 0.0, 1.0);\n",
        "}\n",
    };

    //-------------------------------
    // Create and bind vertex array.
    //-------------------------------
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    //--------------------------------------
    // Create, bind and fill vertex buffer.
    //--------------------------------------
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //-------------------------------------
    // Create, bind and fill index buffer.
    //-------------------------------------
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //-----------------
    // Create program.
    //-----------------
    program = glCreateProgram();

    //----------------------------------
    // Create and attach vertex shader.
    //----------------------------------
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, sizeof(vertexShaderSource) / sizeof(vertexShaderSource[0]), vertexShaderSource, 0);
    glCompileShader(vertexShader);
    printShaderInfoLog(vertexShader);
    glAttachShader(program, vertexShader);

    //------------------------------------
    // Create and attach fragment shader.
    //------------------------------------
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, sizeof(fragmentShaderSource) / sizeof(fragmentShaderSource[0]), fragmentShaderSource, 0);
    glCompileShader(fragmentShader);
    printShaderInfoLog(fragmentShader);
    glAttachShader(program, fragmentShader);

    //---------------
    // Link program.
    //---------------
    glLinkProgram(program);
    printProgramInfoLog(program);

    //-----------------------
    // Set up shader inputs.
    //-----------------------
    GLint position = glGetAttribLocation(program, "position");
    glEnableVertexAttribArray(position);
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

    //------------------------------------
    // Detach and delete fragment shader.
    //------------------------------------
    glDetachShader(program, fragmentShader);
    glDeleteShader(fragmentShader);

    //----------------------------------
    // Detach and delete vertex shader.
    //----------------------------------
    glDetachShader(program, vertexShader);
    glDeleteShader(vertexShader);

    //----------------------
    // Unbind vertex array.
    //----------------------
    glBindVertexArray(0);

    //!!!!!!!!!!!!!!!!!!!
    // Unbinding and deleting the buffers here and only binding the VAO in
    // render() works just fine, but is it okay to do this or should I leave
    // it as is?
    //!!!!!!!!!!!!!!!!!!!
}

Scene::~Scene()
{
    glDeleteProgram(program);
    glDeleteBuffers(1, &indexBuffer);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteVertexArrays(1, &vertexArray);
}

namespace
{
    void printProgramInfoLog(GLuint program)
    {
        int logLength;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0)
        {
            char* log = new char[logLength];
            glGetProgramInfoLog(program, logLength, 0, log);
            fprintf(stderr, "%s", log);
            delete[] log;
        }
    }

    void printShaderInfoLog(GLuint shader)
    {
        int logLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0)
        {
            char* log = new char[logLength];
            glGetShaderInfoLog(shader, logLength, 0, log);
            fprintf(stderr, "%s", log);
            delete[] log;
        }
    }
}

Upvotes: 2

Views: 1017

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473352

VAOs do not store the data. They store the buffer object bindings and vertex formats. The buffer objects are still the holders of the data storage.

So no, don't do that.

Upvotes: 3

Related Questions