Skip to main content
Became Hot Network Question
added 240 characters in body
Source Link

Note

These snippets are part of a quite big project...

If somebody needs a MRE, please add a comment: I can add the initialization code and whatever is needed as soon as I get to use my device and test the code


Note

These snippets are part of a quite big project...

If somebody needs a MRE, please add a comment: I can add the initialization code and whatever is needed as soon as I get to use my device and test the code

Source Link

OpenGL: Freeing allocated memory

Here's a snippet of my code. I have a Button structure made up by 2 Figure structures, which contains vertices, colors and the relative VBOs and VAO.

I have a function to allocate the memory and one to free it, but I'm not sure if it's missing something.

#include "GL/glew.h"
#include "GL/freeglut.h"

#define GLM_ENABLE_EXPERIMENTAL
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtx/transform.hpp"
#include "glm/gtc/type_ptr.hpp"

// Structures
typedef struct {
    std::vector<glm::vec2> vertices;
    std::vector<glm::vec4> colors;
    GLuint VAO, VBO_V, VBO_C;
    int drawMode;
} Figure;

typedef struct {
    glm::vec2 pos;
    glm::vec2 size;
    glm::vec4 color;
    glm::vec4 colorHover;
    Figure bg;
    Figure border;
    void (*onClick)(void);
} Button;

// Creation
Button* createButton(float posx, float posy, float width, float height,
    glm::vec4 color, glm::vec4 colorHover, glm::vec4 colorBorder, void (*onClick)(void))
{
    Button* button = new Button;

    button->pos.x = posx;
    button->pos.y = posy;
    button->size.x = width;
    button->size.y = height;
    button->color = color;
    button->colorHover = colorHover;
    button->onClick = onClick;

    // Background Figure
    button->bg.drawMode = GL_TRIANGLES;
    button->bg.vertices.push_back({ -1.0f, 1.0f });
    button->bg.vertices.push_back({ -1.0f, -1.0f });
    button->bg.vertices.push_back({ 1.0f, 1.0f });
    button->bg.vertices.push_back({ 1.0f, 1.0f });
    button->bg.vertices.push_back({ 1.0f, -1.0f });
    button->bg.vertices.push_back({ -1.0f, -1.0f });
    for (int i = 0; i < button->bg.vertices.size(); i++)
    {
        button->bg.colors.push_back(button->color);
    }
    // Generate VAO 
    glGenVertexArrays(1, &button->bg.VAO);
    glBindVertexArray(button->bg.VAO);
    // VBO for vertices
    glGenBuffers(1, &button->bg.VBO_V);
    glBindBuffer(GL_ARRAY_BUFFER, button->bg.VBO_V);
    glBufferData(GL_ARRAY_BUFFER, button->bg.vertices.size() * sizeof(glm::vec2), button->bg.vertices.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(0);
    // VBO for colors
    glGenBuffers(1, &button->bg.VBO_C);
    glBindBuffer(GL_ARRAY_BUFFER, button->bg.VBO_C);
    // Check: cambiare a GL_DYNAMIC_DRAW?
    glBufferData(GL_ARRAY_BUFFER, button->bg.colors.size() * sizeof(glm::vec4), button->bg.colors.data(), GL_DYNAMIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(1);

    // Border Figure
    button->border.drawMode = GL_LINE_LOOP;
    button->border.vertices.push_back({ -1.0f, 1.0f });
    button->border.vertices.push_back({ -1.0f, -1.0f });
    button->border.vertices.push_back({ 1.0f, -1.0f });
    button->border.vertices.push_back({ 1.0f, 1.0f });
    for (int i = 0; i < button->border.vertices.size(); i++)
    {
        button->border.colors.push_back({ 1.0f, 1.0f, 1.0f, 1.0f });
    }
    glGenVertexArrays(1, &button->border.VAO);
    glBindVertexArray(button->border.VAO);
    glGenBuffers(1, &button->border.VBO_V);
    glBindBuffer(GL_ARRAY_BUFFER, button->border.VBO_V);
    glBufferData(GL_ARRAY_BUFFER, button->border.vertices.size() * sizeof(glm::vec2), button->border.vertices.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glGenBuffers(1, &button->border.VBO_C);
    glBindBuffer(GL_ARRAY_BUFFER, button->border.VBO_C);
    glBufferData(GL_ARRAY_BUFFER, button->border.colors.size() * sizeof(glm::vec4), button->border.colors.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);

    return button;
}

void destroyButton(Button* button)
{
    glDeleteBuffers(1, &button->bg.VBO_V);
    glDeleteBuffers(1, &button->bg.VBO_C);
    glBindVertexArray(0); // Unbind any currently bound VAO
    glDeleteVertexArrays(1, &button->bg.VAO);
    button->bg.vertices.clear();
    button->bg.colors.clear();

    glDeleteBuffers(1, &button->border.VBO_V);
    glDeleteBuffers(1, &button->border.VBO_C);
    glBindVertexArray(0); // Unbind any currently bound VAO
    glDeleteVertexArrays(1, &button->border.VAO);
    button->border.vertices.clear();
    button->border.colors.clear();

    delete button;
}

int main(int argc, char** argv)
{
  // glut/OpenGL init code
  // [...]

  Button* myButton = createButton(100.0f, 100.0f, 150.0f, 40.0f,
    { 0.0f, 0.0f, 0.7f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, nullptr);
  destroyButton(myButton);
  
  return 0;
}

Is that the correct approach to free the allocated resources, or am I missing something? Is it ok to delete VAO after the VBOs?