Luqman Akash
Luqman Akash

Reputation: 41

Updating only Color of selected Triangles, VBO update

actually Im a bit confused about using glBufferSubData and glMapBuffer. In my program I'm loading a mesh of Triangles so i created a Struct of Vertex and initialized my VertexBuffer with the data of whole mesh. I implemented ray-casting and ray-triangle intersection. What im trying to do is, if my cursor intersects with the mesh, the intersected triangle changes his color as long its get intersected. Its working at the moment but when I try to load a bigger mesh with 50.000+ Vertices it doesnt work anymore. I am updating my whole VBO with glBufferData because I dont understand how I can update only Color of Triangles with glBufferSubData. Can someone explain me how I can update only the specific part (e.g. Color) of my VBO ?

struct Vertex
{
    glm::vec3  Pos;
    glm::vec3  Normal;
    glm::vec3  Color;
};

VertexBuffer(void* vertices, size_t size)
{
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_DYNAMIC_DRAW);

    glBindVertexArray(0);
}

void Render()
{
    glBindVertexArray(vertexBuffer->VAO);
    glUseProgram(Fill->program);

    glUniformMatrix4fv(glGetUniformLocation(Fill->program, "model"), 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(glGetUniformLocation(Fill->program, "view"), 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(glGetUniformLocation(Fill->program, "projection"), 1, GL_FALSE, glm::value_ptr(proj));

    for (int j = 0; j < numVertices; j += 3){

        if (intersectPlane(this->Vertices[j], this->Vertices[j + 1], this->Vertices[j + 2], ray, orig)){

            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);
            this->Vertices[j].Color = glm::vec3(1.0, 0.0, 0.0);
            this->Vertices[j + 1].Color = glm::vec3(1.0, 0.0, 0.0);
            this->Vertices[j + 2].Color = glm::vec3(1.0, 0.0, 0.0);
            glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), Vertices, GL_DYNAMIC_DRAW);
        }
        else{
            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);
            this->Vertices[j].Color = glm::vec3(0.695f, 0.695f, 0.695f);
            this->Vertices[j + 1].Color = glm::vec3(0.695f, 0.695f, 0.695f);
            this->Vertices[j + 2].Color = glm::vec3(0.695f, 0.695f, 0.695f);
            glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), Vertices, GL_DYNAMIC_DRAW);
        }
    }

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->buffer);

    GLuint posLoc = glGetAttribLocation(Fill->program, "Position");
    GLuint norm = glGetAttribLocation(Fill->program, "Normal");
    GLuint colo = glGetAttribLocation(Fill->program, "Color");

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Pos));
    glVertexAttribPointer(norm, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Normal));
    glVertexAttribPointer(colo, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color));

    glEnableVertexAttribArray(posLoc);
    glEnableVertexAttribArray(norm);
    glEnableVertexAttribArray(colo);

        glDrawArrays(GL_TRIANGLES, 0, numVertices);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);

}

Upvotes: 0

Views: 268

Answers (1)

Ripi2
Ripi2

Reputation: 7198

glBufferSubData updates part (or the whole) of the buffer without the need to recreate it.

In your case you can do some calculus to know the position in bytes inside the buffer (so called "offset") of the edge currently selected, and update the buffer just for that pair of vertices.

glMapBuffer gives you a (virtual) pointer to the buffer. You can read or write to that address directly using your C/C++ functions. Be aware to "unmap" when done.

Now, your buffer layout is Pos,Normal,Color and repeat. So: PxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCb... "interleaved data". You must be carefull with the positions (bytes) you update.

Upvotes: 1

Related Questions