Частина 6 - Завантаження та візуалізація растрового файлу

Завантаження файлів растрових зображень (файлів BMP) природно підтримується SDL2. Спосіб буде наступним (зі слідуючої схеми).

Creative Commons License Це зображення від https://www.freepascal-meets-sdl.net ліцензоване під Creative Commons Attribution 4.0 International License.
Схема завантаження та візуалізації растрового файлу в SDL2.

Почнемо зліва на схемі. Найпростіший спосіб отримати файл растрового зображення (BMP) для гри чи програми, готовим до використання, - створити його в програмі для малювання. Або скористайтеся прикладом растрового зображення “fpsdl.bmp”, який ми використовували в коді.

Free Pascal meets SDL sample image bmp format
Creative Commons License Це зображення від https://www.freepascal-meets-sdl.net ліцензоване під Creative Commons Attribution 4.0 International License.
Оригінальне зображення розміром 200×200 пікселів.

Файл растрового зображення зберігається на Вашому жорсткому диску і може бути завантаженим функцією SDL_LoadBMP в поверхню SDL2. Ця поверхня SDL2 тоді перетворюється в текстуру SDL2 функцією SDL_CreateTextureFromSurface (чия назва сама пояснює що вона робить). І нарешті ця текстура візуалізується викликом SDL_RenderPresent, цю функцію ми вже знаємо.

А тепер давайте подивимося, як це робиться в коді.

program SDL_LoadingRenderingBMP;

uses SDL2;

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlSurface1: PSDL_Surface;
  sdlTexture1: PSDL_Texture;

begin

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

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

  // створення поверхні з файлу
  sdlSurface1 := SDL_LoadBMP('fpsdl.bmp');
  if sdlSurface1 = nil then
    Halt;

  // створення текстури з поверхні
  sdlTexture1 := SDL_CreateTextureFromSurface(sdlRenderer, sdlSurface1);
  if sdlTexture1 = nil then
    Halt;

  // візуалізація текстури
  if SDL_RenderCopy(sdlRenderer, sdlTexture1, nil, nil) <> 0 then
    Halt;

  // візуалізація в вікно на 2 секунди
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(2000);

  // очистка пам'яті
  SDL_DestroyTexture(sdlTexture1);
  SDL_FreeSurface(sdlSurface1);
  SDL_DestroyRenderer(sdlRenderer);
  SDL_DestroyWindow (sdlWindow1);

  //закриваємо SDL2
  SDL_Quit;

end.                                                                   

Результат такий:

Result screenshot for chapter 4
Creative Commons License Це зображення від https://www.freepascal-meets-sdl.net ліцензовано під Creative Commons Attribution 4.0 International License.
Це результат виконання коду.

Розділ Var,

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlSurface1: PSDL_Surface;
  sdlTexture1: PSDL_Texture;

містить дві нових зміних, названі “sdlSurface1” та “sdlTexture1” вказівних типів PSDL_Surface та PSDL_Texture, відповідно.

Після налаштування SDL2, вікна та візуалізатора, як нам вже відомо, ми знаходимо наступне.

Крок 1: Завантаження растрового файла в поверхню SDL2


  // створення поверхні з файла
  sdlSurface1 := SDL_LoadBMP('fpsdl.bmp');
  if sdlSurface1 = nil then
    Halt;

SDL_LoadBMP(назва файла растрового зображення) робить те, що ви очікуєте, завантажує файл зображення та генерує з нього поверхню SDL2. Однак, якщо Ви просто вказали ім'я файлу, мається на увазі, що файл знаходиться в тій самій папці, що і виконувана програма. За бажанням Ви також можете вказати повний шлях до файлу, наприклад у Windows щось на зразок «C:\MyImages\fpsdl.bmp». Функція оголошена як

 SDL_LoadBMP(_file: PAnsiChar): PSDL_Surface

і повертає nil у випадку помилки, напр. якщо файл не знайдено.

Крок 2: Створення текстури SDL2 з поверхні SDL2

Наступним кроком є ​​отримання текстури SDL2. Це досягається наступним чином.

  // створення текстури з поверхні
  sdlTexture1 := SDL_CreateTextureFromSurface(sdlRenderer, sdlSurface1);
  if sdlTexture1 = nil then
    Halt;

Використовується функція SDL_CreateTextureFromSurface(візуалізатор, поверхня).

SDL_CreateTextureFromSurface(renderer: PSDL_Renderer; surface: PSDL_Surface): PSDL_Texture

Вона просто робить те, що Ви очікуєте, і перетворює поверхню SDL2 у текстуру SDL2 за допомогою даного візуалізатора.

Крок 3: Підготовка текстури SDL2 до візуалізації

Перш ніж реально відтворити текстуру, нам потрібно скопіювати її до цілі візуалізації (наше вікно) за допомогою SDL_RenderCopy(візуалізатор, текстура, прямокутник джерела (текстура), прямокутник призначення (ціль візуалізації)).

// візуалізація текстури
  if SDL_RenderCopy(sdlRenderer, sdlTexture1, nil, nil) <> 0 then
    Halt;

Отже, текстура копіюється до цілі візуалізації (а це вікно). Перший аргумент nil означає, що ми хочемо скопіювати цілий прямокутник. Другий nil означає, що ми хочемо скопіювати у повні розміри цілі візуалізації. Давайте детальніше розглянемо функцію.

SDL_RenderCopy(renderer: PSDL_Renderer; texture: PSDL_Texture; srcrect: PSDL_Rect; dstrect: PSDL_Rect): SInt32

Як Ви тут бачите, можна використовувати аргументи типу PSDL_Rect, які в основному описують прямокутники.

Step 4: Візуалізація

І нарешті, візуалізація здійснюється викликом вже відомої функції SDL_RenderPresent().

Крок 5: Знищення поверхонь і текстур

Відразу після цього важливо звільнити пам'ять, виділену під поверхню та текстуру функціями SDL_FreeSurface(surface) та SDL_DestroyTexture(texture).

  //очистка пам'яті
  SDL_DestroyTexture(sdlTexture1);
  SDL_FreeSurface(sdlSurface1);
  SDL_DestroyRenderer(sdlRenderer);
  SDL_DestroyWindow (sdlWindow1);

Тепер ви знаєте, як завантажити та відтворити bmp-файл у вікно. 🙂

Примітка: НІКОЛИ не поєднуйте SDL_CreateTextureFromSurface() та SDL_LoadIMG!

Ніколи не поєднуйте крок 1 та крок 2 щоб уникнути оголошення та звільнення поверхні. НІКОЛИ НЕ РОБІТЬ цього:

sdlTexture1 := SDL_CreateTextureFromSurface(sdlRenderer, SDL_LoadBMP('fpsdl.bmp'));

Це виконається без будь-яких проблем, хоча SDL_CreateTextureFromSurface() не звільняє поверхню, створену SDL_LoadBMP(). у Вас не буде змінної, щоб звільнити цю поверхню. Це створює витік пам'яті

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

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

Опублікувати коментар