[英]Iterate Vertex Buffer
我正在嘗試模擬OpenGL的GL_POINT進行調試和反向工程OpenGL。 我正在嘗試迭代給定Vertex-Buffer的指針,Index-Buffer指針和跨度。
所以我做了什么:
要渲染單個模型,調用如下:
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指針。
- 大步前進。
- 索引指針。
你不能
緩沖區對象沒有指針 。 glBufferData
和glBufferSubData
將數據從給定的指針復制到緩沖區對象存儲中。 與所有不以“ Pointer”一詞結尾的OpenGL函數一樣, 在執行這些函數之后,應用程序可以自由地對它們執行任何操作 。 OpenGL 不會保留這些指針。 因此,您也不應該。
如果要跟蹤存儲在緩沖區對象中的內存,則必須自己分配內存並自己進行復制。 當調用glBufferData
或glBufferSubData
,您將不得不將數據從該指針復制到內部存儲中。 如果用戶映射了要寫入的緩沖區,則必須等待緩沖區被取消映射,然后使用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.