我认为这个 open gl 代码导致内存泄漏,我犯了什么错误?
I think this open gl code is causing a memory leak, What mistake am I making?
在这段代码中,我尝试画两条线,最初它基本上是一个 VBO 和一个 VAO 的简短设置,然后我画线,它似乎有效,但是当我复制并粘贴代码几次时为了获得更多行,我似乎正在造成内存泄漏,因此一定是做错了。
我觉得有更好的方法可以做到这一点,比如在其他地方的初始化函数中创建一个 VAO,它只运行一次并重用它删除我的缓冲区对象,所以我只是绑定 VAO 并在中绘制或其他东西我的绘图功能。所以我尝试首先在这个函数中完成这一切,如果 x = 0 使 VBO 和 VBO 等然后 x=1 所以它只运行一次用于创建缓冲区对象等。但后来我得到错误并且没有任何东西说有没有绑定 VAO ...我知道销毁不同数据类型的规则有点复杂,也许我不清楚。
它画得很好,但正如我所说,内存每秒大约增加 1 兆字节。这似乎发生在大约一分钟后 运行.
void drawMenu(){
vec3 start(-3,-.8,0);
vec3 end(3,-.8,0);
startPoint = start;
endPoint = end;
GLfloat colorToSet[4]= {1.0f,1.0f,1.0f,1.0f};
verticesl = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glUseProgram(shaderProgram);
GLuint uniformLocation = glGetUniformLocation(shaderProgram,"uniformColor");
if (uniformLocation<0){
cout<< "drawline function can't find a uniform location in your fragment shader "<< endl;
}
else glUniform4f(uniformLocation, colorToSet[0],colorToSet[1],colorToSet[2],colorToSet[3]);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);
glGenVertexArrays(1, &VAO);// can creat the VAO now to store the VBO in
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, 2);
glDeleteBuffers(1,&VBO);
GLfloat colorToSet1[4]= {1.0f,1.0f,1.0f,1.0f};
start = vec3(-3,-.9,0);
end = vec3(3,-.9,0);
glUniform4f(uniformLocation, colorToSet1[0],colorToSet1[1],colorToSet1[2],colorToSet1[3]);
verticesl = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);//fills the previously bound vbo
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the buffer
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, 2);
glDeleteBuffers(1,&VBO);
}
您正在渲染函数中执行 glGenBuffers
和 glBufferData
,这将分配 GPU 内存并在每一帧加载它。相反,请在程序的设置部分使用 glGenBuffers
。很可能您只是更改为大多数渲染(网格、地形等)提供给着色器的转换,因此您只需要在设置中调用一次 glBufferData
。如果你真的每帧都在改变顶点数据(动态文本?动画构造的网格?),那么你将需要使用 GL_DYNAMIC_DRAW
,当定义你的缓冲区时,你可以 glBufferData
在渲染函数中谨慎使用。
在这段代码中,我尝试画两条线,最初它基本上是一个 VBO 和一个 VAO 的简短设置,然后我画线,它似乎有效,但是当我复制并粘贴代码几次时为了获得更多行,我似乎正在造成内存泄漏,因此一定是做错了。
我觉得有更好的方法可以做到这一点,比如在其他地方的初始化函数中创建一个 VAO,它只运行一次并重用它删除我的缓冲区对象,所以我只是绑定 VAO 并在中绘制或其他东西我的绘图功能。所以我尝试首先在这个函数中完成这一切,如果 x = 0 使 VBO 和 VBO 等然后 x=1 所以它只运行一次用于创建缓冲区对象等。但后来我得到错误并且没有任何东西说有没有绑定 VAO ...我知道销毁不同数据类型的规则有点复杂,也许我不清楚。
它画得很好,但正如我所说,内存每秒大约增加 1 兆字节。这似乎发生在大约一分钟后 运行.
void drawMenu(){
vec3 start(-3,-.8,0);
vec3 end(3,-.8,0);
startPoint = start;
endPoint = end;
GLfloat colorToSet[4]= {1.0f,1.0f,1.0f,1.0f};
verticesl = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glUseProgram(shaderProgram);
GLuint uniformLocation = glGetUniformLocation(shaderProgram,"uniformColor");
if (uniformLocation<0){
cout<< "drawline function can't find a uniform location in your fragment shader "<< endl;
}
else glUniform4f(uniformLocation, colorToSet[0],colorToSet[1],colorToSet[2],colorToSet[3]);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);
glGenVertexArrays(1, &VAO);// can creat the VAO now to store the VBO in
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, 2);
glDeleteBuffers(1,&VBO);
GLfloat colorToSet1[4]= {1.0f,1.0f,1.0f,1.0f};
start = vec3(-3,-.9,0);
end = vec3(3,-.9,0);
glUniform4f(uniformLocation, colorToSet1[0],colorToSet1[1],colorToSet1[2],colorToSet1[3]);
verticesl = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);//fills the previously bound vbo
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the buffer
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, 2);
glDeleteBuffers(1,&VBO);
}
您正在渲染函数中执行 glGenBuffers
和 glBufferData
,这将分配 GPU 内存并在每一帧加载它。相反,请在程序的设置部分使用 glGenBuffers
。很可能您只是更改为大多数渲染(网格、地形等)提供给着色器的转换,因此您只需要在设置中调用一次 glBufferData
。如果你真的每帧都在改变顶点数据(动态文本?动画构造的网格?),那么你将需要使用 GL_DYNAMIC_DRAW
,当定义你的缓冲区时,你可以 glBufferData
在渲染函数中谨慎使用。