2012-03-27 14 views
14

Ich verwende den folgenden Scala-Code. Es kompiliert eine einzelne Anzeigeliste von 10.000 Würfeln. Dann zeigt es sie in der Display-Schleife mit einem Animator an, der so schnell wie möglich läuft. Aber die FPS ist nur um 20. Ich hatte gedacht, dass die Verwendung von Display-Listen in der Lage wäre, damit sehr schnell fertig zu werden. Ich habe eine Situation, in der ich in der Lage sein muss, 10k-100k Objekte anzuzeigen. Gibt es einen besseren Weg? In der Display-Schleife ist so ziemlich alles, was es macht, gluLookAt und glCallList aufzurufen (es ist die letzte Methode).OpenGL-Leistung für 10.000 statische Würfel

Ich verwende JOGL 2.0 RC5 von jogamp.org, die sagt, es unterstützt „OpenGL 1,3-3,0, 3,1-3,3, ≥ 4,0, ES 1.x und 2.x ES + fast alle Erweiterungen des Herstellers“

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

Welche Hardware verwenden Sie? Ist doppelte "Pufferung" aktiviert? –

+0

Ich habe 'caps.setDoubleBuffered (true)' hinzugefügt und die Leistung nicht beeinträchtigt. Was die Hardware angeht, habe ich vor einem oder zwei Jahren eine Mid-Range-Nvidia-Grafikkarte. CPUs sind 2 Dual-Core-Opterons von Jahren. – mentics

+0

Zweitens, geben Sie bitte die OpenGL-Version an, die Sie verwenden. Bedeutet 'GL2' OpenGL 2? _Oh_, das ist [JOGL] (http://jogamp.org/jogl/www/) und [GL2] (http://download.java.net/media/jogl/jogl-2.x-docs/ javax/media/opengl/GL2.html) bedeutet dies OpenGL * 3 *. Die Suche nach _scala GL2_ hat nicht zu sehr vielen Treffern geführt ... –

Antwort

10

Sie können über die Verwendung eines Vertexpuffers nachdenken, der eine Möglichkeit zum Speichern von Zeicheninformationen für ein schnelleres Rendering darstellt.

Siehe hier für eine Übersicht:

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

+0

Warum spricht es davon, dass auf dieser Seite Inhalte veraltet sind? Sind VBO veraltet oder was ist auf dieser Seite? Es ist verwirrend. – mentics

+1

@ taotree: Es ruft über den 'glVertexPointer',' glTexCoordPointer' und andere Sachen. Das wurde entfernt. Pufferobjekte sind immer noch da.Ich bin nicht dazu gekommen, diese Seite aufzuräumen. –

+1

Ich versuchte dieses Beispiel, das VBO verwendet: http://wadeawalker.wordpress.com/2010/10/17/tutorial-faster-rendering-with-vertex-buffer-objects/ und es war in der Lage, 1 Million einfache Formen zu tun ungefähr 28 fps. – mentics

4

Wenn Sie die Vertex-Informationen in einem Eckpunktpufferspeicher Objekt speichern, laden Sie es dann zu OpenGL, werden Sie wahrscheinlich eine große Leistungssteigerung sehen, vor allem, wenn Sie Zeichnen statische Objekte. Dies liegt daran, dass die Vertex-Daten auf der Grafikkarte verbleiben und nicht jedes Mal von der CPU abgerufen werden.

+0

Ich dachte, Display-Listen speichern die Daten auf der Grafikkarte. – mentics

1

Sie erstellen eine Anzeigeliste, in der Sie für jeden Cube drawItem aufrufen. Innerhalb von drawItem für jeden Würfel drücken und pop die aktuelle Transformationsmatrix und dazwischen drehen und skalieren den Würfel, um es richtig zu platzieren. Im Prinzip könnte dies performant sein, da die Transformationen auf den Würfelkoordinaten vorberechnet und somit vom Fahrer optimiert werden könnten. Als ich das selbe versuchte (zeige viele Würfel wie in minecraft), aber ohne Rotation, dh ich habe nur glPush/glPopMatrix() und glTranslate3f() verwendet, erkannte ich, dass diese Optimierungen, dh das Entfernen der unnötigen Matrix, Pops und Anwendungen, wurden NICHT von meinem Fahrer gemacht. Also für ungefähr 10-20K Würfel habe ich nur ungefähr 40fps und für 200K Würfel nur ungefähr 6-7 fps. Dann habe ich versucht, die Übersetzungen manuell zu machen, dh ich habe die entsprechenden Versatzvektoren direkt zu den Scheitelpunkten meiner Würfel hinzugefügt, dh in der Anzeigeliste gab es keine Matrix Push/Pop und kein GlTranslatef mehr, ich habe eine enorme Geschwindigkeit erreicht, also lief mein Code ungefähr 70 mal so schnell.

Verwandte Themen