Initializing a OpenGL VBO with a struct

Viewed 353

Im having problems to add a struct to a OpenGL VBO

This is my struct

struct Vertex {

    //vertices
    std::vector<glm::vec3> vertices;

    //texture coordinates
    std::vector<glm::vec3> texCord;
}

This is how im assigning and initializing the VBO

glGenVertexArrays(1, &buffer.VAO);
glGenBuffers(1, &buffer.VBO);
glGenBuffers(1, &buffer.EBO);

glBindBuffer(GL_ARRAY_BUFFER, buffer.VAO);

//Initialize buffer data 
glBindBuffer(GL_ARRAY_BUFFER, buffer.VBO);
glBufferData(GL_ARRAY_BUFFER,
            vertex.vertices.size() * sizeof(glm::vec3) +
            vertex.texCord.size() * sizeof(glm::vec3)
            &vertex,
            GL_STATIC_DRAW);

//indices attribute
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertex.indices.size() * sizeof(glm::vec2), &vertex.indices[0], GL_STATIC_DRAW);

//vertices coordinates attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, vertices));

//texture coordinates attribute
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCord));

And my draw command looks like this

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(buffer.VAO);
glDrawElements(GL_TRIANGLES, vertex.indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

Is it possible to initialize buffer data with a raw struct and if yes how?

2 Answers

std::vector stores a pointer to dynamically allocated memory. However, you must pass a consecutive buffer to glBufferData.
Create the object's data store with glBufferData, but use glBufferSubData to initialize the buffer:

size_t vertexSize = vertex.vertices.size() * sizeof(glm::vec3);
size_t texCordSize = vertex.texCord.size() * sizeof(glm::vec3);

glBufferData(GL_ARRAY_BUFFER, vertexSize + texCordSize, nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize, vertex.vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertexSize, texCordSize, vertex.texCord.data());

Thanks to @Rabbid76 I now solved my problem. Code is down below.

Note: I need to create the buffer before filling data with glBufferSubData

glGenVertexArrays(1, &buffer.VAO);
glGenBuffers(1, &buffer.VBO);
glGenBuffers(1, &buffer.EBO);

glBindBuffer(GL_ARRAY_BUFFER, buffer.VAO);

int vertexSize = sizeof(glm::vec3) * vertex.vertices.size();
int texCordSize = sizeof(glm::vec2) * vertex.texCord.size();
int totalSize = vertexSize + texCordSize;

int indicesSize = sizeof(unsigned int) * vertex.indices.size();

//Create Buffer dynamically
glBufferData(GL_ARRAY_BUFFER, totalSize, NULL, GL_DYNAMIC_DRAW);

//Fill the buffer with data 
glBindBuffer(GL_ARRAY_BUFFER, buffer.VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize, vertex.vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertexSize, texCordSize, vertex.texCord.data());

//indices attribute
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, vertex.indices.data(), GL_STATIC_DRAW);

//position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) + sizeof(glm::vec2), (void*)0);
        
//texture attribute
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) + sizeof(glm::vec2), (void*)sizeof(glm::vec3));

glBindVertexArray(0);
Related