首页 > 解决方案 > 粒子和 OpenGL 的问题,没有绘制任何内容

问题描述

我正在学习 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);

我没有发现任何问题,我真的需要一些帮助,我完全迷路了。

标签: c++opengl

解决方案


您必须创建一个 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 状态,只需在初始化期间即可。


推荐阅读