0

私は単純なゲームを開発しており、現在キャンバスから openGL に切り替えています。そのため、私の openGL の経験は非常に限られています。私はあなたの瞬間に単純なパーティクルエンジンを作成しようとしていますが、それは正常に動作しますが、現在の実装ではすべての draw() 呼び出しでこの行を実行する必要があります [ vertexBuffer.put(vertices); ] そしてそれは本当に遅い..これを回避する方法はありますか?

コードは次のようになります。

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);
    }
}
4

3 に答える 3

1

推奨事項として、このような多数のオブジェクトの ArrayList を作成すると、大量のメモリ オーバーヘッドが発生する可能性があります。また、GL ES 1 ではなく 2.0 を使用することを検討しましたか? このようにして、GLSL を使用してパーティクル シェーダー プログラムを作成できます。これにより、メモリを解放し、CPU ではなく GPU で計算を行うことができます。これにより、パフォーマンスが大幅に向上するはずです。

于 2011-08-08T15:19:55.480 に答える
0

これを回避する方法はありますか?

すべてのオブジェクトを前もって割り当て、ゲームの実行中にそれらを再利用し続けます。

ここで私の他の投稿を参照してください。

于 2011-04-19T10:05:58.100 に答える
0

OK、これを行うための本当に良い方法を見つけました(と思います)。float の vertexbuffer を使用する代わりに、Shorts の vertexbuffer を使用します。今、私は 23 fps の銀河 S で 15,000 のパーティクルを実行しています。

于 2011-04-22T08:43:28.657 に答える