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