Збільшити швидкість блиску?


9

Я працюю над 2-х бічним прокруткою в PyGame. Для кожної карти ми використовуємо одну текстуру (це фактичний розмір текстури):

карта текстури

Потім завантажуємо зображення за допомогою цього коду:

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))

І це працює. Проблема полягає в тому, що це досить повільно: я отримую мізерні 40 FPS на низько-пристойному ПК, і це без жодного фактичного AI / об'єкта, поки ми прагнемо 60 FPS. Як ми можемо прискорити це?


Зауважте, що наведений вище код захищений та виведений із контексту. Повний код можна знайти тут: https://github.com/nightcracker/PyGG2

І останнє, але не в останню чергу, хоча зображення, яке вище може виглядати як 8-бітове, в грі є елементи, які потребують більшої бітової глибини.


Розділіть на розмірний розмір на текстуру, скажімо, 1024 ширини на блок, і лише зафарбуйте два, які є релевантними одночасно.
Jari Komppa

@JariKomppa: Пробував це, не впливає на блискуче (пігаме досить розумний, щоб блиснути лише прямою частиною, про яку я їм кажу), лише використання пам'яті.
orlp

Ви не можете ... не використовувати пігаму (trollface.jpg) .... jkjk, в цьому випадку я здогадуюсь, що там не відбувається ваше уповільнення, чи ви протестували це широко?
ultifinitus

@ultifinitus: Так, я профілював це cProfile.
orlp

Яка різниця в швидкості, якщо відображати її при фактичній роздільній здатності? Що робити, якщо попередньо обчислити велике зображення?
ultifinitus

Відповіді:


7

Дозвольте перерахувати деякі загальні порівняльні оптимізації, пов’язані з блискучими пікселями на поверхні (з мого досвіду).

1) Зазвичай зображення палітри (індексовані зображення), коли вони блимають, піднимуть один додатковий рівень перенаправлення (щоб отримати колір). Тому вони будуть повільними, коли блимати, порівняно з справжніми кольоровими зображеннями.

2) Справжні кольорові піксельні дані (припустимо, що не мають альфа-скажімо24-бітових даних) можуть бути швидко відображені, оскільки ми можемо зробити 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' функції Blit під кришкою. Зазвичай Sdl блит буде дуже швидким і оптимізованим, тому просто зайвий раз зробіть не вищезгадані моменти та профіль! Удачі!

* Оновлення: * Налаштування кольорової клавіші - це як додавання додаткової перевірки при блискуванні кожного пікселя на поверхні. Дещо, як це -

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

         }

Отже, тут, якщо ви бачите, ми обмежені в тому, щоб не використовувати memcpy, оскільки нам потрібно перевірити дійсність кожного пікселя!


Гаразд, як виявляється, дзвінок set_colorkeyпросунувся на текстуру карти, надаючи їй (дорогий) альфа-канал. convertПрацівниками Державтоінспекції зафіксовано , що, і тепер я біг 150 FPS стайні на цьому лайні ПК. Дякую!
orlp

Ей буде редагувати пов'язане з кольором ключ, навіть забув додати трохи інформації про це: D
Айяппа

5

sprite.convert() не робить те, що ви думаєте, що це робить.

sprite = sprite.convert() це те, що вам потрібно.


Уопс, я маю sprite = sprite.convert()в реальному коді хоч :)
orlp

Ага, добре. :) У такому випадку я не маю нічого запропонувати тобі, окрім як розглянути можливість використання pyglet замість pygame або використовувати pyOpenGL безпосередньо, якщо тобі зручно для OpenGL.
Килотан

@Kylotan: хороший товариш з лову! я не перевірив це :)
Айяппа

або, ще краще:sprite = pygame.image.load("Maps/MapTesting.png").convert()
MestreLion
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.