블리 팅 속도를 높이시겠습니까?


9

PyGame에서 2d sidecroller를 작업 중입니다. 각 맵에 대해 하나의 텍스처를 사용합니다 (텍스처의 실제 크기).

지도 질감

그런 다음이 코드로 이미지를로드합니다.

sprite = pygame.image.load("Maps/MapTesting.png")
sprite.convert()
sprite = pygame.transform.scale(sprite,
              (sprite.get_width()*6, sprite.get_height()*6))

보시다시피, 텍스처는 실제 맵 텍스처를 만들기 위해 6 번 날려집니다. 평균적으로이 텍스처는 약 4500x800입니다. 이 텍스처는 전체 화면이 더럽 기 때문에 (화면이 옆으로 스크롤되므로) 매 프레임마다 화면에 블리 팅되어야합니다 . 우리는이 코드를 사용하여 그렇게합니다 :

screen.blit(sprite, (0, 0),
(cameraposx, cameraposy, windowheight, windowwidth))

그리고 작동합니다. 문제는 속도가 느리다는 것입니다. 저렴한 PC에서 빈약 한 40 FPS를 얻습니다. 실제 AI / 객체가 진행되지 않고 60 FPS를 목표로하고 있습니다. 어떻게하면 속도를 높일 수 있습니까?


위의 코드는 삭제되고 컨텍스트에서 제외됩니다. 전체 코드는 여기에서 찾을 수 있습니다 : https://github.com/nightcracker/PyGG2

마지막으로 위의 이미지는 8 비트처럼 보일 수 있지만 게임에 더 많은 비트 심도가 필요한 요소가 있습니다.


텍스처 당 적절한 크기 (예 : 블록 당 1024 너비)로 분할하고 한 번에 관련된 두 개만 블리 팅합니다.
Jari Komppa

@JariKomppa : 시도해 보았지만, 블리 팅에 영향을 미치지 않습니다 (파이 게임은 내가 말한 rect 만 블리 팅 할 정도로 똑똑합니다).
orlp

pygame (trollface.jpg)을 사용할 수 없었습니다 .... jkjk,이 경우 속도 저하가 발생하지 않는 것으로 추측됩니다. 광범위하게 테스트 했습니까?
ultifinitus

@ultifinitus : 예, cProfile로 프로파일 링했습니다.
orlp

실제 해상도로 표시하면 속도 차이는 무엇입니까? 더 큰 이미지를 미리 계산하면 어떻게 되나요?
ultifinitus

답변:


7

Blitting pixel과 관련하여 일반적인 경험을 바탕으로 표면에 최적화 된 최적화를 나열하겠습니다.

1) 일반적으로 팔레트 이미지 (색인 이미지)는 블리트 될 때 한 단계의 리디렉션 (색상을 얻음)을 수행하므로 트루 컬러 이미지와 비교할 때 블리 팅 할 때 속도가 느려집니다.

2) 트루 컬러 픽셀 데이터 (알파가 없음-24 비트 데이터가 있다고 가정)는 이미지의 각 스캔 라인 (이미지의 일부를 복사하는 경우)에 대해 장치 프레임 버퍼에 memcpy를 수행 할 수 있으므로 매우 빠르게 블리 팅 할 수 있습니다 블리 팅 할 데이터가 전체 이미지 인 경우 훨씬 빠른 전체 데이터를 직접 memcpy 할 수 있습니다!

3) 알파 픽셀 데이터를 블리 팅하면 결과적으로 각 구성 요소를 계산하는 것이 포함되므로 비용이 가장 많이 들며 RGB 데이터로 다시 팩킹해야합니다. 간단히 말해서 최종 색상을 얻기 위해 각 픽셀에 대해 더 많은 작업을 수행하십시오!

Finalrgb = Alpha*(Srgb) + (1-Alpha)*Drgb (this is for normal blend equation)
    where Srgb is source-rgb (we need to apply for each of the component for final color)
       Drgb is the color that will be there in the destination buffer.

나는 전에 pyGame에서 일하지 않았다. 일반적으로 Sdl 블리트는 매우 빠르고 최적화되어 있으므로 위의 포인트와 프로파일을 다시 작성하지 마십시오! 행운을 빕니다!

* 업데이트 : * 색상 키 설정은 표면에 각 픽셀을 블리 팅 할 때 하나의 추가 검사를 추가하는 것과 같습니다.

       for(eachPixelColor in allPixels)
         {
            if(eachPixelColor is NOT colorKeyColor)
            {
              copy color to the frame buffer!
            }

         }

따라서 여기에서 알 수 있듯이 각 픽셀의 색상 유효성을 확인해야하므로 memcpy를 사용하지 않아야합니다!


좋아, set_colorkey맵 텍스처에서 미끄러 져 전화를 걸면 알파 채널이 비싸다. A는 convert그 고정, 지금은이 쓰레기의 PC에 150 FPS 안정을 실행하고 있습니다. 감사!
orlp

헤이 컬러 키와 관련된 편집합니다 심지어 있습니다 ABT 몇 가지 정보를 추가하는 것을 잊었다 : D
Ayyappa

5

sprite.convert() 당신이 생각하는 것을하지 않습니다.

sprite = sprite.convert() 당신이 필요한 것입니다.


Woops, 난 sprite = sprite.convert()진짜 코드를 가지고 있지만 :)
orlp

아하, 좋아 :)이 경우 파이 게임 대신 피그렛 사용을 고려하거나 OpenGL에 익숙하다면 pyOpenGL을 직접 사용하는 것을 제외하고는 제공 할 것이 없습니다.
Kylotan

@Kylotan : 좋은 캐치 메이트! 내가 그것을 :) 확인하지 않은
Ayyappa

또는 더 나은 :sprite = pygame.image.load("Maps/MapTesting.png").convert()
MestreLion
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.