2

現在、C++ と OpenGL を使用して 2D 横スクロール ゲームをプログラミングしています。ウィンドウを取得するために SFML を使用していますが、すべてのクワッドを OpenGL で直接描画しているため、これは関係ありません。問題は、Framebuffer オブジェクトを使用してライト テクスチャを描画し、それをシーンのマスクとして使用すると、フレームレートが低下することです。通常、ゲームは 60 fps で限界に達しますが、fbo を使用すると、約 40 fps、場合によっては 30 fps になります。この効果は素晴らしいと思います:D フレームバッファを使用したことがないので、 テクスチャへのフレームバッファ FBO レンダリングは非常に遅いです。 Android で OpenGL ES 2.0 を使用しているのはなぜですか? 役に立たないようです。だから私の質問:私は何を間違っていますか?それとも、同じ効果を達成するためのもっと簡単な方法がありますか? Ubuntu 12.04で実行しています。私のコード:

    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
    }

編集: //render lights では、3 つのライト テクスチャ (円形、放射状、黒から白) が glBegin(GL_QUADS) などを介して fbo にレンダリングされます。もちろん、後でもっと多くのライトを使用したいと思います。ライトが移動して互いに重なり合っているため、フレームごとに fbo を更新する必要があります。

レンダー ライト:

for(std::vector<LightSource*>::iterator it = lights.begin(); it != lights.end(); it++) {
    (*it)->draw();
}

ここで、lights は LightsSources のベクトルです。光源::描画():

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() と activate は通常 true です。

4

1 に答える 1

0

どの種類の GPU を使用していますか?
私が今見ている唯一のことは、多くの GPU で最速のフォーマットと考えられている「GL_BGRA」の代わりにテクスチャフォーマット「GL_RGBA」を使用していることです。したがって、GPU が非常に古い場合は、それが問題になる可能性があります。

于 2013-02-21T16:07:41.600 に答える