Проблема с Particle и OpenGL, ничего не нарисовано - PullRequest
1 голос
/ 20 апреля 2019

Я изучаю OpenGL и пытаюсь внедрить некоторые частицы в свое приложение.

Для этого я прошел несколько курсов.

Но когда я пытаюсь визуализировать мои частицы, ничего не происходит, они даже не попадают в шейдер (я пытался вставить в него какой-то бесконечный цикл, и ничего не произошло). Я много чего перепробовал, может есть что-то, чего я не понял ..

Я создал класс Particle с конструктором, обновлением и методом рисования, я следил за каждым этапом курса и адаптировал его к своему классу (курс выполняет все в основном цикле).

У моего класса частиц есть несколько закрытых членов:

private:

    size_t maxSize_;

    std::vector<float> quadData_;
    unsigned int dataVbo_;

    std::vector<float> posData_;
    unsigned int posVbo_;

    std::vector<float> colorData_;
    unsigned int colorVbo_;


    std::list<Particle> allParticles_;

и вот инициализация Particles:

Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{

    posData_.resize(maxSize_*4);
    colorData_.resize(maxSize_*4);


    glGenBuffers(1, &dataVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
    glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);


    // The VBO containing the positions and sizes of the particles
    glGenBuffers(1, &posVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);

    // The VBO containing the colors of the particles
    glGenBuffers(1, &colorVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);

}

и ничья:

void Particles::draw(){


    size_t count(posData_.size());

    glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());

    glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
    glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());


    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);

    // 2nd attribute buffer : positions of particles' centers
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);

    // 3rd attribute buffer : particles' colors
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);

    glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
    glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
    glVertexAttribDivisor(2, 1); // color : one per quad -> 1

    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
}

И в моем основном цикле я делаю это:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myParticules.update(elapsedTime);

    glDisable(GL_DEPTH_TEST);

    glUseProgram(_particleShad);

    myParticles.draw();

Я также отправляю какие-нибудь униформы vec и mat, но ничего важного.

В моем шейдере я только пытаюсь сделать это:

Vertex :
    gl_Position = vec4(squareVertices.xyz, 1);
        //squareVertices contain the vertices of my square for my particles

Fragment :
        color = vec4(1, 1, 1, 1);

Я не нахожу ничего плохого, мне действительно нужна помощь, я полностью потерян.

1 Ответ

1 голос
/ 20 апреля 2019

Вы должны создать VAO (Vertex Array Object):

class Particles {
private:
     // add:
     GLuint vao;
     ...

Инициализация:

Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{

    posData_.resize(maxSize_*4);
    colorData_.resize(maxSize_*4);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &dataVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
    glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);


    // The VBO containing the positions and sizes of the particles
    glGenBuffers(1, &posVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);

    // The VBO containing the colors of the particles
    glGenBuffers(1, &colorVbo_);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
    // Initialize with empty (NULL) buffer : it will be updated later, each frame.
    glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);


    glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
    glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
    glVertexAttribDivisor(2, 1); // color : one per quad -> 1
}

Код чертежа:

void Particles::draw(){
    size_t count(posData_.size());

    glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
    glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());

    glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
    glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());

    glBindVertexArray(vao);
    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}

Обратите внимание, что вам не нужно обновлять состояние VAO во время вызова draw(), только во время инициализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...