情况:我正在注入使用Vertex Buffers渲染模型的应用程序。我想获得每个模型的每个顶点的精确坐标。我使用了弯路来跟踪传递给客户的信息。基本上所有信息都会在它到达该应用程序之前先通过我。
问题:我已截获所有OpenGL调用,如何获取顶点缓冲区数据?
我的代码如下:
struct BufferObject //My struct to hold all data gathered.
{
GLint ID;
GLsizei Size;
GLboolean Reserved;
GLenum Type, Usage;
const GLvoid* BufferPointer;
};
BufferObject CurrentBuffer;
std::vector<BufferObject> ListOfBuffers;
DLL_EXPORT __stdcall void MyHook_glBindBufferARB(GLenum target, GLuint buffer)
{
BufferBound = true;
CurrentBuffer.Type = target; //Save what kind of buffer it is.
CurrentBuffer.ID = buffer; //Save the buffer ID.
(*original_glBindBufferARB) (target, buffer);
}
DLL_EXPORT __stdcall void MyHook_glBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
{
if (BufferBound && CurrentBuffer.Type == target && target == GL_ARRAY_BUFFER) //If it's vertices, save them.. All the X, Y, Z's.
{
BufferBound = false;
CurrentBuffer.Size = size; //Save the buffer size.
CurrentBuffer.BufferPointer = data; //Not sure if to do this or to use memcpy or what.. :S
CurrentBuffer.Usage = usage; //Save it's usage.
ListOfBuffers.push_back(CurrentBuffer); //Add the current buffer to the list.
}
(*original_glBufferDataARB) (target, size, data, usage);
}
DLL_EXPORT __stdcall void MyHook_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
ModelRendering = true;
CurrentModel.Stride = stride; //A model is being rendered so save it's stride.
CurrentModel.NullVertex = (pointer == NULL);
CurrentModel.VertexPointer = pointer; //This seems to always be NULL.
ListOfModels.push_back(CurrentModel);
(*original_glVertexPointer) (size, type, stride, pointer);
}
DLL_EXPORT __stdcall void MyHook_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
{
if (ModelRendering) //If one of the models I'm tracking is being rendered.
{
Model* ModelPtr = &ListOfModels.back();
ModelPtr->ID = 0;
ModelPtr->TriangleCount = count / 3; //Should be correct.
if (!ModelPtr->NullVertex) //If vertexpointer was not null.
{
const GLfloat* Pointer = static_cast<const GLfloat*>(ModelPtr->VertexPointer); //Should be used to iterate each vertex? Gotten from vertex pointer..
ModelPtr->X = *Pointer + ModelPtr->Stride;
ModelPtr->Y = *Pointer + ModelPtr->Stride + sizeof(GLfloat); //I think?
ModelPtr->Z = *Pointer + ModelPtr->Stride + (2 * sizeof(GLfloat));
}
else //It's rendering from the vertex buffer.. This is what I need.
{
ModelPtr->X = *(ListOfBuffers[CurrentBuffer.ID].BufferPointer) + ModelPtr->Stride;
ModelPtr->Y = *(ListOfBuffers[CurrentBuffer.ID].BufferPointer) + ModelPtr->Stride + sizeof(GLfloat);
ModelPtr->Z = *(ListOfBuffers[CurrentBuffer.ID].BufferPointer) + ModelPtr->Stride + sizeof(GLfloat);
}
if ((ModelPtr->Stride == Stride) && Overlay)
original_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
original_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
original_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
(*original_glDrawElements) (mode, count, type, indices);
}
我使用了一个结构来保存我为每个缓冲区收集的所有数据,并使用一个向量来保存所有缓冲区的列表。我怎样才能获得数据?它必须是可能的,因为gDEBugger可以这样做:S。
这就是应用程序的作用:
//Creates a buffer and stores data in it.
glGenBuffersARB(1, 0x0BAD9664)
glBindBufferARB(GL_ARRAY_BUFFER, 49)
glBufferDataARB(GL_ARRAY_BUFFER, 97996, 0x266AF026, GL_STATIC_DRAW)
//Calls buffer 49 and starts to draw it.
glBindBufferARB(GL_ARRAY_BUFFER, 49)
glVertexPointer(3, GL_FLOAT, 24, 0x00000000)
glEnableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
glColorPointer(4, GL_UNSIGNED_BYTE, 24, 0x0000000C)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 56)
glDrawElements(GL_TRIANGLES, 1326, GL_UNSIGNED_SHORT, 0x00000000);