How can I iterate a buffer with a stride? For example, I saved the pointer to a vertex buffer for later use. I've got the stride, the pointer, and triangle count for vertices. I want to iterate my pointer using this info to get the vertices. I'm doing it wrong right now because it doesn't display all of them.

Anyone have any idea how I can use this information to get each vertex?

struct BufferObject
{
    GLint ID;
    GLsizei Size;
    GLboolean Reserved;
    GLenum Type, Usage;
    const GLvoid* BufferPointer;
};

BufferObject CurrentBuffer;
std::vector ListOfBuffers;

GL_EXPORT __stdcall void GLHook_glBindBufferARB(GLenum target, GLuint buffer)
{
    BufferBound = true;
    CurrentBuffer.Type = target;
    CurrentBuffer.ID = buffer;

    (*optr_glBindBufferARB) (target, buffer);
}

GL_EXPORT __stdcall void GLHook_glBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
{
    if (BufferBound)
    {
        BufferBound = false;
        CurrentBuffer.Size = size;
        CurrentBuffer.Usage = usage;
        CurrentBuffer.BufferPointer = data;
        ListOfBuffers.push_back(CurrentBuffer);
    }
    (*optr_glBufferDataARB) (target,  size, data, usage);
}

void IterateModelVertices()
{
        for (size_t I = 0; I < ListOfBuffers.size(); I++)
        {
            if (ListOfBuffers[I].ID == CurrentBuffer.ID)
            {
                const GLfloat* Ptr = static_cast(ListOfBuffers[I].BufferPointer);

                for (int J = 0; J < ModelPtr->TriangleCount; J++)
                {
                    Not sure if I'm using it correctly though.
                    ModelPtr->Vertices.push_back(Vector3D(*(Ptr + (J * ModelPtr->Stride)), *(Ptr + (J * ModelPtr->Stride + 1)), *(Ptr + (J * ModelPtr->Stride + 2))));
                }
                break;
            }
        }
}

I've also tried:

    for (int I = 0; I < TriangleCount; I++)
    {
       cout<<"X: " << *(Pointer + (I * Stride))<<endl;
       cout<<"Y: " << *(Pointer + (I * Stride + 1))<<endl;
       cout<<"Z: " << *(Pointer + (I * Stride + 2))<<endl;
    }

Recommended Answers

All 4 Replies

The problem here is that when you add a number to a pointer, it moves the pointer by that number of objects that the pointer points to, not by that number of bytes. Say you have float* ptr;, then *(ptr + 4) is equivalent to ptr[4], meaning that it gets the float value that is 4 floats after the pointer address, not the float value that is 4 bytes after the pointer address. In OpenGL, the stride is specified as a number of bytes, so I assume your "Stride" variables are also in bytes. The way to solve this is by casting the pointer to a 1-byte type pointer, for instance, char*, then do the addition by the stride, and then cast it back to the actual pointer type to retrieve the value. As so:

for (int I = 0; I < TriangleCount; I++)
{
   cout<<"X: " << *( reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer) + (I * Stride) ) ) << endl;
   cout<<"Y: " << *( reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer) + (I * Stride) ) + 1 ) << endl;
   cout<<"Z: " << *( reinterpret_cast<const GLfloat*>(reinterpret_cast<const char*>(Pointer) + (I * Stride) ) + 2 ) << endl;
}

Notice also how the + 1 and + 2 are put after the cast back to const GLfloat*.

commented: Perfect! +6

Wow... I got lost there ={
Usually I understand but this time I really got lost.

meaning that it gets the float value that is 4 floats after the pointer address, not the float value that is 4 bytes after the pointer address.

This part confused me. I got lost there. Can you break that down further?

You can try and run this:

#include <iostream>

float arr[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};

int main() {
  float* ptr = arr;

  // get the actual "address" that the pointer points to:
  std::size_t ptr_value = reinterpret_cast<std::size_t>(ptr);
  std::cout << "ptr = " << ptr_value << std::endl;

  // if you offset the pointer by 4, you get:
  float* ptr1 = ptr + 4;
  std::size_t ptr1_value = reinterpret_cast<std::size_t>(ptr1);
  std::cout << "ptr1 - ptr = " << ptr1_value - ptr_value << " bytes." << std::endl;

  // check this condition:
  if( ptr1_value - ptr_value == 4 * sizeof(float) )
    std::cout << "The difference between ptr1 and ptr is equal to 4 times the size of a float." << std::endl;

  // if you offset the pointer by 4 bytes, you get:
  float* ptr2 = reinterpret_cast<float*>(reinterpret_cast<char*>(ptr) + 4);
  std::size_t ptr2_value = reinterpret_cast<std::size_t>(ptr2);
  std::cout << "ptr2 - ptr = " << ptr2_value - ptr_value << " bytes." << std::endl;

  // check this condition:
  if( ptr2_value - ptr_value == 4 )
    std::cout << "The difference between ptr2 and ptr is equal to 4 bytes." << std::endl;

  return 0;
};

The meaning of my sentence was to explain the behavior of the above piece of code. Try it for yourself and you'll see.

PERFECT!! It works! I understand now =] Thank you so much mike!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.