Android OpenGL OutOfMemory (Распределение буферов) - PullRequest
0 голосов
/ 05 июля 2011

Я анализирую двоичный файл с вершинами и их свойствами.Эти файлы варьируются от 50 000 до 2 000 000 вершин.Для более низких файлов у меня нет проблем с выделением сразу из массивов и отрисовкой точек, но для больших файлов это большая проблема.

Когда я создаю floatbuffer как таковой:

FloatBuffer buf = ByteBuffer.allocateDirect(vertices.length * 4);

Иногда я получаю OutOfMemory ошибок.Это не единственный буфер, который я рисую, я также делаю цвета.Есть ли лучший способ рисования вершин или выделения на лету буферов, и я рисую каждый раз?Вот некоторый базовый код рисования, который я использую:

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.nativeOrder());
    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);
}

Вызов new ProgressTask(ctx).execute(); просто анализирует и заполняет массивы.Я не могу позволить себе постоянно анализировать файл, это занимает слишком много времени.Какие варианты у меня есть?

1 Ответ

1 голос
/ 05 июля 2011

1) Я не знаю, что вы визуализируете, но кажется довольно странным отображать 50000 GL_POINT. Если вместо этого вы должны визуализировать polys (используя GL_TRIANGLE_STRIP или GL_TRIANGLE_FAN), вы можете сократить количество вершин, вероятно, наполовину или даже в трети, в зависимости от того, насколько хорошо вы оптимизируете данные.

2) Возможно, вы держите две ссылки на буферы вершин и цветов. Согласно документации, allocateDiret МОЖЕТ отобразить промежуточную память - или он может просто скопировать весь байт []. Позвольте сборщику мусора очистить lasVertices и lasColors, сделав их локальными переменными в конструкторе PointCloud, вместо того, чтобы они были переменными-членами. (Или, если они должны быть членами, установите их в null после помещения их в ByteBuffers.) Таким образом, если ByteBuffer копирует данные, у вас не будет двух копий.

...