Reputation: 1155
I've created a "ping pong" shader class which renders a shader between two textures. For some reason the program has a massive memory leak which I can't locate. I don't use a single new statement within the display function. The code looks like this:
Display func:
void display()
{
r->Render();
glutSwapBuffers();
}
Render:
void Effect2::Render()
{
shader.Start(time);
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-1.0f, 1.0f);
}
glEnd();
shader.End();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
shader.BindCurrentTexture();
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-1.0f, 1.0f);
}
glEnd();
glDisable(GL_TEXTURE_2D);
Renderer::Render();
}
shader start, end, bindtexture:
void PingPongShader::Start(float time)
{
if(!began)
{
//buffer
glGenFramebuffers(1, &frameBuffer);
GLenum drawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, drawBuffers);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[current], 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textures[abs(current-1)]);
glUseProgram(shader);
if(paramCallback != NULL)
paramCallback(shader);
//internal shader vars
glUniform2f(screenSizeLoc, (float)width, (float)height);
if(drawingRadius > 0)
{
glUniform1f(dr_radius, drawingRadius);
glUniform4f(dr_color, drawingColor[0], drawingColor[1], drawingColor[2], drawingColor[3]);
glUniform2f(dr_pos, drawingPos[0], drawingPos[1]);
}
else
{
glUniform1f(dr_radius, -1.0);
}
glUniform1f(timeLoc, time);
began = true;
}
else
{
printf("Could not call Start(). Did you forget to call End() ?");
}
}
void PingPongShader::End()
{
if(began)
{
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_TEXTURE_2D);
current = abs(current-1);
began = false;
}
else
{
printf("Could not call End(). Did you forget to call Start() ?");
}
}
void PingPongShader::BindCurrentTexture()
{
glBindTexture(GL_TEXTURE_2D, textures[skip ? abs(current-1) : current]);
}
Except for the memory leak, the output is exactly what I expect.
Any ideas?
Upvotes: 2
Views: 285
Reputation: 171097
You're calling glGenFramebuffers
in each Start()
, thus allocating a new buffer object in each frame.
Side note: 1 - current
is more efficient (and I'd say more idiomatic) than abs(current - 1)
for alternating between 0 and 1.
Upvotes: 4