我正在开发一个简单的游戏,我目前正在从canvas切换到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);
}
}
答案 0 :(得分:1)
作为建议,创建如此大量对象的ArrayList可以创建大量的内存开销。另外,您是否考虑过使用GL ES 2.0而不是1?这样你就可以使用GLSL创建一个粒子着色器程序,这将允许你释放内存并在GPU上进行计算而不是CPU。那应该大大提高性能。
答案 1 :(得分:0)
答案 2 :(得分:0)
好的,我现在找到了一个非常好的方法(我认为)。我没有使用浮点数的顶点缓冲区,而是使用了短脚本顶点缓冲区。现在我用23fps在星系S上运行15k粒子。