2013-12-10 2 views
2

Я пытаюсь найти возможность минимизировать выделение памяти и сборку мусора в приложении Java OpenGL (JOGL). Я переношу некоторый проект C/C++/C# OpenGL на Java в качестве учебного упражнения. Одна вещь, с которой я сталкиваюсь, - отсутствие указателей на Java и выделение объектов и GC из них при запуске приложения. В C/C++/C# я могу запускать приложения и запускать их без выделения дополнительной памяти или объектов путем передачи ссылок, но в Java кажется, что мои проекты несовместимы.Java OpenGL (JOGL) Массивы объектов и FloatBuffers

По мере развития этих проектов они используют объекты более высокого уровня. В C они были структурами для векторов и матриц и классов C++/C#. Все они сводятся к массивам байтов в памяти. Который затем каким-то образом применяется для плавания [] для вызовов OpenGL или массивов объектов внутри приложения, поэтому я могу использовать объекты, основанные на объектах, такие как перегрузка, добавление и размножение операторов, или доступ к свойствам, например, для работы с объектами. Любой, кто работает с OpenGL, вероятно, видит, что я делаю. Таким образом я распределяю все на нагрузку и просто передаю данные.

Ява бросила меня на какие-то петли. Кажется, я не могу передавать данные взад и вперед, поэтому я продолжаю создавать множество данных, и GC приходит и работает. Это заметно из-за потребления и очистки ресурсов и заметного заикания во время запуска приложения. Я немного облегчил это, создав FloatBuffers в дополнение к массивам VectorXf для данных геометрии и передав FloatBuffer до OpenGL. Но когда мне нужно обновлять векторные данные, я должен вернуть данные обратно в буферный буфер. Это также означает, что я сохраняю двойные данные и несут накладные расходы на заполнение флоатбуфером.

Хотелось бы услышать, как другие справляются с этими проблемами. Я хотел бы сохранить объекты более высокого порядка для встроенной функциональности, но иметь возможность передавать данные в OpenGL. Являются ли мои проекты просто несовместимыми с Java? Нужно ли мне переходить только на FloatBuffers? Как передать данные компонента в объект более высокого порядка без штрафа за создание объекта. Настолько много OpenGL-приложений существуют, что я подозреваю, что существует некоторая «магия» для использования одного и того же буфера для float [] и Object [] или выделения смежного блока для данных объекта и передачи ссылки на OpenGL.

ответ

3

Движущей силой при управлении вашими данными OpenGL является то, что вы не хотите нести ответственность за память, содержащую геометрию или текстуры. Использование float[] или даже FloatBuffers должно выполняться только с целью переноса геометрических данных в объекты буфера OpenGL. После того как вы создали буфер OpenGL и скопировали данные на него, вам больше не нужно сохранять копию в JVM. Фактически во всех современных аппаратных средствах это приведет к сохранению данных на самой видеокарте, полностью вне JVM.

В идеале, если большая часть вашей геометрии является статичной, вы можете скопировать ее в буферы OpenGL во время запуска и никогда больше не управлять ею напрямую. Если вы имеете дело с большим количеством динамической геометрии, вам все равно придется переносить данные обратно и обратно в драйвер OpenGL. В этом случае вы, вероятно, захотите сохранить пул FloatBuffers, который может действовать как паромы для перемещения данных между вашим кодом, созданием или обнаружением изменяющейся геометрии, и драйвером. FloatBuffers неизбежны, поскольку OpenGL ожидает данные в заданном формате, который будет отличаться от внутреннего представления данных в JVM, но по крайней мере вам не нужно поддерживать отдельный FloatBuffer для каждого набора данные, которые у вас есть.

+0

То, где я нахожусь. Создал VBO для всего и перешел к GL, а затем удалил буфер. Странная вещь - 1 из 5 раз, когда приложение будет сбрасывать ядро ​​в glBufferData. Его как код перемещается к вызову glBufferData до того, как буферы с плавающей точкой заполнены или где-нибудь нуль. Все, что я делаю после сбоя, при запуске запускается снова, и это работает. Все еще работаю над тем, чтобы аннулировать поведение. Для динамического содержимого, вывода шрифта экрана, я сохраняю буффер, чтобы переправляться, когда вы указывали данные на аппаратное обеспечение через glDrawArrays. До сих пор все остальное статично. – user2811897

+0

FloatBuffers - это что-то вроде боли. Они сохраняют внутренний указатель на «текущее пятно» в буфере, так что их легко добавить к ним. Большинство сбоев, с которыми я столкнулся при работе с ними, заставляют забыть сбросить указатель до 0, прежде чем отправлять его в GL, что означает, что OpenGL начнет чтение из середины или конца буфера и, возможно, перейдет в неинициализированную память. Другие потенциальные источники ошибок включают просчет количества байтов, доступных в буфере, которые необходимо передать в glBufferData. – Jherico

+0

Все буферы установлены в положение (0) до запуска glBufferData. Его также странно, что это происходит только время от времени. Такой же запуск кода выполняется. Размер, может быть, но я фактически directAllocate() ByteBuffers asFloatBuffer, поэтому мой размер вычисляется в байтах, поэтому я на 99% уверен, что они точны. Его порт из C, как langs, поэтому математика такая же, я надеюсь ... – user2811897

0

Мой опыт: Я использовал FloatBuffers только для передачи данных, но я обнаружил, что это было действительно убийство производительности для динамических сеток, потому что мне приходилось преобразовывать массивы Vec в FloatBuffers каждый раз, когда я меняю свои сетки. Теперь я избавился от своих массивов vec и постоянно использовал FloatBuffers через свои классы mesh, менее изящные для обработки, но намного быстрее.Поэтому я бы посоветовал вам сохранить & обновить все данные геометрии с помощью FloatBuffers

Смежные вопросы