2

I'm learning OpenGL and I'm trying to implement some particles in my application.

To do so, I followed some courses.

But when I try to render my particles, nothing happen, it doesn't even enter the shader (I tried to put some infinite loop in it and nothing happened). I tried a lot of thing, maybe there is something I did not understand..

I created a class Particle, with a constructor, an update and a draw method, I followed every step of the course, and adapted it to my class (the course is doing everything in the main loop).

My particles class got some private members:

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_;

and here is the initialization of 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);

}

and the 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);
}

And in my main loop I'm doing this:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myParticules.update(elapsedTime);

    glDisable(GL_DEPTH_TEST);

    glUseProgram(_particleShad);

    myParticles.draw();

I'm also sending some uniform vec and mat, but nothing important.

In my shader I only try to do this:

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

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

I don't find anything wrong, I really need some help, I'm totally lost.

2
  • Try enabling alpha blending and enabling visibility of back-facing polygons Commented Apr 20, 2019 at 16:36
  • Sorry, should have mentionned it, but I allready did this, I tryied a lot of little option, but nothing changed Commented Apr 20, 2019 at 16:43

1 Answer 1

2

You must create a VAO (Vertex Array Object):

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

Initialization:

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
}

Drawing code:

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);
}

Notice how you don't need to update your VAO state during the draw() call, only during the initialization.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.