繁体   English   中英

仅更新所选三角形的颜色,VBO更新

[英]Updating only Color of selected Triangles, VBO update

实际上,我对使用glBufferSubData和glMapBuffer感到有些困惑。 在我的程序中,我正在加载一个Triangles网格,因此我创建了Vertex的Struct并使用整个网格的数据初始化了VertexBuffer。 我实现了射线投射和射线三角形相交。 我要尝试做的是,如果我的光标与网格相交,则相交的三角形只要相交就会改变其颜色。 它目前可以正常工作,但是当我尝试使用50.000+顶点加载更大的网格时,它不再起作用。 我用glBufferData更新了整个VBO,因为我不明白如何用glBufferSubData仅更新三角形的颜色。 有人可以解释我如何只更新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);

}

glBufferSubData无需重新创建glBufferSubData更新缓冲区的一部分(或全部)。

在您的情况下,您可以进行一些演算以了解当前选定边的缓冲区(所谓的“偏移”)中以字节为单位位置 ,并仅针对该对顶点更新缓冲区。

glMapBuffer为您提供了一个(虚拟的)指向缓冲区的指针。 您可以使用C / C ++函数直接读取或写入该地址。 完成后要注意“取消映射”。

现在,您的缓冲区布局为Pos,Normal,Color并重复。 因此:PxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCbPxPyPzNxNyNzCrCgCb ...“交错数据”。 您必须小心更新的位置(字节)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM