OpenGL挂钩顶点缓冲区

时间:2012-08-05 22:46:22

标签: c++ opengl

情况:我正在注入使用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);

0 个答案:

没有答案