I'm parsing a binary file with vertices and their properties. These files range from 50,000-2,000,000 vertices. For the lower files, I have no problems allocating straight off of arrays and drawing the points, but for larger files, its a big problem.
When I create a floatbuffer as such:
FloatBuffer buf = ByteBuffer.allocateDirect(vertices.length * 4);
I sometimes get OutOfMemory errors. This isn't the only buffer I draw, I also do color. Is there a better way of drawing the vertices or allocating on the fly to the buffers and I draw everytime? Here is some basic drawing code I am using:
public PointCloud(String passedFileName, Context ctx) {
fileName = passedFileName;
header = new LAS_HeadParser(fileName);
numVertices = (int)header.numberOfPoints;
lasVertices = new float[numVertices*3];
lasColors = new float[numVertices*4];
intensity = new float[numVertices];
vbb = ByteBuffer.allocateDirect(lasVertices.length * 4);
cbb = ByteBuffer.allocateDirect(lasColors.length * 4);
new ProgressTask(ctx).execute();
}
public void setupBuffers(){
// a float is 4 bytes, therefore we multiply the number if
// vertices with 4.
vbb.order(ByteOrder.nati开发者_如何学编程veOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(lasVertices);
vertexBuffer.position(0);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(lasColors);
colorBuffer.position(0);
}
public void draw(GL10 gl) {
//Log.d("Enter Draw", "*****************");
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glPointSize(0.6f);
gl.glDrawArrays(GL10.GL_POINTS, 0, numVertices);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
The call new ProgressTask(ctx).execute();
just parses and populates arrays. I can't afford to continually parse the file, it takes too long. What options do I have?
1) I don't know what you're rendering, but it seems rather odd to render 50,000 GL_POINTs. If you were to render polys instead (using GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN) you can cut the number of vertices probably in half or even in third, depending on how well you optimize the data.
2) You may be holding two references to the vertex and color buffers. According to documentation allocateDiret MAY map to intermediate memory -- or it may just copy the whole byte[]. Let the garbage collector clean up lasVertices and lasColors by making them local variables in the PointCloud constructor, rather than having them be member variables. (Or if they have to be members, set them to null after putting them in the ByteBuffers.) That way, if ByteBuffer is copying the data, you won't have two copies.
精彩评论