粒子和OpenGL出现问题,什么也没画

时间:2019-04-20 16:29:20

标签: c++ opengl

我正在学习OpenGL,并且正在尝试在应用程序中实现一些粒子。

为此,我学习了一些课程。

但是当我尝试渲染我的粒子时,什么也没有发生,甚至都没有进入着色器(我试图在其中放入无限循环,什么也没发生)。我尝试了很多事情,也许有些我不理解的东西。

我创建了一个类Particle,具有构造函数,更新和draw方法,我按照课程的每个步骤进行操作,并将其调整为适合我的课程(该课程在主循环中完成所有操作)。

我的粒子课有一些私人成员:

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和垫子,但是没什么重要的。

在我的着色器中,我只尝试这样做:

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 个答案:

答案 0 :(得分:1)

您必须创建一个VAO(顶点数组对象):

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

请注意,您无需在draw()调用期间仅在初始化期间更新VAO状态。