2

私はボクセルベースのゲームを作成しており、そのニーズに応じて、ブロックレンダリングエンジンを作成しています。

ポイントは、たくさんのキューブを生成する必要があるということです。これらのブロックの16x16x16チャンクを超えるレンダリングを行うたびに、FPSはほとんどドロップダウンされません。これは、これらのすべての立方体の6つの面すべてをレンダリングするためです。それは24576クワッドです、そして私はそれを望んでいません。

だから、私の質問は、表示されていない頂点(またはクワッド)のレンダリングを停止して、ゲームのパフォーマンスを向上させる方法はありますか?

ブロックをレンダリングするためのクラスは次のとおりです。

public void renderBlock(int posx, int posy, int posz) {
  try{
    //t.bind();
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);// or even GL_FRONT_AND_BACK */);

    glPushMatrix();

    GL11.glTranslatef((2*posx+0.5f),(2*posy+0.5f),(2*posz+0.5f));             // Move Right 1.5 Units And Into The Screen 6.0
    GL11.glRotatef(rquad,1.0f,1.0f,1.0f);

    glBegin(GL_QUADS);               // Draw A Quad

    GL11.glColor3f(0.5f, 0.4f, 0.4f);             // Set The Color To Green
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f( 1f, 1f,-1f);         // Top Right Of The Quad (Top)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f(-1f, 1f,-1f);         // Top Left Of The Quad (Top)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f(-1f, 1f, 1f);         // Bottom Left Of The Quad (Top)
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f( 1f, 1f, 1f);         // Bottom Right Of The Quad (Top)

    //GL11.glColor3f(1.2f,0.5f,0.9f);             // Set The Color To Orange
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f( 1f,-1f, 1f);         // Top Right Of The Quad (Bottom)
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f(-1f,-1f, 1f);         // Top Left Of The Quad (Bottom)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f(-1f,-1f,-1f);         // Bottom Left Of The Quad (Bottom)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f( 1f,-1f,-1f);         // Bottom Right Of The Quad (Bottom)

    //GL11.glColor3f(1.0f,0.0f,0.0f);             // Set The Color To Red
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f( 1f, 1f, 1f);         // Top Right Of The Quad (Front)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f(-1f, 1f, 1f);         // Top Left Of The Quad (Front)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f(-1f,-1f, 1f);         // Bottom Left Of The Quad (Front)
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f( 1f,-1f, 1f);         // Bottom Right Of The Quad (Front)

    //GL11.glColor3f(1f,0.5f,0.0f);             // Set The Color To Yellow
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f( 1f,-1f,-1f);         // Bottom Left Of The Quad (Back)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f(-1f,-1f,-1f);         // Bottom Right Of The Quad (Back)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f(-1f, 1f,-1f);         // Top Right Of The Quad (Back)
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f( 1f, 1f,-1f);         // Top Left Of The Quad (Back)

    //GL11.glColor3f(0.0f,0.0f,0.3f);             // Set The Color To Blue
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f(-1f, 1f, 1f);         // Top Right Of The Quad (Left)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f(-1f, 1f,-1f);         // Top Left Of The Quad (Left)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f(-1f,-1f,-1f);         // Bottom Left Of The Quad (Left)
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f(-1f,-1f, 1f);         // Bottom Right Of The Quad (Left)

    //GL11.glColor3f(0.5f,0.0f,0.5f);             // Set The Color To Violet
    GL11.glTexCoord2f(0,0);
    GL11.glVertex3f( 1f, 1f,-1f);         // Top Right Of The Quad (Right)
    GL11.glTexCoord2f(1,0);
    GL11.glVertex3f( 1f, 1f, 1f);         // Top Left Of The Quad (Right)
    GL11.glTexCoord2f(1,1);
    GL11.glVertex3f( 1f,-1f, 1f);         // Bottom Left Of The Quad (Right)
    GL11.glTexCoord2f(0,1);
    GL11.glVertex3f( 1f,-1f,-1f);         // Bottom Right Of The Quad (Right)

    //rquad+=0.0001f;
    glEnd();
    glPopMatrix();
  }catch(NullPointerException t){t.printStackTrace(); System.out.println("rendering block failed");}
}

それらをレンダリングするコードは次のとおりです。

private void render() {
  GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
  for(int y=0; y<32; y++){
    for(int x=0; x<16; x++){
      for(int z=0; z<16; z++) {
        b.renderBlock(x, y, z);

      }
    }
  }
}
4

3 に答える 3

4

コードには、より大きなパフォーマンスの問題があります。glVertexXXX() callsこのような多数の頂点を描画するために、即時モードのOpenGLレンダリング()を使用するべきではありません。

この方法でレンダリングを実行すると、コードはすべての頂点に対してグラフィックスドライバーを呼び出す必要がありますが、これは低速です。

代わりに、頂点バッファオブジェクトを使用する必要があります。これにより、すべてのジオメトリをグラフィックカードに直接アップロードしてから、1回のJavaメソッド呼び出しですべてのキューブを描画できます(おそらくglDrawArrays)。

于 2012-04-06T16:22:20.780 に答える
2

ulmangtが言ったように、VBOを使用することをお勧めしますが、その前に、表示されている面のみを計算する必要があります。

これは、顔が空のボクセル(「空気」)に隣接しているかどうかを(最初に1回だけ)チェックすることで簡単に実行できます。そうである場合は、そのクワッド(面)をレンダリングに追加します。

その後、変更されたボクセルのネイバーに対してのみこのチェックを実行します。例:ユーザーが立方体を削除したら、そのボクセルの6つの隣接オブジェクトを確認し、それらの四角形をレンダリングに追加します。ボクセルが追加されたら逆の操作を行い、隣接するクワッドを削除します。

したがって、750個のクワッドの代わりにボクセルで作られた5x5x5の立方体を使用すると、最終的に150個になります。

ビューにチャンク(ボクセルのグループ)をレンダリングし(プレーヤーの後ろにあるものを無視する)、距離制限を使用するだけで、他の利点を得ることができます。

octreesを使用して、表示される可能性があることがわかっているチャンクのみをレンダリングすることで、さらに夢中になります。

于 2012-04-09T20:21:00.270 に答える
1

ブロックのレンダリングにイミディエイトモードを使用しないことをお勧めします。ディスプレイリストを使用するのは、セットアップが最も簡単で、非常に高速だからです。第二に、イミディエイトモードのみを使用している場合でも、描画時にglBegin / glEnd呼び出しを1つだけ使用します。将来、テクスチャにテクスチャアトラスを使用し、非表示の顔のレンダリングを停止する方法を主な質問にします。非常に単純です。私が行う方法は、基本的に、ブール値を返す各面に対して6つのメソッドを作成することです。その面の方向のブロックタイプがエアブロックの場合は、単純に戻ります。それからそれはそれがtrueを返すことを意味します、それ故にそれをレンダリングします。そして、drawメソッドに、パラメータ「boolean backface、boolean topface ...など」と、描画する側をチェックするifステートメントを追加します。

私が助けてくれたことを願っています、頑張ってください!

于 2014-08-26T00:37:56.350 に答える