Java 2D Drawing 최적의 성능


Answers

내 생각과 똑같은 문제가있어. 내 게시물을 확인하십시오.

Java2D 성능 문제

성능 저하의 원인과 해결 방법을 보여줍니다. 모든 플랫폼에서 제대로 작동하는 것은 아닙니다. 게시물에서 이유를 확인할 수 있습니다.

Question

Java 2D 게임을 작성하는 중입니다. 필자는 내장 된 Java 2D 드로잉 라이브러리를 사용하고 있는데 JFrame (때때로 풀 스크린으로 표시됨)의 Canvas에있는 BufferStrategy에서 가져온 Graphics2D를 그려 넣습니다. BufferStrategy는 이중 버퍼입니다. 재 초기화는 타이머를 통해 능동적으로 수행됩니다. 그래도 성능 문제가 있습니다. 특히 Linux에서.

그리고 Java2D에는 그래픽 버퍼를 만들고 그래픽을 그리는 방법이 너무 많아서 내가 옳은 일을하는지 알지 못합니다. 나는 graphics2d.getDeviceConfiguration ()을 사용하여 실험을 해왔다. createCompatibleVolatileImage는 유망 해 보였지만 그리기 코드를 바꾸면 더 빠를 것 같지 않다.

자바 1.5 이상에서 2D 그래픽을 화면에 렌더링하는 가장 빠른 방법은 무엇입니까? 이 게임은 상당히 앞서 있으므로 OpenGL이나 게임 엔진과 같이 완전히 다른 드로잉 방법으로 전환하고 싶지는 않습니다. 기본적으로 Graphics2D 객체를 사용하여 화면에 물건을 그리는 가장 빠른 방법을 얻는 방법을 알고 싶습니다.




저는 누군가가 당신보다 나은 대답을 줄 수 있기를 희망하면서이 질문을 보았습니다.

그동안 jdk 1.4 베타 릴리스 이후에 작성된 다음 Sun 백서 를 발견했습니다. 여기에는 런타임 플래그 (기사 하단)를 비롯하여 미세 조정에 대한 몇 가지 흥미로운 권장 사항이 있습니다.

" Solaris 및 Linux의 런타임 플래그

SDK 1.4 버전의 베타 3 릴리스부터 Java 2D는 로컬 또는 원격 디스플레이 환경에서 작업하는 경우 DGA를 사용할 수없는 경우 기본적으로 픽스맵에 이미지를 저장합니다. pmoffscreen 플래그를 사용하여이 동작을 무시할 수 있습니다.

-Dsun.java2d.pmoffscreen = true / false

이 플래그를 true로 설정하면 DGA를 사용할 수 있더라도 오프 스크린 pixmap 지원이 활성화됩니다. 이 플래그를 false로 설정하면 오프 스크린 픽스맵 지원이 비활성화됩니다. 오프 스크린 픽스맵 지원을 비활성화하면 일부 렌더링 문제를 해결할 수 있습니다. "




대안으로 순수한 Java 2D를 사용하지 않으려면 GTGE 또는 JGame (Google에서 검색)과 같은 게임 라이브러리를 사용하고 그래픽에 쉽게 액세스 할 수 있으며 이중 버퍼링과 훨씬 간단한 그리기 명령을 제공 할 수도 있습니다.




명심해야 할 몇 가지가 있습니다.

1) 이 링크를 새로 고침하는 것은 스윙 타이머를 사용하는 방법을 보여줍니다. 스윙 타이머는 repaint를 호출하는 좋은 옵션입니다. 다시 그리는 방법은 알아 냈습니다 (이전 포스터는 중요하므로 너무 많은 작업을하지는 않습니다).

2) 한 스레드에서만 그리기를하고 있는지 확인하십시오. 여러 스레드에서 UI를 업데이트하면 문제가 발생할 수 있습니다.

3) 더블 버퍼링. 이렇게하면 렌더링이 부드럽게됩니다. 이 사이트 는 당신에게 더 좋은 정보가 있습니다.




Java를 사용하여 기본 드로잉 응용 프로그램을 만들었습니다. 나는 그래픽 집중적 인 작업을하지 않았지만 모든 repaint 호출을 잘 처리 할 것을 권한다. 상위 컨테이너에서 다시 그리는 호출은 렌더링 작업량을 두 배로 늘릴 수 있습니다.




내 머리 꼭대기에서 몇 가지 팁을 소개합니다. 당신이 더 구체적이고 무엇을하려고했는지 더 많이 도울 수 있습니다. 게임처럼 들리지만, 나는 추측하고 싶지 않습니다.

당신이 필요로하는 것을 그리십시오! 맹목적으로 repaint ()를 호출하지 말고, repaint (Rect) 또는 repaint (x, y, w, h)와 같은 형제 중 일부를 시도하십시오.

알파 블렌딩은 이미지 / 프리미티브를 블렌딩하는 데 값 비싼 작업이 될 수 있으므로 조심하십시오.

가능한 한 프리 랜더 / 캐시를 시도하십시오. 똑같은 방식으로 원을 그린다면, BufferedImage로 드로잉을 고려한 다음 BufferedImage를 그립니다. 속도에 대한 메모리를 희생합니다 (게임 / 높은 퍼포먼스 그래픽의 전형적인)

OpenGL을 사용하고, LWJGL의 JOGL을 사용하십시오. JOGL은 Java와 유사하지만 LWJGL은 OpenGL 액세스에 더 많은 게임 기능을 제공합니다. OpenGL은 스윙 할 수있는 것보다 적절한 하드웨어 및 드라이버를 사용하여 수주 할 수 있습니다.




이중 버퍼링을 사용하는지 확인하고, 메모리에있는 첫 번째 큰 버퍼를 그리면 모든 그리기가 완료 될 때 화면으로 플러시됩니다.




이 게시물에 대한 답변, Consty 's에 대한 답변 및 내 자신의 연구 :

효과 :

  • GraphicsConfiguration.createCompatibleImage 를 사용하여 그리는 이미지와 호환되는 이미지를 만듭니다. 이것은 절대적으로 중요합니다!
  • Canvas.createBufferStrategy 를 통해 이중 버퍼링 된 도면을 사용하십시오.
  • -Dsun.java2d.opengl=True 사용하면 그리기 속도를 향상시킬 수 있습니다.
  • 확장을 위해 변환을 사용하지 마십시오. 대신 사용할 이미지의 스케일 버전을 캐싱하십시오.
  • 반투명 이미지는 피하십시오! 비트 마스크 이미지는 괜찮지 만 반투명은 Java2D에서 매우 비쌉니다.

내 테스트에서 이러한 방법을 사용하여 10 배에서 15 배까지 속도가 향상되어 적절한 Java 2D 그래픽을 만들 수있었습니다.




아직 언급되지 않은 중요한 것이 있습니다. 나는 할 수있는 모든 것을 캐시합니다. 화면을 가로 질러 이동하는 객체가 있고 모양이 많이 변경되지 않으면 이미지에 그려서 이미지를 각 프레임의 새 위치에있는 화면에 렌더링합니다. 객체가 매우 단순한 것이라 할지라도 - 얼마나 많은 시간을 절약 할 수 있는지 놀랄 것입니다. 비트 맵 렌더링은 프리미티브 렌더링보다 훨씬 빠릅니다.

렌더링 힌트를 명시 적으로 설정하고 품질 고려 사항이 허용하는 경우 앤티 엘리 어싱과 같은 설정을 해제 할 수도 있습니다.