OpenGL顶点缓冲区对象,是否可以访问顶点数据用于其他用途,例如碰撞检测



我目前正在使用Superbible 5th版附带的GLTools类。我正在寻找GLTriangleBatch类,它有以下代码:

// Create the master vertex array object
glGenVertexArrays(1, &vertexArrayBufferObject);
glBindVertexArray(vertexArrayBufferObject);

// Create the buffer objects
glGenBuffers(4, bufferObjects);
#define VERTEX_DATA     0
#define NORMAL_DATA     1
#define TEXTURE_DATA    2
#define INDEX_DATA      3
// Copy data to video memory
// Vertex data
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_VERTEX);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pVerts, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Normal data
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_NORMAL);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pNorms, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Texture coordinates
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[TEXTURE_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*2, pTexCoords, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_TEXTURE0, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Indexes
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*nNumIndexes, pIndexes, GL_STATIC_DRAW);
// Done
glBindVertexArray(0);
// Free older, larger arrays
delete [] pIndexes;
delete [] pVerts;
delete [] pNorms;
delete [] pTexCoords;
// Reasign pointers so they are marked as unused
pIndexes = NULL;
pVerts = NULL;
pNorms = NULL;
pTexCoords = NULL;

据我所知,代码传递指针pVerts,pNorms,pTexCoords,pIndexes的数组,并将它们存储在Vertex数组对象中,该对象本质上是顶点缓冲区对象的数组。这些存储在 GPU 上的内存中。然后删除原始指针。

我对访问顶点位置感兴趣,这些位置保存在 pVert 指向的数组中。

现在我的问题围绕着碰撞检测。我希望能够访问我的GLTriangleBatch的所有顶点的数组。我以后可以使用某种吸气剂方法通过vertexBufferObject获得它们吗?最好只保留 pVerts 指针并为此使用 getter 方法吗?我正在考虑性能,因为我希望将来实现 GJK 碰撞检测算法......

缓冲区对象在用作顶点数据的源时,是为了渲染而存在的。从性能的角度来看,通常不建议向后退(回读数据(。

你给glBufferData的提示有三种访问模式:DRAW,READ和COPY;这些模式告诉OpenGL你打算如何直接从缓冲区对象获取/检索数据。这些提示并不控制OpenGL应该如何从/写入它。这些只是提示;API 不会强制实施任何特定行为,但违反这些行为可能会导致性能不佳。

DRAW 表示您将把数据放入缓冲区,但不会从中读取。READ 表示您将从缓冲区读取数据,但不会写入它(通常用于转换反馈或像素缓冲区(。COPY 意味着您既不会直接读取也不会写入缓冲区。

请注意,没有"读取和写入"的提示。只有"写"、"读"和"两者都不是"。考虑一下,这是一个提示,说明将数据直接写入缓冲区,然后开始从该缓冲区读取是多么好的想法。

同样,提示是针对用户直接获取或检索数据。 glBufferDataglBufferSubData和各种映射函数都执行写入操作,而glGetBufferSubData和映射函数都执行读取操作。

无论如何,您不应该这样做。如果需要在客户端上使用位置数据,请在客户端内存中保留位置数据的副本。

此外,某些驱动程序完全忽略使用提示。相反,他们根据您实际使用缓冲区对象的方式来决定将缓冲区对象放置在何处,而不是您说打算如何使用它。这对您来说会更糟,因为如果您开始从该缓冲区读取,驱动程序可能会将缓冲区的数据移动到速度不那么快的内存中。它可以移出 GPU,甚至移动到客户端内存空间中。

但是,如果您坚持这样做,则有两种方法可以从缓冲区对象读取数据。 glGetBufferSubDataglBufferSubData的反数。而且,您始终可以映射缓冲区以进行读取而不是写入。

相关内容

  • 没有找到相关文章

最新更新