2
votes

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.

1
Honestly, talking about "fast" and "slow" doesn't make any sense when you're using the FFP. You should probably fix that first.Cubic
sorry, don't know what you mean. please explain yourself.user1943758
Nothing here sticks out as a potential problem. I'm assuming //render lights is where you do some rendering to the FBO. What's going on in there?Aeluned
Yes, that's true. I editeduser1943758
post what's in render lights, please.Aeluned

1 Answers

0
votes

What kind of GPU are you using?
The only thing I see right now is that you're using the texture format "GL_RGBA" instead of "GL_BGRA", which is considered the fastest format on many GPUs. So if you GPU is very old, that might be the issue.