In this code I attempt to draw two lines, initially it's basically a short setup of a VBO and a VAO and then I draw the line, it seems to work, but when I copy and paste the code a few times to get more lines I seem to be creating a memory leak, and therefore must be doing it wrong.
I have a feeling there's a better way to do it, such as create a VAO in an initialization function elsewhere that only runs once and reuse it delete my buffer objects, So I just bind the VAO and draw or something in my draw function. So I tried to do it all in this function first with an if x = 0 make the VBO and VBO etc. then x=1 so it only runs once for the creationof buffer objects etc. But then I get errors and nothing draws saying there's no bound VAO ... I know that the rules for destroying different data types are kinda complicated and maybe I'm not clear on them.
It draws nicely, but as I say the memory keeps going up about 1 megabyte per second. This seems to occur after about a minute running.
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);
}
You are doing glGenBuffers
and glBufferData
inside a render function, which will allocate GPU memory and loads it every frame. Instead, use glGenBuffers
in the setup part of your program. Most likely you are only changing the transformation which is supplied to the shader for most rendering (meshes, terrain, etc), so you only need to call glBufferData
once in the setup. If you really are changing vertex data every frame (dynamic text? animated constructed meshes?), then you will need to use GL_DYNAMIC_DRAW
, when defining your buffers, then you can glBufferData
inside render function sparingly.