Вопрос

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

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

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

Это было полезно?

Решение

Думаю, у меня те же проблемы, что и у вас.Посмотрите мой пост здесь:

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-Dsun.java2d.pmoffscreen=истина/ложь

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top