2013-05-04 3 views
0

Я пытаюсь подражать GL_POINT OpenGL для отладки и обратной обработки OpenGL. Я пытаюсь выполнить итерацию Vertex-Buffer с указанием его указателя, указателя-указателя-указателя и шага.Iterate Vertex 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. 
} 

Как я могу получить вершины для каждого треугольника, если у меня есть:

  • ВБО Pointer.
  • The Stride.
  • Указатель указателя.
+0

Я не вижу, что это имеет отношение к 'GL_POINTS'. –

+0

GL_POINT делает это, когда вы используете его с glDrawElements. Если я устанавливаю GL_FILL, он заполняет всю модель. Если я устанавливаю GL_POINTS, он отображает только каждую вершину. Я хочу получить каждую из этих вершин так же, как это делает функция, когда она использует GL_POINTS. Наверное, я пытаюсь понять, как gl_drawelements работает и подражает ему. – Brandon

+0

Я по-прежнему смущен относительно того, что это связано с рендерингом GL_POINTS. Они используют 'GL_TRIANGLES'. Вы говорите о режиме * polygon *, или вы говорите о примитивном типе, который вы передаете в функцию draw? –

ответ

3

Как я могу получить вершины для каждого треугольника, если у меня есть:

  • ВБО Pointer.
  • The Stride.
  • Указатель указателя.

Вы не можете.

Буферные объекты не имеют указателей. glBufferData и glBufferSubDataкопия данные от данного указателя в хранилище объектов буфера. Как и во всех функциях OpenGL, которые не заканчиваются словом «Указатель», after the execution of these functions, the application is free to do whatever it wants with them. OpenGL не поддерживает эти указатели. И поэтому вы тоже не должны.

Если вы хотите отследить память, хранящуюся в буферном объекте, вам придется выделить память самостоятельно и сделать копию самостоятельно. Когда приходит вызов glBufferData или glBufferSubData, вам придется скопировать данные с этого указателя во внутреннее хранилище. Если пользователь сопоставляет буфер для записи, вам придется ждать, пока буфер не будет удален, а затем скопируйте данные из буфера с помощью glGetBufferSubData.

Это не будет быстро.

Кроме того, вам нужно больше, чем шаг, если вы намерены отображать данные вершин. Вам нужен тип; предполагая, что пользователь использует только GL_FLOAT, это довольно плохое предположение (если вы не хотите, чтобы ваш код был специфичным для приложения).

В любом случае, вы имеете дело с очень плохо организованным приложением.Кажется, что используют объекты буфера для , некоторые атрибуты (например, glColorPointer) и не используют их для других (glVertexPointer). Это сделает вашу работу труднее.

Вы в основном должны делать то, что делает OpenGL. Для каждого атрибута вам необходимо записать тип, шаг, нормализацию и заданный «указатель». Но вам также необходимо проверить, привязан ли буфер к GL_ARRAY_BUFFER (это означает, что вам нужно stop, притворяясь, что может быть только один буфер, привязанный за раз. Вам нужно отслеживать, что привязано к каждой другой цели) ,

Если буфер связан с GL_ARRAY_BUFFER, когда вы вызываете одну из функций «Указатель», это означает, что данный «указатель» не является указателем; это смещение байта относительно начала объекта буфера. Поэтому вам нужно будет сохранить «указатель» и объект буфера, который был привязан к GL_ARRAY_BUFFER во время вызова функции. Если буфер не привязан к нему, то указатель фактически является реальным указателем на память, который приложение должно поддерживать, пока оно пытается выполнить с ним.

Во время рендеринга для каждого атрибута вы либо используете указатель атрибута, либо используете смещение буфера + смещение, чтобы вычислить, где начинаются данные объекта буфера. Вы используете это для доступа к своей копии данных объекта буфера. В любом случае вы разрешаете указатель. Затем вы используете тип и нормализацию, чтобы решить, как читать данные, и вы используете шаг, чтобы перейти от одной вершины к следующей.

+0

Ах, я вижу. Тогда у меня есть первая часть. Я скопировал данные из указателя, переданного в glBufferData и SubData, и сохранил его в моем векторе ListOfBuffers. Я не хранили какой тип, например GL_ARRAY_BUFFER, потому что я только хранил буферы, которые были GL_ARRAY_BUFFER. Я буду хранить все сейчас. Я не знаю, как получить нормализацию или прочитать данные, используя это, но я буду искать его. Если это то же самое, что и в математическом классе, то, я думаю, я делю X по длине, так что длина вектора равна единице. – Brandon

Смежные вопросы