Частина 12 - Логічна роздільна здатність

Тепер представимо про неймовірну функцію SDL 2.0 яка вирішує велику серйозну проблему для багатьох програмістів. Вона стосується роздільної здатності програми або гри.

Логічна роздільна здатність в SDL 2.0

Якщо Ви створюєте гру, лише велику частину питань Ви можете частково вирішити просто на стадії планування. Основне питання: яку саме роздільну здатність користувачі збираються використовувати для гри? Чи підтримують їх монітори роздільну здатність, яку Ви вирішили використовувати? Користувач/геймер використовує широкоформатний монітор? І так далі. Залежно від відповідей на ці запитання, Ви можете вибрати роздільну здатність спрайтів/файлів зображень. Якщо Ви хочете отримати цільову роздільну здатність 640x480 (VGA), Ви оберете менш деталізовані вихідні зображення, ніж якщо б Ви обрали 1024x768 (XGA), або навіть широкоформатний 1680x1050 (WSXGA +) або будь-яку іншу високу роздільну здатність. Якби кожен монітор/відеокарта могли відображати всі можливі роздільні здатності, це не представляло б великої проблеми. Система просто переключиться на необхідну роздільну здатність і вуаля гра працює і виглядає, як очікувалося. На жаль, не можна очікувати, що система, максимальна роздільна здатність якої дозволяє XGA відображати роздільну здатність WSXGA +. Крім того, навіть якщо система здатна відображати дуже високі роздільні здатності, немає гарантії, що вона зможе перейти до роздільної здатності VGA.

Крім того, якщо Ви оптимізуєте гру для роздільної здатності VGA, Ви будете обирати спрайти/зображення відповідно до розміру екрана 640x480 пікселів. Скажімо, Ви граєте в гоночну гру. Ви вибираєте зображення автомобіля шириною 64 пікселі та висотою 32 пікселі. Це заповнює велику частину екрану з роздільною здатністю VGA. У роздільній здатності WSXGA + ширина та висота автомобіля будуть виглядати менше половини, що буде здаватися крихітним. SDL 2.0 надає рішення для уникнення багатьох проблем, пов’язаних із налаштуваннями роздільної здатності: логічна роздільна здатність.

Давайте подивимось на код.

program SDL_LogicalResolution;

uses SDL2;

const
  Border:  TSDL_Rect = (x: 0;   y:   0; w: 640; h: 480);
  Quarter: TSDL_Rect = (x: 320; y: 240; w: 320; h: 240);

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;

begin

  // ініціалізація підсистеми відео
  if SDL_Init(SDL_INIT_VIDEO) < 0 then
    Halt;

  if SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, @sdlWindow1, @sdlRenderer) <> 0 then
    Halt;

  // встановити фільтр масштабування
  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 'linear');  

  // встановити логічну роздільну здатність
  if SDL_RenderSetLogicalSize(sdlRenderer, 640, 480) <> 0 then
    Halt;

  // намалювати червону границю
  SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderDrawRect(sdlRenderer, @Border);

  // намалювати зелену четвертину
  SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderDrawRect(sdlRenderer, @Quarter);

  // візуалізувати в вікно на 3 секунди
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(3000);

  // очистити пам'ять
  SDL_DestroyRenderer(sdlRenderer);
  SDL_DestroyWindow (sdlWindow1);

  // завершити роботу SDL2
  SDL_Quit;

end.

Ця програма в основному малює два прямокутники, червоний і зелений. Вони визначаються цими константами.

const
  Border:  TSDL_Rect = (x: 0;   y:   0; w: 640; h: 480);
  Quarter: TSDL_Rect = (x: 320; y: 240; w: 320; h: 240);

Константа “Border” розміщена в координатах (0/0) і має ширину 640 пікселів і висоту 480 пікселів. “Quarter” розміщена в координатах (320/240) і має ширину 320 і висоту 240. Припустимо, у вас є сучасний монітор і візуалізація цих двох прямокутників у повноекранний режим із типовою роздільною здатністю 1680 × 1050 або навіть вище. Ви будете очікувати в результаті щось на зразок цього:

Creative Commons License Це зображення від https://www.freepascal-meets-sdl.net ліцензовано за Creative Commons Attribution 4.0 International License.
Це очікуваний результат, якщо ваш монітор має роздільну здатність 1680×1050 пікселів, і Ви візуалізуєте червоний прямокутник у положенні (0/0) із розміром 640×480 пікселів, а зелений прямокутник у положенні (320/240) із розміром 320×240 пікселів.

Але оскільки ми ввели логічну роздільну здатність у програму, ми насправді отримуємо щось подібне:

Creative Commons License Це зображення від https://www.freepascal-meets-sdl.net ліцензовано за умовами Creative Commons Attribution 4.0 International License.
Це результат для роздільної здатності монітора 1680×1050 пікселів, якщо використовується логічний розмір 640×480 пікселів. Зверніть увагу на чорну межу ("поштова скринька") ліворуч і праворуч від червоного прямокутника через різні співвідношення сторін, 16:10 (монітор) та 4: 3 (цільова роздільна здатність 640 × 480).

Як SDL2 досягає логічної роздільної здатності?

Хоча роздільна здатність Вашого монітора може бути набагато більшою (наприклад, 1680×1050 пікселів), ніж очікувана Вашою програмою (640×480 пікселів), SDL2 буде масштабувати все вгору або вниз, щоб найкраще відповідати Вашій реальній роздільній здатності!

Функція SDL_RenderSetLogicalSize() використовується щоб досягнути логічної роздільної здатності і повертається 0 при успіху і негативний код помилки при невдачі.

SDL_RenderSetLogicalSize(renderer: PSDL_Renderer; w: SInt32; h: SInt32): SInt32.

Вона встановлюне родільну здатність незалежно від пристрою для візуалізації. Вона використовуватиме функції масштабування всередині, щоб відповідати цільовій роздільній здатності фактичній роздільній здатності екрана / пристрою. Якщо Ви хочете показувати гру в роздільній здатності VGA (640x480) на екрані з роздільною здатністю XGA (1024x768), SDL_RenderSetLogicalSize() буде масштабувати все, що потрібно для заповнення екрана. Навіть якщо пропорції пристрою інакші, наприклад Ви намагаєтесь отримати роздільну здатність з пропорціями 4:3 на широкоформатному моніторі з пропорціями 16:9, ця функція просто додасть кілька смужок у відповідних місцях (див. скріншот вище) і максимально піджене цільову роздільну здатність до роздільної здатності пристрою. Це продемонстровано в прикладі коду. Цільова роздільна здатність 640 пікселів ширини і 480 пікселів висоти (співвідношення 4:3) повинна бути досягнута в пристрої (вікно) ширина х висота якого 1680 х 1050 пікселів (співвідношення 16:10).

Повернемось до коду. Повноекранна візуалізація з роздільною здатністю робочого столу досягається прапорцем SDL_WINDOW_FULLSCREEN_DESKTOP.

  if SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, @sdlWindow1, @sdlRenderer) <> 0 then
    Halt;

І тоді логічний розмір встановлюється, як обговорювалось SDL_RenderSetLogicalSize(). До речі, настійно рекомендується встановити фільтр масштабування (SDL_SetHint()) до фільтра кращої якості, тому що важке масштабування робиться за кулісами функцією SDL_RenderSetLogicalSize().

  // встановити фільтр масштабування
  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 'linear');
  
  // встановити логічну роздільну здатність
  if SDL_RenderSetLogicalSize(sdlRenderer, 640, 480) <> 0 then
    Halt;

Взагалі-то це все :-), все інше, малювання та рендеринг прямокутників та очищення пам'яті Вам відомо.

← попередня частина | наступна частина →

Немає коментарів:

Дописати коментар