2011-04-19 55 views
0

我正在開發一個簡單的遊戲,我目前正在從畫布切換到OpenGL。所以我的OpenGL經驗非常有限。我試圖在現在創建一個簡單的粒子引擎,它工作正常,但與我目前的實現,我必須在每一個draw()調用[vertexBuffer.put(vertices); ],這真的很慢..有什麼辦法可以解決這個問題嗎?opengl粒子引擎最佳實踐?

代碼如下所示:

public class ParticlesTest { 

    private float[] vertices; 
    private short[] indices; 


    private FloatBuffer vertexBuffer; 


    private ShortBuffer indexBuffer; 
    private ByteBuffer vbb; 

    private int MAX_PARTICLES = 100; 

    private ArrayList<Particle> particles; 
    public ParticlesTest() { 

     particles = new ArrayList<Particle>(); 

     vertices = new float[MAX_PARTICLES*6*3]; 
     indices = new short[MAX_PARTICLES*2]; 


     short cnt = 0; 
     for(int i = 0; i < 60; i++){ 
      createParticle(); 

      indices[cnt] = cnt; 
      cnt++; 
      indices[cnt] = cnt; 
      cnt++; 

     } 

     vbb = ByteBuffer.allocateDirect(vertices.length * 4); 
     vbb.order(ByteOrder.nativeOrder()); 
     vertexBuffer = vbb.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.position(0); 

     ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); 
     ibb.order(ByteOrder.nativeOrder()); 
     indexBuffer = ibb.asShortBuffer(); 
     indexBuffer.put(indices); 
     indexBuffer.position(0); 



    } 

    private void createParticle() { 
     Particle particle = new Particle(); 
     particle.setSpeedX((float)(Math.random() * 20 - 10)); 
     particle.setSpeedY((float)(Math.random() * 20 - 10)); 
     particle.setX(100); 
     particle.setY(100); 

     particles.add(particle); 


    } 
    private void update(){ 

     int len = particles.size(); 

     for(int i = 0; i < len; i++){ 
      Particle particle = particles.get(i); 

      float oldX = particle.getX(); 
      float oldY = particle.getY(); 
      float speedX = particle.getSpeedX(); 
      float speedY = particle.getSpeedY(); 

      oldX += speedX; 
      oldY += speedY; 

      particle.setX(oldX); 
      particle.setY(oldY); 

      if(oldX < 0 || oldX > 400 || oldY < 0 || oldY > 600){ 
       particles.remove(i); 
       len--; 
      } 
     } 

     if(len < MAX_PARTICLES){ 
      createParticle(); 
     } 
    } 


    private void translate(){ 


     int vcount = 0; 
     short icount = 0; 

     int clen = vertices.length; 

     for(int c = 0; c < clen; c++){ 
      vertices[c] = 0f; 
     } 


     int len = particles.size(); 

     for(int i = 0; i < len; i++){ 
      Particle particle = particles.get(i); 

      float oldX = particle.getX(); 
      float oldY = particle.getY(); 

      float speedX = particle.getSpeedX(); 
      float speedY = particle.getSpeedY(); 

      vertices[vcount] =oldX; 
      vcount++; 
      vertices[vcount] = oldY; 
      vcount++; 
      vertices[vcount] = 0f; 
      vcount++; 

      vertices[vcount] =oldX + speedX; 
      vcount++; 
      vertices[vcount] = oldY + speedY; 
      vcount++; 
      vertices[vcount] = 0f; 
      vcount++; 

      indices[icount] = icount; 
      icount++; 
      indices[icount] = icount; 
      icount++; 

     } 
    } 


    public void draw(GL10 gl,int w,int h) { 

     update(); 
     translate(); 

     vertexBuffer.put(vertices); 

     vertexBuffer.position(0); 

     //GLFPS.VERTS = vertices.length; 


     // rendering. 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);  
//  gl.glDrawElements(GL10.GL_LINE_STRIP, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); 
     gl.glDrawElements(GL10.GL_LINES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); 



     // Disable the vertices buffer. 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    } 
} 

回答

0

好的我現在發現了一個很好的方法來做到這一點(我認爲)。我沒有使用浮點的頂點緩衝,而是使用了Shorts的vertexbuffer。現在我用23fps在星系S上運行15k粒子。

0

有什麼辦法來解決這個問題?

預先分配所有對象並在遊戲運行時保持重用它們。

看到我的其他帖子here

+0

是否真的是一個很好的方法來運行gl.glDrawElements(GL10.GL_TRIANGLES,3,GL10.GL_UNSIGNED_SHORT,mIndexBuffer);每個粒子上有 ?我只是想知道,因爲我的測試表明太多的這些調用非常昂貴(比如說1000個粒子+其他所有應該繪製的內容......)或者? – user465627 2011-04-19 10:49:32

1

作爲一個建議,創建一個這樣大量的對象的ArrayList可以產生大量的內存開銷。另外,您是否考慮過使用GL ES 2.0而不是1?這樣,您可以使用GLSL創建粒子着色器程序,這將允許您釋放內存並在GPU上執行計算而不是CPU。那應該大大提高性能。