2012-03-27 23 views
14

Tôi đang chạy mã Scala sau đây. Nó biên soạn một danh sách hiển thị duy nhất của 10.000 hình khối. Sau đó, nó sẽ hiển thị chúng trong vòng lặp hiển thị với trình làm hoạt hình chạy nhanh nhất có thể. Nhưng FPS chỉ khoảng 20. Tôi đã nghĩ rằng việc sử dụng danh sách hiển thị sẽ có thể xử lý việc này rất nhanh chóng. Tôi có một tình huống mà tôi cần để có thể hiển thị 10k-100k đối tượng. Có cách nào tốt hơn để làm như vậy không? Trong vòng lặp hiển thị, khá nhiều tất cả nó làm là gọi gluLookAt và glCallList (đó là phương pháp cuối cùng).Hiệu suất OpenGL cho 10.000 hình khối tĩnh

Tôi đang sử dụng JOGL 2.0-rc5 từ jogamp.org cho biết nó hỗ trợ "OpenGL 1.3 - 3.0, 3.1 - 3.3, ≥ 4.0, ES 1.x và ES 2.x + gần như tất cả tiện ích mở rộng nhà cung cấp"

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

bạn đang sử dụng phần cứng nào? Tính năng "đệm" đôi có được bật không? –

+0

Tôi đã thêm 'caps.setDoubleBuffered (true)' và nó không ảnh hưởng đến hiệu suất. Đối với phần cứng, tôi có một card đồ họa tầm trung nvidia từ một hoặc hai năm trước. CPU là 2 opteron lõi kép từ nhiều năm trước. – mentics

+0

Thứ hai, vui lòng chỉ định phiên bản OpenGL bạn sử dụng. 'GL2' có chỉ ra OpenGL 2 không? _Oh_, đây là [JOGL] (http://jogamp.org/jogl/www/) và [GL2] (http://download.java.net/media/jogl/jogl-2.x-docs/ javax/media/opengl/GL2.html) có nghĩa là OpenGL * 3 *. Tìm kiếm _scala GL2_ không dẫn đến nhiều lần truy cập ... –

Trả lời

10

Bạn có thể muốn suy nghĩ về việc sử dụng Vertex Buffer, đây là cách lưu trữ thông tin bản vẽ để hiển thị nhanh hơn.

Xem ở đây cho một cái nhìn tổng quan:

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

+0

Tại sao nó nói về trang đó có nội dung không được dùng nữa? VBO có bị phản đối hay trang nào không? Thật khó hiểu. – mentics

+1

@taotree: Gọi về 'glVertexPointer',' glTexCoordPointer' và các nội dung khác. Điều đó đã bị xóa. Các đối tượng đệm vẫn còn đó.Tôi đã không nhận được xung quanh để làm sạch trang đó. –

+1

Tôi đã thử ví dụ này sử dụng VBO's: http://wadeawalker.wordpress.com/2010/10/17/tutorial-faster-rendering-with-vertex-buffer-objects/ và nó có thể làm 1 triệu hình dạng đơn giản tại khoảng 28 khung hình/giây. – mentics

4

Nếu bạn lưu trữ các thông tin đỉnh trong một đối tượng đỉnh đệm, sau đó tải nó lên OpenGL, có thể bạn sẽ thấy một sự gia tăng lớn trong hoạt động, đặc biệt là nếu bạn đang vẽ các đối tượng tĩnh. Điều này là do dữ liệu đỉnh nằm trên card đồ họa, thay vì lấy nó từ CPU mỗi lần.

+0

Tôi nghĩ danh sách hiển thị lưu trữ dữ liệu trên cạc đồ họa. – mentics

1

Bạn tạo danh sách hiển thị mà bạn gọi là drawItem cho mỗi khối. Bên trong drawItem cho mỗi khối bạn đẩy và bật ma trận chuyển đổi hiện tại và xoay vòng giữa và quy mô khối lập phương để đặt chính xác. Về nguyên tắc có thể được thực hiện kể từ khi chuyển đổi trên tọa độ khối lập phương có thể được precomputed và do đó tối ưu hóa bởi người lái xe. Khi tôi cố gắng làm như vậy (hiển thị rất nhiều hình khối như trong minecraft) nhưng không xoay, tức là tôi chỉ sử dụng glPush/glPopMatrix() và glTranslate3f(), tôi nhận ra rằng những tối ưu hóa này, tức là loại bỏ các ma trận không cần thiết/pop và các ứng dụng, KHÔNG được thực hiện bởi tài xế của tôi. Vì vậy, cho khoảng 10-20K khối tôi chỉ có khoảng 40fps và cho 200K khối chỉ khoảng 6-7 fps. Sau đó, tôi đã cố gắng thực hiện các bản dịch bằng tay, tức là tôi đã thêm vectơ offset tương ứng vào các đỉnh của hình khối của tôi, tức là bên trong danh sách hiển thị không có ma trận push/pop và không có glTranslatef nữa, vì vậy mã của tôi chạy nhanh gấp 70 lần.