簡體   English   中英

迭代頂點緩沖區

[英]Iterate Vertex Buffer

我正在嘗試模擬OpenGL的GL_POINT進行調試和反向工程OpenGL。 我正在嘗試迭代給定Vertex-Buffer的指針,Index-Buffer指針和跨度。

所以我做了什么:

  • 我迷上了使用OpenGL的應用程序。
  • 我使用gDebugger(由AMD創建的用於調試的應用程序)監控了呼叫

要渲染單個模型,調用如下:

glPushMatrix()
glViewport(4, 165, 512, 334)
glMultMatrixf({1, 0, 0, 0}
{0, 1, 0, 0}
{0, 0, 1, 0}
{26880, -741, 26368, 1})

glGenBuffersARB(1, 0x0A2B79D4)
glBindBufferARB(GL_ARRAY_BUFFER, 15)
glBufferDataARB(GL_ARRAY_BUFFER, 17460, 0x0C85DE1C, GL_STATIC_DRAW)
glGenBuffersARB(1, 0x0A2B79D4)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 16)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, 8946, 0x0C85DE1C, GL_STATIC_DRAW)
glBindBufferARB(GL_ARRAY_BUFFER, 0)
glVertexPointer(3, GL_FLOAT, 12, 0x31CB24C9)
glEnableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER, 15)
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, 4473, GL_UNSIGNED_SHORT, 0x00000000)
glPopMatrix()

我掛接了每個調用,並將所有參數存儲到一個類和一些變量中。

typedef struct  //A struct to hold information about every buffer the application uses.
{
    GLint ID;
    GLsizei Size;
    GLboolean Reserved;
    GLboolean Bound;
    GLenum Type, Usage;
    uint32_t CheckSum;
    const GLvoid* BufferPointer;
} BufferObject;


BufferObject CurrentBuffer;  //Keep track of the currently bound buffer.
std::vector<BufferObject> ListOfBuffers;  //A list of all buffers used in the application.



//Detours the OpenGL function so that it calls this one first before calling the original one. (OpenGL call interception.)
void HookglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
    if ((size == 3) && (pointer != nullptr) && type == GL_FLOAT) //A model is rendering..
    {
        ModelRendering = true;
        CurrentModel.Stride = stride;
        CurrentModel.VertexPointer = pointer; //Store the pointer.
        ListOfModels.push_back(CurrentModel); //Store the model.
    }

    (*original_glVertexPointer) (size, type, stride, pointer); //Call the original function.
}

//Hook the drawing function and get each vertex being rendered.
void HookglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
{
    Model* ModelPtr = &ListOfModels.back();

    if (ModelPtr != nullptr)
    {
        for (int I = 0; I < count / 3; ++I) //So for every triangle, I want to get the vertex of it and store it in my Vertices vector..
        {
            //This needs to somehow use the stride to get the right vertex.
            //Perhaps CurrentBuffer.BufferPointer instead of ModelPtr->VertexPointer.
            int X = *reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(ModelPtr->VertexPointer) * I);
            int Y = *reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(ModelPtr->VertexPointer) * I + 1);
            int Z = *reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(ModelPtr->VertexPointer) * I + 2);
            ModelPtr->Vertices.push_back(Vector3D(X, Y, Z));
        }
    }
    (*original_glDrawElements) (mode, count, type, indices);  //call the original function.
}

如果有,如何獲得每個三角形的頂點:

  • VBO指針。
  • 大步前進。
  • 索引指針。

如果有,如何獲得每個三角形的頂點:

  • VBO指針。
  • 大步前進。
  • 索引指針。

你不能

緩沖區對象沒有指針 glBufferDataglBufferSubData 數據從給定的指針復制到緩沖區對象存儲中。 與所有不以“ Pointer”一詞結尾的OpenGL函數一樣, 在執行這些函數之后,應用程序可以自由地對它們執行任何操作 OpenGL 不會保留這些指針。 因此,您也不應該。

如果要跟蹤存儲在緩沖區對象中的內存,則必須自己分配內存並自己進行復制。 當調用glBufferDataglBufferSubData ,您將不得不將數據從該指針復制到內部存儲中。 如果用戶映射了要寫入的緩沖區,則必須等待緩沖區被取消映射,然后使用glGetBufferSubData從緩沖區復制回數據。

它不會很快。

此外,如果要渲染頂點數據,則需要大步前進。 您需要類型; 假設用戶僅使用GL_FLOAT是一個很糟糕的假設(除非您希望代碼是特定於應用程序的)。

無論如何,您都在處理一個行為異常的應用程序。 似乎對某些屬性(例如glColorPointer )使用緩沖區對象,而對其他一些屬性( glVertexPointer )不使用緩沖區對象。 這會使您的工作更加困難。

您基本上需要做OpenGL要做的事情。 對於每個屬性,您需要記錄類型,步幅,規范化和給定的“指針”。 但是,您需要檢查當前是否GL_ARRAY_BUFFER緩沖區綁定到GL_ARRAY_BUFFER (這意味着您需要停止假裝一次只能綁定一個緩沖區。您需要跟蹤綁定到每個不同目標的對象)。

如果在調用“指針”函數之一時將緩沖區綁定到GL_ARRAY_BUFFER ,則意味着給定的“指針”不是指針。 它是相對於緩沖區對象開始的字節偏移量。 因此,您將需要存儲在調用函數時綁定到GL_ARRAY_BUFFER的“指針” 緩沖區對象。 如果沒有綁定緩沖區,則該指針實際上是一個實內存指針,應用程序必須嘗試使用​​該內存保持活動。

在渲染時,對於每個屬性,您可以使用屬性的指針,也可以使用緩沖區對象+偏移量來計算緩沖區對象數據的起始位置。 您可以使用它來訪問緩沖區對象數據的副本。 無論哪種方式,您都可以解析為指針。 然后,您可以使用類型和規范化來確定如何讀取數據,並使用跨度從一個頂點到另一個頂點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM