2012-03-27 14 views
14

次のScalaコードを実行しています。 10,000個のキューブからなる単一のディスプレイリストをコンパイルします。できるだけ速く動作するアニメーターを使用して、それらを表示ループに表示します。しかし、FPSはわずか20前後です。ディスプレイリストを使用すると、これを非常に迅速に処理できると思っていました。私は10k〜100kのオブジェクトを表示できる必要がある状況があります。そうするより良い方法はありますか?表示ループでは、ほとんどの場合、gluLookAtとglCallListを呼び出します(最後の方法です)。 " - 3.0、3.1から3.3、≥4.0、ES 1.xおよび2.xのES +ほぼすべてのベンダー拡張機能のOpenGL 1.3"10,000静的キューブのOpenGLパフォーマンス

私はそれをサポートしていると言うjogamp.orgからJOGL 2.0 RC5を使用しています

class LotsOfCubes extends GLEventListener { 
    def show() = { 
    val glp = GLProfile.getDefault(); 
    val caps = new GLCapabilities(glp); 
    val canvas = new GLCanvas(caps); 
    canvas.addGLEventListener(this); 

    val frame = new JFrame("AWT Window Test"); 
    frame.setSize(300, 300); 
    frame.add(canvas); 
    frame.setVisible(true); 
    } 

    override def init(drawable: GLAutoDrawable) { 
    val gl = drawable.getGL().getGL2() 
    gl.glEnable(GL.GL_DEPTH_TEST) 

    gl.glNewList(21, GL2.GL_COMPILE) 
    var i = -10.0f 
    var j = -10.0f 
    while (i < 10.0f) { 
     while (j < 10.0f) { 
     drawItem(gl, i, j, 0.0f, 0.08f) 
     j += 0.1f 
     } 
     i += 0.1f 
     j = -10f 
    } 
    gl.glEndList() 

    val an = new Animator(drawable); 
    drawable.setAnimator(an); 
    an.setUpdateFPSFrames(100, System.out) 
    an.start(); 
    } 

    override def dispose(drawable: GLAutoDrawable) { 
    } 

    override def reshape(drawable: GLAutoDrawable, x: Int, y: Int, width: Int, height: Int) { 
    val gl = drawable.getGL().getGL2(); 
    val glu = new GLU 
    gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); 
    gl.glLoadIdentity(); 
    glu.gluPerspective(10, 1, -1, 100); 
    gl.glViewport(0, 0, width, height); 
    gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); 
    } 

    def drawBox(gl: GL2, size: Float) { 
    import Global._ 
    gl.glBegin(GL2.GL_QUADS); 
    for (i <- 5 until -1 by -1) { 
     gl.glNormal3fv(boxNormals(i), 0); 
     val c = colors(i); 
     gl.glColor3f(c(0), c(1), c(2)) 
     var vt: Array[Float] = boxVertices(boxFaces(i)(0)) 
     gl.glVertex3f(vt(0) * size, vt(1) * size, vt(2) * size); 
     vt = boxVertices(boxFaces(i)(1)); 
     gl.glVertex3f(vt(0) * size, vt(1) * size, vt(2) * size); 
     vt = boxVertices(boxFaces(i)(2)); 
     gl.glVertex3f(vt(0) * size, vt(1) * size, vt(2) * size); 
     vt = boxVertices(boxFaces(i)(3)); 
     gl.glVertex3f(vt(0) * size, vt(1) * size, vt(2) * size); 
    } 
    gl.glEnd(); 
    } 

    def drawItem(gl: GL2, x: Float, y: Float, z: Float, size: Float) { 
    gl.glPushMatrix() 
    gl.glTranslatef(x, y, z); 
    gl.glRotatef(0.0f, 0.0f, 1.0f, 0.0f); // Rotate The cube around the Y axis 
    gl.glRotatef(0.0f, 1.0f, 1.0f, 1.0f); 
    drawBox(gl, size); 
    gl.glPopMatrix() 
    } 

    override def display(drawable: GLAutoDrawable) { 
    val gl = drawable.getGL().getGL2() 
    val glu = new GLU 
    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) 
    gl.glLoadIdentity() 
    glu.gluLookAt(0.0, 0.0, -100.0f, 
     0.0f, 0.0f, 0.0f, 
     0.0f, 1.0f, 0.0f) 
    gl.glCallList(21) 
    } 
} 
+0

どのハードウェアを使用していますか?ダブル "バッファリング"は有効になっていますか? –

+0

'caps.setDoubleBuffered(true)'を追加しましたが、パフォーマンスには影響しませんでした。ハードウェアに関しては、1年前から2年前のミッドレンジのNVIDIAグラフィックカードを持っています。 CPUは数年前から2つのデュアルコア・オプテロンです。 – mentics

+0

次に、使用するOpenGLのバージョンを指定してください。 'GL2'はOpenGL 2を指していますか? _Oh_これは[JOGL](http://jogamp.org/jogl/www/)、[GL2](http://download.java.net/media/jogl/jogl-2.x-docs/)です。 javax/media/opengl/GL2.html)は、OpenGL * 3 *を意味します。 _scala GL2_を検索しても多くのヒットは発生しませんでした... –

答えて

10

高速なレンダリングのために描画情報を保存するための方法である頂点バッファを使用することを考えてください。

は、概要については、こちらを参照してください:

http://www.opengl.org/wiki/Vertex_Buffer_Object

+0

廃止予定のページがあるページについて、なぜそれについて話していますか? VBOは非推奨ですか、それともそのページにありますか?ややこしい。 – mentics

+1

@taotree:これは、 'glVertexPointer'、' glTexCoordPointer'などのことを呼びます。それは削除されました。バッファオブジェクトはまだそこにあります。私はそのページを掃除しようとしていません。 –

+1

私はVBOを使用するこの例を試しました:http://wadeawalker.wordpress.com/2010/10/17/tutorial-faster-rendering-with-vertex-buffer-objects/そして、それは100万の単純な形をすることができました約28fps。 – mentics

4

あなたが頂点バッファオブジェクト内の頂点情報を保存する場合は、OpenGLのにアップロードし、あなたはおそらく、特にあなたの場合、パフォーマンスが大幅に増加が表示されます静的オブジェクトを描画しています。これは、頂点データが毎回CPUから取り出されるのではなく、グラフィックスカード上にとどまっているためです。

+0

私はディスプレイリストがグラフィックスカードにデータを保存すると思った。 – mentics

1

各キューブに対してdrawItemを呼び出す表示リストを作成します。各キューブのdrawItem の内部では、現在の変換行列をプッシュしてポップし、その間にキューブを回転してスケールし、正しく配置します。原理的には、キューブ座標上の 変換が事前に計算され、したがってドライバによって最適化されるので、実行可能である可能性がある。私はglPush/glPopMatrix()とglTranslate3f()のみを使用していましたが、実際にはこれらの最適化、つまり不必要な行列を取り除くことが実現しました。私のドライバでは、ポップやアプリケーションは実行されませんでした。したがって、約10〜20Kのキューブでは、約40fpsしか得られず、200Kのキューブでは約6〜7fpsしか得られませんでした。 次に、私は手動で翻訳をしようとしました。つまり、私のキューブの頂点にそれぞれのオフセットベクトルを直接追加しました。つまり、ディスプレイリストの中にマトリックスプッシュ/ポップはなく、glTranslatefもなくなりました。私のコードは約70倍速かった。

関連する問題