将粒子位置(glm vec3s)顶点传递给顶点缓冲区对象

时间:2013-11-21 18:25:22

标签: c++ visual-c++ opengl particle-system

我有粒子和粒子系统类。在我的主程序中,我创建了一个粒子系统实例并初始化其中的粒子。在显示功能中,我想一次将所有粒子的位置传递到顶点缓冲区。但我不确定用于访问所有位置顶点的符号。

class particle{
    glm::vec3 pos;
    glm::vec3 vel;
}


class particleSystem{
    std::vector<particle> m_particles; 
}

我试过这样的事情:

//Displaying particles starts here
glGenBuffers(1, &particleBuffers); 
glBindBuffer(GL_ARRAY_BUFFER, particleBuffers);
glBufferData(GL_ARRAY_BUFFER, sizeof(ps.m_particles[].pos), ps.m_particles[].pos, GL_STATIC_DRAW);
glVertexAttribPointer(position_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_POINTS, 0, (GLsizei)ps.m_particles.size());         //Draw them to screen
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Displaying particles ends here

其中ps是粒子系统类的一个实例。我用来访问glBufferData函数中粒子的所有位置的符号不起作用。有什么建议?

2 个答案:

答案 0 :(得分:3)

我会考虑将 整个 粒子矢量上传到GPU,如下所示:

struct particle {
  glm::vec3 pos;
  glm::vec3 vel;
};

[...]

glBufferData          (GL_ARRAY_BUFFER, sizeof (particle) * ps.m_particles.size (), 
                       &ps.m_particles [0], GL_STATIC_DRAW);
glVertexAttribPointer (position_loc, 3, GL_FLOAT, GL_FALSE, sizeof (particle), 0);

我不确定您的原始代码是如何工作的,如果您将particle声明为类,这些字段默认具有私有权限。

这里有两点需要提及:

  1. &ps.m_particles [0]是获取指向代表矢量数据存储的连续内​​存块的指针的标准方法。

  2. 由于您的粒子数据结构包含两个字段,因此您的步幅不为零。

    • 这是glVertexAttribPointer (...)
    • 调用中倒数第二个参数

  3. 或者,您可以考虑使用单独的数据结构来存储从CPU端仿真所需的数据中实际渲染所需的数据:

    struct particle_vtx {
      glm::vec3 pos;
      //glm::vec3 color;
    };
    
    struct particle_state {
      glm::vec3 vel;
      //GLuint texture;
    };
    
    [...]
    
    class particleSystem {
      std::vector<particle_vtx>   m_particle_verts;
      std::vector<particle_state> m_particle_states;
    };
    

    这可能是最通用的解决方案,因为您将拥有两个连续内存池,将GPU所需内容与CPU需求区分开来。您将获得更高的内存效率(在GPU方面),并且在将顶点数据发送到GPU时不需要任何特殊处理。如今,授权的有状态粒子系统可以完全在GPU上实现,从小处开始。

答案 1 :(得分:0)

您必须将整数值传递给向量数组运算符。如果您尝试创建一个glm::vec3数组以传递到glBufferData,则必须手动执行此操作 - 可能是通过使用for循环和动态分配。