Переклад виконано з дозволу автора оригінального матеріалу. Усі пропозиції та зауваження щодо перекладу прохання залишати в коментарях на сторінці матеріалу.
Екрани та зображення мають прямокутну форму, тому ця форма має особливе значення для SDL2 та, зокрема, для програмування графіки.
Прямокутники: TSDL_Rect та PSDL_Rect в SDL 2.0
Часто функції вимагають аргументу типу PSDL_Rect. Це аналог вказівника на TSDL_Rect. Він оголошений наступним чином:
PSDL_Rect = ^TSDL_Rect; TSDL_Rect = record x,y: SInt32; w,h: SInt32; end;
Просто цей запис описує прямокутник (rectangle), звідси і назва. Змінні x і y відповідають координатам x/y лівого верхнього кута прямокутника, що відносяться до початку координат 0/0, який є лівим верхнім кутом, наприклад, текстура, вікно,… Змінна w - це ширина, а h - висота прямокутника. Це воно. Наступним кроком є визначення прямокутника шляхом присвоєння деяких значень для x, y, w і h.
Якщо Ви користуєтесь PSDL_Rect, Вам потрібно виділити необхідну пам'ять процедурою Pascal new як для будь-якого простого вказівника на запис.
Використання прямокутників для руху та масштабування
Наступний код демонструє основний принцип того, як створити враження руху зображень (спрайтів) і як працює масштабування. Ви будете вражені, наскільки це насправді просто.
program SDL_RectanglesScaling;
uses SDL2;
var
sdlWindow1: PSDL_Window;
sdlRenderer: PSDL_Renderer;
sdlSurface1: PSDL_Surface;
sdlTexture1: PSDL_Texture;
sdlRectangle: TSDL_Rect;
begin
//ініціалізація відеосистеми
if SDL_Init(SDL_INIT_VIDEO) < 0 then Halt;
if SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN, @sdlWindow1, @sdlRenderer) <> 0
then Halt;
// встановити якість масштабування
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 'nearest');
// create surface from file
sdlSurface1 := SDL_LoadBMP('fpsdl.bmp');
if sdlSurface1 = nil then
Halt;
// завантажити файл зображення
sdlTexture1 := SDL_CreateTextureFromSurface(sdlRenderer, sdlSurface1);
if sdlTexture1 = nil then
Halt;
// підготувати прямокутник
sdlRectangle.x := 12;
sdlRectangle.y := 25;
sdlRectangle.w := 178;
sdlRectangle.h := 116;
// візуалізувати текстуру
SDL_RenderCopy(sdlRenderer, sdlTexture1, @sdlRectangle, nil);
SDL_RenderCopy(sdlRenderer, sdlTexture1, nil, @sdlRectangle);
// візуалізувати у вікні протягом 2 секунд
SDL_RenderPresent(sdlRenderer);
SDL_Delay(2000);
// очистити пам'ять
SDL_DestroyTexture(sdlTexture1);
SDL_FreeSurface(sdlSurface1);
SDL_DestroyRenderer(sdlRenderer);
SDL_DestroyWindow (sdlWindow1);
//завершити SDL2
SDL_Quit;
end.
В результаті ми отримаємо ось це.
Для порівняння, ось оригінальне зображення розміром 200 × 200 пікселів.
Давайте розберемо код.
var
sdlWindow1: PSDL_Window;
sdlRenderer: PSDL_Renderer;
sdlTexture1: PSDL_Texture;
sdlRectangle: TSDL_Rect;
В розділі var ми оголошуємо відомі змінні для вікна, візуалізатора та текстури. Також у нас є нова змінна типу TSDL_Rect.
// підготувати прямокутник
sdlRectangle.x := 12;
sdlRectangle.y := 25;
sdlRectangle.w := 178;
sdlRectangle.h := 116;
Після ініціалізації SDL2 та налаштування вікна та візуалізатора, як вже відомо, прямокутник отримує деякі значення. Він просто включає слова “Free Pascal meets SDL” оригінальному зображенні (див. вище).
Масштабування в SDL2
Якість масштабування
Безпосередньо перед створенням поверхні та текстури в коді є цей рядок.
// встановити якість масштабування
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 'nearest');
Це встановлює якість візуалізації. Його потрібно встановити перед створенням текстури. Функція SDL_SetHint(назва підказки, значення підказки) не є спеціальною функцією для встановлення якості масштабування, але тут ми використовуємо її саме для цього. Можливі значення
- nearest або 0
- вибірка найближчого пікселя
- вибірка найближчого пікселя
- linear або 1
- лінійна фільтрація
- підтримується в OpenGL і Direct3D
- лінійна фільтрація
- best або 2
- анізотропна фільтрація
- підтримується в Direct3D.
Всі значення повинні бути встановлені як рядкові значення, тобто „nearest” або „0”. Ось порівняння найближчого та лінійного фільтрів.
Анізотропний фільтр не робить для мене нічого, навіть якщо я використовував Direct3D.
Масштабування за допомогою прямокутників
// візуалізація текстури
SDL_RenderCopy(sdlRenderer, sdlTexture1, @sdlRectangle, nil);
SDL_RenderCopy(sdlRenderer, sdlTexture1, nil, @sdlRectangle);
У цей момент відбувається магія, яка веде до результуючого зображення. До речі, оскільки функція SDL_RenderCopy() вимагає, щоб аргументи прямокутника були типу PSDL_Rect, ми використовуємо тут оператор @ (оператор покажчика).
SDL_RenderCopy(sdlRenderer, sdlTexture1, @sdlRectangle, nil);
Це означає: скопіюйте область, описану “sdlRectangle”, з джерела (тут “sdlTexture1”) на всю область (через nil) пункту призначення, отже, вікно.
Оскільки вікно має ширину та висоту по 500 пікселів, вихідний прямокутник лише ширину 178 пікселів та висоту 116 пікселів, SDL2 автоматично масштабує зображення, щоб воно відповідало більшим (або меншим) розмірам пункту призначення.
SDL_RenderCopy(sdlRenderer, sdlTexture1, nil, @sdlRectangle);
Це означає: скопіюйте ціле джерело (через значення nil) у область, описану “sdlRectangle”. Джерелом є зображення розміром 200 × 200 пікселів, яке потрібно стиснути до прямокутника 178 × 116 пікселів у положенні (12/25). Це саме те, що Ви бачите на отриманому зображенні (вгорі), де ціле зображення стискається в цю область.
Рух зображень (спрайтів)
Хоча це не охоплено безпосередньо в наведеному прикладі коду, Ви отримуєте уявлення про те, як працює рух. Для кожного кадру Ви налаштовуєте (x/y) координати прямокутника для пункту призначення, щоб спрайт рухався.
Після очищення пам'яті програма завершується.
Немає коментарів:
Дописати коментар