尝试使用 OpenGL 创建粒子系统时出现分段错误
Segmentation fault error while attempting to create a particle system with OpenGL
我正在尝试创建一个简单的粒子系统,但我遇到了分段错误。我的问题似乎与我传递的顶点属性的数量有关。一个顶点有 3 个浮点数,对应于 x、y 和 z 坐标,所以如果我想创建 100 万个粒子,我将有一个包含 300 万个浮点数的数组,其中包含每个粒子的位置坐标。问题是,如果我超过一定数量的粒子,比如大约 400000,我会遇到分段错误。
部分代码如下:
#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;
}
我设法写了大约 400000-500000 个粒子,超过这个数目我遇到了分段错误。 GDB 说分割信号正好在主线的第一行,我不明白。我也试图通过直接在主函数中设置一个 long int nr = 1000000
来设置粒子数,但是我得到了同样的错误,这样 GDB 在 float particleData[nr];
.[=13= 处给我一个错误]
我正在使用 VS Code 在 Linux 系统上编写和 运行 我的代码,我的 GPU 是 GTX 1070 FE。
根据评论,使用...
float particleData[NP * 3];
可能会导致堆栈溢出。您应该考虑使用 std::vector
而不是在堆栈上分配这么大的数组。以下是您的代码(希望)进行了最少的必要修改(查找 @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;
我正在尝试创建一个简单的粒子系统,但我遇到了分段错误。我的问题似乎与我传递的顶点属性的数量有关。一个顶点有 3 个浮点数,对应于 x、y 和 z 坐标,所以如果我想创建 100 万个粒子,我将有一个包含 300 万个浮点数的数组,其中包含每个粒子的位置坐标。问题是,如果我超过一定数量的粒子,比如大约 400000,我会遇到分段错误。
部分代码如下:
#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;
}
我设法写了大约 400000-500000 个粒子,超过这个数目我遇到了分段错误。 GDB 说分割信号正好在主线的第一行,我不明白。我也试图通过直接在主函数中设置一个 long int nr = 1000000
来设置粒子数,但是我得到了同样的错误,这样 GDB 在 float particleData[nr];
.[=13= 处给我一个错误]
我正在使用 VS Code 在 Linux 系统上编写和 运行 我的代码,我的 GPU 是 GTX 1070 FE。
根据评论,使用...
float particleData[NP * 3];
可能会导致堆栈溢出。您应该考虑使用 std::vector
而不是在堆栈上分配这么大的数组。以下是您的代码(希望)进行了最少的必要修改(查找 @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;