2012-03-27 20 views
14

Aşağıdaki Scala kodunu çalıştırıyorum. 10.000 küplük tek bir ekran listesini derler. Ardından bunları görüntü döngüsünde olabildiğince hızlı çalışan bir animatörle görüntüler. Ama FPS sadece 20 civarında. Ekran listelerini kullanmanın çok çabuk halledebileceğini düşünmüştüm. 10k-100k'lık nesneleri gösterebilmem gereken bir durum var. Bunu yapmanın daha iyi bir yolu var mı? Ekran döngüsünde, hemen hemen hepsi gluLookAt ve glCallList (son yöntem) diyor. "- 3,0, 3,1-3,3, ≥ 4.0, ES 1.x ve ES 2.x + neredeyse tüm satıcı uzantıları OpenGL 1.3"10,000 statik küp için OpenGL performansı

Ben desteklediğini söyledi jogamp.org gelen JOGL 2.0 RC5 kullanıyorum

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

Hangi donanımı kullanıyorsunuz? Çift "tamponlama" etkin mi? –

+0

'caps.setDoubleBuffered (true)' ekledim ve performansı etkilemedi. Donanım gelince, bir veya iki yıl önce orta menzilli nvidia ekran kartı var. CPU'lar yıllar önce 2 adet çift çekirdekli opterondur. – mentics

+0

İkincisi, lütfen kullandığınız OpenGL sürümünü belirtin. GL2, OpenGL 2'yi gösteriyor mu? _Oh_, bu [JOGL] (http://jogamp.org/jogl/www/) ve [GL2] (http://download.java.net/media/jogl/jogl-2.x-docs/ javax/media/opengl/GL2.html) bu, OpenGL * 3 * anlamına gelir. _scala GL2_ için arama yapmak çok fazla sonuç vermedi ... –

cevap

10

Vertex Buffer kullanımı hakkında düşünmek isteyebilirsiniz; bu, daha hızlı oluşturma için çizim bilgilerini depolamanın bir yoludur.

bir bakış için buraya bakınız: Bir köşe tampon nesnede köşe bilgi depolamak ise

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

+0

Bu sayfada neden kullanım dışı şeyler hakkında konuşuluyor? VBO'lar kullanımdan kaldırıldı mı, yoksa bu sayfada ne var? Kafa karıştırıcı. – mentics

+1

@taotree: "glVertexPointer", "glTexCoordPointer" ve diğer şeyler hakkında konuşuyor. Bu kaldırıldı. Arabellek nesneleri hala var.Bu sayfayı temizlemek için etrafta gezemedim. –

+1

VBO'ları kullanan bu örneği denedim: http://wadeawalker.wordpress.com/2010/10/17/tutorial-faster-rendering-with-vertex-buffer-objects/ ve 1 milyon basit şekil gerçekleştirebildi yaklaşık 28 fps. – mentics

4

ardından OpenGL yükleyin, muhtemelen, özellikle performans büyük bir artış göreceksiniz sen statik nesneler çiziyorlar. Bunun nedeni, vertex verilerinin grafik kartında kalmasını sağlamaktır, her seferinde CPU'dan almak yerine.

+0

Ekran listelerinin verileri grafik kartında sakladığını düşündüm. – mentics

1

Her küp için drawItem çağırdığınız bir görüntüleme listesi oluşturursunuz. İçindeki her bir küp için numaralı çizimde, mevcut dönüştürme matrisini itip açıp, döndürerek küpü doğru şekilde yerleştirmek için ölçeklendirin. Küp koordinatlarındaki dönüşümleri önceden ayarlanabildiğinden ve dolayısıyla sürücü tarafından optimize edilebildiğinden, bu prensipte performans olabilir. Aynı şeyi yapmaya çalıştığımda (minecraft'taki gibi çok sayıda küp görüntüledim), ancak sadece glPush/glPopMatrix() ve glTranslate3f() kullandım, aslında bu optimizasyonların, yani gereksiz en matrislerden kurtulmasının farkına vardım. pops ve uygulamalar, şoförüm tarafından yapılmadı. Yani yaklaşık 10-20K küp için sadece yaklaşık 40fps ve 200K küpleri sadece yaklaşık 6-7 fps var. O zaman çevirileri elle yapmaya çalıştım, yani ilgili ofset vektörlerini küplerimin köşelerine doğrudan ekledim, yani ekran listesinde matris push/pop yok ve glTranslatef yok, büyük bir hız aldım, Bu yüzden kodum yaklaşık 70 kat hızlı koştu.