Подтвердить что ты не робот

Оптимальная производительность 2D-2D-графики

Я сейчас пишу Java 2D-игру. Я использую встроенные библиотеки 2D 2D-чертежей, опираясь на Graphics2D, который я приобретаю из BufferStrategy из Canvas в JFrame (который иногда полноэкранный). BufferStrategy имеет двойную буферизацию. Перекраска осуществляется активно, через таймер. У меня проблемы с производительностью, особенно в Linux.

И Java2D имеет очень много способов создания графических буферов и рисования графики, которые я просто не знаю, правильно ли я поступаю. Я экспериментировал с graphics2d.getDeviceConfiguration(). CreateCompatibleVolatileImage, который выглядит многообещающим, но у меня нет реальных доказательств того, что это будет быстрее, если я переключу код чертежа на это.

В своем опыте, что является самым быстрым способом рендеринга 2D-графики на экране в Java 1.5+? Обратите внимание, что игра довольно далеко впереди, поэтому я не хочу переключаться на совершенно другой метод рисования, такой как OpenGL или движок игры. Я в основном хочу знать, как получить самый быстрый способ использования объекта Graphics2D для рисования материала на экране.

4b9b3361

Ответ 1

У меня такие же проблемы, как я. Посмотрите мой пост здесь:

Проблемы с производительностью Java2D

Он показывает причину ухудшения производительности и как ее исправить. Однако это не гарантировало хорошую работу на всех платформах. Вы увидите, почему в сообщении.

Ответ 2

Синтез ответов на этот пост, ответы на Consty's и мои собственные исследования:

Что работает:

  • Используйте GraphicsConfiguration.createCompatibleImage для создания изображений, совместимых с тем, что вы рисуете. Это абсолютно необходимо!
  • Используйте двойной буферизированный чертеж с помощью Canvas.createBufferStrategy.
  • Используйте -Dsun.java2d.opengl=True, где доступно ускорение рисования.
  • Избегайте использования преобразований для масштабирования. Вместо этого кешируйте версии изображений, которые вы собираетесь использовать.
  • Избегайте полупрозрачных изображений! Изображения с битовой маской отлично, но прозрачность в Java2D очень дорога.

В моих тестах, используя эти методы, я получил увеличение скорости 10x - 15x, что делает подходящую 2D 2D-графику возможностью.

Ответ 3

Вот несколько советов с моей головы. Если бы вы были более конкретными и что вы пытались сделать, я мог бы помочь больше. Звучит как игра, но я не хочу предполагать.

Сделайте только то, что вам нужно! Не слепо переписывайте() все время, попробуйте некоторых из братьев и сестер, таких как перерисовка (Rect) или перерисовка (x, y, w, h).

Будьте очень осторожны с альфа-смешиванием, поскольку это может быть дорогостоящая операция смешивания изображений/примитивов.

Попытайтесь как можно больше прервать/кешировать. Если вы обнаружите, что рисовать круг одинаково, снова и снова, подумайте о том, чтобы вставить в BufferedImage, а затем просто нарисовать BufferedImage. Вы жертвуете памятью для скорости (типичной для игр/высокой графикой)

Рассмотрим использование OpenGL, используйте JOGL LWJGL. JOGL более похож на Java, тогда как LWJGL предоставляет больше игровых функций поверх OpenGL-доступа. OpenGL может набирать порядки (с соответствующим оборудованием и драйверами), чем Swing.

Ответ 4

Там важный, который еще не упоминался, я думаю: кешируйте изображения всего, что вы можете. Если у вас есть объект, который перемещается по экрану, и внешний вид его сильно не меняется, нарисуйте его на изображении, а затем визуализируйте изображение на экране в новой позиции в каждом кадре. Сделайте это, даже если объект очень простой - вы можете быть удивлены, сколько времени вы сохраняете. Рендеринг растрового изображения намного быстрее, чем рендеринг примитивов.

Возможно, вы также захотите взглянуть на настройку подсказок рендеринга явно и отключить такие функции, как сглаживание, если позволяют соображения качества.

Ответ 5

Я сделал некоторые базовые приложения рисования, используя Java. Я не работал над чем-то слишком графически-интенсивным, но я бы порекомендовал вам, чтобы вы хорошо справились со всеми призывами "перекрасить". Дополнительный вызов перерисовки в родительском контейнере может удвоить объем вашего рендеринга.

Ответ 6

Я смотрел этот вопрос, надеясь, что кто-то предложит вам лучший ответ, чем мой.

Тем временем я нашел следующий Sun white paper, который был написан после бета-версии jdk 1.4. Здесь есть несколько интересных рекомендаций по тонкой настройке, включая флаги времени выполнения (внизу статьи):

" Флаг выполнения для Solaris и Linux

Начиная с версии SDK версии 1.4, версия 1.4, Java 2D сохраняет изображения в растровых изображениях по умолчанию, когда DGA недоступен, независимо от того, работаете ли вы в локальной или удаленной среде отображения. Вы можете переопределить это поведение с помощью флага pmoffscreen:

-Dsun.java2d.pmoffscreen = true/false

Если вы установите для этого флага значение true, поддержка экранной поддержки карт включена, даже если DGA доступен. Если вы установите для этого флага значение false, отключена поддержка экранной поддержки pixmap. Отключение поддержки неосновной поддержки pixmap может решить некоторые проблемы с рендерингом. "

Ответ 7

убедитесь, что вы используете двойную буферизацию, нарисуйте сначала один большой буфер в памяти, который затем вышьте на экран, когда все чертежи сделаны.

Ответ 8

Есть несколько вещей, которые вам нужно иметь в виду.

1) обновляется эта ссылка показывает, как использовать swingtimers, которые могут быть хорошим вариантом для вызова перерисовки. Получение перерисовывания (как отмечали предыдущие плакаты, важно, чтобы вы не делали слишком много работы).

2) Убедитесь, что вы выполняете только рисование в одном потоке. Обновление пользовательского интерфейса из многолистных потоков может привести к неприятным вещам.

3) Двойная буферизация. Это делает рендеринг более плавным. этот сайт содержит дополнительную информацию для вас

Ответ 9

Альтернативой, если вы не хотите использовать чистую Java 2D, является использование игровой библиотеки, такой как GTGE или JGame (поиск в Google), а затем простой доступ к графике, а также двойная буферизация и гораздо более простой рисунок команды.