【问题标题】:Hooking OpenGL Help (4 - 5 Questions)挂钩 OpenGL 帮助(4 - 5 个问题)
【发布时间】:2012-08-23 23:37:20
【问题描述】:

好的,所以我已经使用我自己的 glwrapper 成功地连接了所有 OpenGL 函数。我遇到的问题是英特尔/Nvidia 与 ATI 的对比。我正在挂钩模型并为每个模型生成 ID,这样我就可以知道正在呈现什么。

以下是我目前掌握的信息+区别:

glPushMatrix()

glMultMatrixf({0.70710671, 0, 0.70710683, 0}
{0, 1, 0, 0}
{-0.70710683, 0, 0.70710671, 0}
{26368, -1125, 28416, 1})

glBindBufferARB(GL_ARRAY_BUFFER, 56)
glBufferSubDataARB(GL_ARRAY_BUFFER, 0, 11544, 0x0B2DF6EC)
glGenBuffersARB(1, 0x0AE6231C)
glBindBufferARB(GL_ARRAY_BUFFER, 65)
glBufferDataARB(GL_ARRAY_BUFFER, 11544, 0x0B2DF6EC, GL_STATIC_DRAW)   
glGenBuffersARB(1, 0x0AE6231C)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 66)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, 7020, 0x0B2DF6EC, GL_STATIC_DRAW)

//上面的一切都是由两个显卡完成的。下面是问题所在。

glBindBufferARB(GL_ARRAY_BUFFER, 56)         //Intel/Nvidia makes this NULL.
glVertexPointer(3, GL_FLOAT, 12, 0x00000000) //Intel/NVidia makes this Not 0x00000.
glEnableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER, 65)
glColorPointer(4, GL_UNSIGNED_BYTE, 12, 0x00000000)
glEnableClientState(GL_COLOR_ARRAY)
glTexCoordPointer(2, GL_FLOAT, 12, 0x00000004)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glDrawElements(GL_TRIANGLES, 3510, GL_UNSIGNED_SHORT, 0x00000000)

我想知道为什么要为 Nvidia && Intel 卡的 bindbuffer 调用清空而不是清空顶点指针,而在 ATI 上,一切都如上所示。

有什么区别?另外我的第二个问题是,如果我存储了指向顶点和索引的指针(保证它们不会被删除),我怎样才能得到每个顶点?

例子:

VBO CurrentBuffer;
std::vector<VBO> Buffers;

Hook_glBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
{
    CurrentBuffer.target = target;
    CurrentBuffer.size = size;
    CurrentBuffer.usage = usage;     //To figure out if it's indices array or vertex array.
    CurrentBuffer.data = data;       //Let us assume that this pointer is never deleted.

    (*original_BufferDataArb)(target, size, data, usage);
}

Hook_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
    CurrentBuffer.VNull = (pointer == NULL) ? true : false;
    CurrentBuffer.VPointer = pointer;  //This can be both null or not null.
    CurrentBuffer.VSize = size;
    CurrentBuffer.Vtype = type;
    CurrentBuffer.Stride = stride;
    Buffers.push_back(CurrentBuffer);

    (*original_VPointer)(size, type, stride, pointer);
}


void Hook_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
{
    if (mode == GL_TRIANGLES)
    {
        const GLfloat* Pointer = static_cast<const GLfloat*>(Buffers.back().VPointer);  //Assuming it isn't NULL.
        for (int I = 0; I < count / 3; ++I)  //For each triangle.
        {
            int X = *(reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer)));
            int Y = *(reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer) + (Buffers.back().Stride)) + 1);
            int Z = *(reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer) + (2 * Buffers.back().Stride)) + 2);
        }
    }

    (*original_DrawElements)(mode, count, type, indices);
}

我是否正确地迭代了指针?此外,如果 vertexpointer 为空,有没有办法可以使用 bufferdata 使用来获取每个顶点?我读到我能做到:

if (CurrentBuffer.VNull)
{
    GLfloat* IndexPointer = Buffers[Buffers.size()].data;      //Index pointer is GL_Element_Array_Buffer
    GLfloat* VertexPointer = Buffers[Buffers.size() - 1].data; //Vertex pointer is GL_Array_Buffer

    for (int I = 0; I < TriangleCount; ++I)
    {
        int X = *VertexPointer[IndexPointer[I]];
        int Y = *VertexPointer[IndexPointer[I]] + 1;
        int Z = *VertexPointer[IndexPointer[I]] + 2;
    }
}

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:
    glBindBufferARB(GL_ARRAY_BUFFER, 56)         //Intel/Nvidia makes this NULL.
    glVertexPointer(3, GL_FLOAT, 12, 0x00000000) //Intel/NVidia makes this Not 0x00000.
    

    您确定,在您的 Intel/NVidia 案例中,程序没有主动设置这些值。空值作为 glVertexPointer 的数据参数只有在绑定了缓冲区对象时才有意义。但是,如果没有绑定缓冲区对象,例如通过使用 ID 为 0 的 glBindBuffer 调用解除绑定,则 glVertexPointer 的数据参数必须是非空指针。

    【讨论】:

    • +1 我没有考虑过,是的,它正在设置它。嗯,但为什么它会在 intel/nvidia 上这样做,但把它留在 ati 上?那是我不确定的。无论哪种方式,它都是一样的,对吧?我不明白的是为什么要这样做或为什么将其设置为 0。有区别吗?
    • @CantChooseUsernames:也许将其设置为零只是正常操作的一部分,您只是在程序执行的不同时间看到它,因为在 NVidia 或 Intel HW 上会触发不同的代码路径。寻找调用glGetString 的程序——如果是这样,它可能会根据硬件(怪癖、变通方法等)对其渲染路径进行一些更改。另请注意,如果版本 >= OpenGL-2,程序也可能会请求 glBindBuffer(不带 ARB)
    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多