Лучшая практика двигателя частиц opengl? - PullRequest
0 голосов
/ 19 апреля 2011

Я занимаюсь разработкой простой игры и в настоящее время переключаюсь с canvas на openGL.Так что мой опыт работы с openGL очень ограничен.Я пытаюсь создать простой движок частиц в данный момент, и он отлично работает, НО с моей текущей реализацией я должен запускать эту строку при каждом вызове draw () call [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);
    }
}

Ответы [ 3 ]

1 голос
/ 08 августа 2011

в качестве рекомендации, создание ArrayList из такого большого количества объектов может привести к значительным накладным расходам памяти.Кроме того, вы рассматривали возможность использования GL ES 2.0 вместо 1?Таким образом, вы можете создать программу Shader для частиц, используя GLSL, это позволит вам освободить память и выполнять вычисления на GPU, а не на CPU.Это должно значительно увеличить производительность.

0 голосов
/ 22 апреля 2011

ОК, я нашел действительно хороший способ сделать это сейчас (я думаю). Вместо использования буфера вершинного буфера у меня есть вершинный буфер шортов. Теперь я запускаю 15k частиц на галактике S с 23fps.

0 голосов
/ 19 апреля 2011

Есть ли способ обойти это?

Выделите все свои объекты заранее и продолжайте использовать их, пока ваша игра запущена.

Смотрите мой другой пост здесь .

...