2012-03-27 3 views
14

다음 스칼라 코드가 실행 중입니다. 10,000 큐브의 단일 디스플레이 목록을 컴파일합니다. 그런 다음 가능한 한 빨리 실행되는 애니메이터를 사용하여 디스플레이 루프에 표시합니다. 그러나 FPS는 약 20 개 밖에 없습니다. 디스플레이 목록을 사용하면 매우 신속하게 처리 할 수 ​​있다고 생각했습니다. 나는 10k-100k의 물체를 표시 할 수 있어야하는 상황이 있습니다. 그렇게 할 수있는 더 좋은 방법이 있습니까? 디스플레이 루프에서 거의 모든 작업은 gluLookAt 및 glCallList (마지막 메서드)를 호출하는 것입니다. "- 3.0 3.1 - 3.3 ≥ 4.0, ES 1.x 및 ES 2.X + 거의 모든 벤더 확장의 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 년 전의 미드 레인지 엔비디아 그래픽 카드가 있습니다. 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/ 그리고 1 백만 개의 간단한 도형을 만들 수있었습니다. 약 28 fps. – mentics

4

는, 다음의 OpenGL에 업로드, 당신은 아마 경우 특히 성능에 큰 증가를 볼 당신 정적 객체를 그리는 중입니다. 이것은 버텍스 데이터가 매번 CPU에서 가져 오기보다는 그래픽 카드에 남아 있기 때문입니다.

+0

디스플레이 목록이 그래픽 카드에 데이터를 저장한다고 생각했습니다. – mentics

1

각 큐브에 대해 drawItem을 호출하는 표시 목록을 만듭니다. 각 큐브에 대해 drawItem 내부에 현재 변형 행렬을 푸시 (push) 및 팝 (pop)하고 큐브를 올바르게 배치하기 위해 회전 및 크기 조절합니다. 원칙적으로 큐브 좌표의 변환이 사전 계산되어 드라이버에 의해 최적화 될 수 있기 때문에 성능이 향상 될 수 있습니다. 나는 회전 (glPush/glPopMatrix()와 glTranslate3f()를 사용했을 뿐이다.) 실제로 이러한 최적화, 즉 불필요한 행렬 푸시/팝 및 응용 프로그램은 내 드라이버가 수행하지 않았습니다. 따라서 약 10-20K 큐브의 경우 약 40fps 밖에 얻을 수 없으며 200K 큐브의 경우 약 6-7fps 밖에 없습니다. 그런 다음 수동으로 변환을 시도했습니다. 즉, 각 큐브의 꼭지점에 직접 오프셋 벡터를 추가했습니다. 즉, 표시 목록 내에 행렬 푸시/팝이없고 glTranslatef가 없으므로 속도가 빨라졌습니다. 그래서 내 코드는 약 70 배 빠르게 실행되었습니다.

관련 문제