I'm currently programming a 2D-sidescroll game with c++ and OpenGL. To get the window I'm using SFML, but that should'nt be relevant as I draw all my quads directly with OpenGL. Now the problem is when I use a Framebufferobject to draw some light-textures on it and then use it as a mask over the scene, the framerate drops down. Normally the game reaches its limit at 60 fps, but with the fbo, its about 40 fps, sometimes even 30. The effect looks nice thought :D I have never used a framebuffer befor, and this: Framebuffer FBO render to texture is very slow, using OpenGL ES 2.0 on Android, why? doesn't seem to help. So my question: What am I doing wrong? Or is there even a much simpler way to reach the same effect? I'm running it on Ubuntu 12.04. My code:
void init() {
GLuint fbo, mask; //framebufferobject and texture
glewInit();
glGenTextures(1, &mask);
glBindTexture(GL_TEXTURE_2D, mask);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1024, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE,
0);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mask,
0);
glClearColor(darkness, darkness, darkness, 1);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
GL_FRAMEBUFFER_COMPLETE)CMain::game.usefbo = false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void render() {
//render usual stuff, then
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, 1024, 600);
glBlendFunc(GL_SRC_COLOR, GL_ONE);
//render lights
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
//render fbo over the screen:
glBindTexture(GL_TEXTURE_2D, mask);
glTranslatef(0, 0, 9);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(0, 1); glVertex2i(0, 600);
glTexCoord2f(1, 1); glVertex2i(1024, 600);
glTexCoord2f(1, 0); glVertex2i(1024, 0);
glEnd();
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//display
}
Edit: At //render lights three light-textures (round, radial, black-to-white) are rendered to the fbo via glBegin(GL_QUADS) etc. Later of course I want to use much more lights. I need to refresh the fbo every frame cause the lights are moving and overlapping each other.
render lights:
for(std::vector<LightSource*>::iterator it = lights.begin(); it != lights.end(); it++) {
(*it)->draw();
}
where lights is a vector of LightsSources. Lightssource::draw():
void LightsSource::draw() {
if (visible()) {
if (activated) {
glTranslatef(this->x, this->y, 0);
glBindTexture(GL_TEXTURE_2D, this->texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(0, 1); glVertex2i(0, height);
glTexCoord2f(1, 1); glVertex2i(width, height);
glTexCoord2f(1, 0); glVertex2i(width, 0);
glEnd();
glLoadIdentity();
}
}
}
visible() and activated are usually true.