Передача вершин позиции частицы (glm vec3s) в объекты буфера вершин

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

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, не работает. Какие-либо предложения?


person jaykumarark    schedule 21.11.2013    source источник


Ответы (2)


Я бы подумал о загрузке полного вектора частиц в 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. Поскольку ваша структура данных частиц содержит два поля, ваш шаг не равен нулю.

    • This is the second-to-last parameter in the call to glVertexAttribPointer (...).

В качестве альтернативы вы можете рассмотреть отдельную структуру данных для хранения данных, которые вам действительно нужны для рендеринга, из данных, необходимых для моделирования на стороне ЦП:

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. Вы будете намного более эффективно использовать память (со стороны графического процессора) и не потребуете какой-либо специальной обработки, когда придет время отправлять данные вершин на графический процессор. Конечно, в наши дни системы частиц с отслеживанием состояния могут быть полностью реализованы на графическом процессоре, начните с малого.

person Andon M. Coleman    schedule 21.11.2013
comment
Что ж, у меня возникла мысль создать структуру данных отдельно для атрибута частицы для облегчения доступа. Но потом я подумал, что наличие класса частиц было бы более подходящим с точки зрения управления кодом. Спасибо за идею. - person jaykumarark; 22.11.2013

Вы должны передать целочисленное значение в оператор векторного массива. Если вы пытаетесь создать массив glm::vec3 для передачи в glBufferData, вам придется сделать это вручную - возможно, с помощью цикла for и динамического распределения.

person Brian Gradin    schedule 21.11.2013