从指针向量的OpenGL数组缓冲区

时间:2017-03-02 21:47:25

标签: c++ pointers opengl

问题 我有一个指向粒子的指针向量:

struct Particle {
    vec3 pos; // just 3 floats, GLM vec3 struct
    // ...
}
std::vector<Particle *> particles;

我想将此向量用作OpenGL中数组缓冲区的数据源 像这样:

glGenBuffers(1, &particleBuffer);
glBindBuffer(GL_ARRAY_BUFFER, particleBuffer);
int bufferSize = sizeof(Particle) * particles->size();
glBufferData(GL_ARRAY_BUFFER, bufferSize, /* What goes here? */, GL_STATIC_DRAW);

glEnableVertexAttribArray(positionAttribLocation);
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (void *)0);

有趣的行是glBufferData( ... )

如何让OpenGL获得数据指针?

2 个答案:

答案 0 :(得分:4)

  

如何让OpenGL获得数据指针?

你没有。

缓冲区对象的重点是数据存在于GPU可访问的内存中。指针是地址,指向CPU可访问对象的指针是指向CPU地址的指针。因此,它不是指向GPU可访问内存的指针。

此外,访问类似的间接数据结构难以置信效率低下。必须做两个指针间接只是为了访问单个值基本上破坏了内存访问的所有缓存一致性的机会。没有它,每个独立的粒子都是缓存未命中。

那很糟糕。这就是OpenGL不允许你这样做的原因。或者至少,它不允许你直接这样做。

执行此操作的正确方法是使用平面vector<Particle>,并根据需要移动它们。

答案 1 :(得分:0)

glBufferData需要一个指向您希望使用的数据数组的指针。在您的情况下,GLfloat[]将用于顶点。你可以编写一个从粒子向量创建GLfloat[]的函数。我使用的代码创建了一个GLfloat[],然后将其作为指向构造函数的指针传递,然后构造函数设置缓冲区数据。这是我的代码;

创建顶点数组 - GlFloat[]

GLfloat vertices[] = {  0, 0, 0, 
                        0, 3, 0,
                        8, 3, 0,
                        8, 0, 0  };

创建顶点之后,我创建一个缓冲区对象(只创建一个新缓冲区并设置它的数据);
Buffer* vbo = new Buffer(vertices, 4 * 3, 3);

我的缓冲区对象的构造函数是;

Buffer::Buffer(GLfloat* data, GLsizei count, GLuint componentCount) {
    m_componentCount = componentCount;

    glGenBuffers(1, &m_bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, m_bufferID);
    glBufferData(GL_ARRAY_BUFFER, count * sizeof(GLfloat), data, GL_STATIC_DRAW); //Set the buffer data to the GLFloat pointer which points to the array of vertices created earlier.
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

将此数组传递给缓冲区后,您可以删除该对象以节省内存,但建议保留该对象以防以后再次使用。

有关更多信息和更好的OpenGL实践,我建议您通过 TheChernoProject 查看以下youtube播放列表。
https://www.youtube.com/watch?v=qTGMXcFLk2E&list=PLlrATfBNZ98fqE45g3jZA_hLGUrD4bo6_&index=12