[英]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.