-2

I'm trying to create a simple particle system but I'm facing the segmentation fault error. My problem seems to be related to the number of vertex attributes I'm passing. One vertex has 3 floats, corresponding to x, y and z coordinates, so if I want to create 1 million particles, I'll have an array of 3 million floats containing the positions coordinates for each particle. The problem is that if I go above a certain number of particles, like around 400000, I get a segmentation fault.

Here's part of the code:

#define NP  1000000

int main(void)
{
    // Init GLFW
    MyGLFW myglfw(4, 5, W, H, "Particles");
    // Create shader program
    Shader shader("shaders/shader.vs", "shaders/shader.fs");

    // Define particle's vertex attrib
    float particleData[NP * 3];
    for(uint i = 0; i < NP * 3; i++)
    {
        // Creates a new particle with random position in the given range
        Particle p(-1.0f, 1.0f);
        particleData[i++] = p.pos[0];
        particleData[i++] = p.pos[1];
        particleData[i]   = p.pos[2];
    }

    // Create Vertex Buffer Object (VBO) to store vertices into GPU memory
    uint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(particleData), particleData, GL_STATIC_DRAW);

    // Position
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // Render loop
    while(!glfwWindowShouldClose(myglfw.getWindow()))
    {
        // Check input
        myglfw.processInput();

        // Rendering commands
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Activate shader
        shader.use();

        // Draw triangle through VAO
        glBindVertexArray(VAO);
        glDrawArrays(GL_POINTS, 0, NP * 3);
        glBindVertexArray(0);

        // GLFW: swap buffers and poll IO events (e.g. keys pressed, released, mouse moved, etc.)
        glfwSwapBuffers(myglfw.getWindow());
        glfwPollEvents();
    }

    // GLFW: terminate, clearing all previously allocated GLFW resources
    myglfw.terminate();
    return 0;
}

I manage to write around 400000-500000 particles and above that I get a segmentation fault. GDB says that the segmentation signal comes right at the first line of the main, which I don't understand. I also tried to set the number of particles by setting a long int nr = 1000000 directly in the main function, but I get the same error, and in this way GDB gives me an error at float particleData[nr];.

I'm writing and running my code on a Linux system using VS Code, my GPU is a GTX 1070 FE.

genpfault
  • 51,148
  • 11
  • 85
  • 139
hubstruct
  • 9
  • 2
  • Possibly a stack overflow due to `float particleData[NP * 3];`. Try using `std::vector particleData(NP * 3)` instead. – G.M. Mar 13 '21 at 13:28

1 Answers1

0

As per the comment, the use of...

float particleData[NP * 3];

is, potentially, causing a stack overflow. Rather than allocate such a large array on the stack you should consider using std::vector instead. The following is your code with (hopefully) the minimal necessary modifications (look for @G.M. )...

#define NP  1000000

int main(void)
{
    // Init GLFW
    MyGLFW myglfw(4, 5, W, H, "Particles");
    // Create shader program
    Shader shader("shaders/shader.vs", "shaders/shader.fs");

    // Define particle's vertex attrib
    std::vector<float> particleData(NP * 3); /* @G.M. */
    for(uint i = 0; i < NP * 3; i++)
    {
        // Creates a new particle with random position in the given range
        Particle p(-1.0f, 1.0f);
        particleData[i++] = p.pos[0];
        particleData[i++] = p.pos[1];
        particleData[i]   = p.pos[2];
    }

    // Create Vertex Buffer Object (VBO) to store vertices into GPU memory
    uint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(particleData[0]) * particleData.size(), particleData.data(), GL_STATIC_DRAW); /* @G.M. */

    // Position
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // Render loop
    while(!glfwWindowShouldClose(myglfw.getWindow()))
    {
        // Check input
        myglfw.processInput();

        // Rendering commands
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Activate shader
        shader.use();

        // Draw triangle through VAO
        glBindVertexArray(VAO);
        glDrawArrays(GL_POINTS, 0, NP * 3);
        glBindVertexArray(0);

        // GLFW: swap buffers and poll IO events (e.g. keys pressed, released, mouse moved, etc.)
        glfwSwapBuffers(myglfw.getWindow());
        glfwPollEvents();
    }

    // GLFW: terminate, clearing all previously allocated GLFW resources
    myglfw.terminate();
    return 0;
G.M.
  • 12,232
  • 2
  • 15
  • 18