Переклад виконано з дозволу автора оригінального матеріалу. Усі пропозиції та зауваження щодо перекладу прохання залишати в коментарях на сторінці матеріалу.
SDL2 дозволяє використовувати в'юпорти.Погляньте на наступний знімок гри SDL2 (Битва за Веснот).
![](https://www.freepascal-meets-sdl.net/wp-content/uploads/bow-example.jpg)
Це класична ситуація використання в'юпортів. Екран гри чітко розділений на три виділені області. Головний екран - це велика частина зліва з горами та замками. Тоді в правому верхньому кутку є мінікарта. І під мінікартою огляд статистики. Ці області та відповідні в'юпорти виділено на наступному знімку екрану.
![](https://www.freepascal-meets-sdl.net/wp-content/uploads/bow-example-viewports.jpg)
Перевагою в'юпортів є те, що кожен з них поводиться як власне вікно, тому якщо Ви будете малювати за правою границею в'юпорта 1 на скріншоті нижче, текстура буде просто обрізана і не буде перекриватись у в'юпортах 2 або 3.
![SDL2 window and viewport coordinates diagram](https://www.freepascal-meets-sdl.net/wp-content/uploads/diagr3.png)
Давайте подивимось на код.
program SDL2_Viewport;
uses SDL2;
const
Viewport1: TSDL_Rect = (x: 0; y: 0; w: 400; h: 500);
Viewport2: TSDL_Rect = (x: 400; y: 0; w: 100; h: 300);
Viewport3: TSDL_Rect = (x: 400; y: 300; w: 100; h: 200);
BlackDot: TSDL_Rect = (x: 10; y: 10; w: 3; h: 3);
var
sdlWindow1: PSDL_Window;
sdlRenderer: PSDL_Renderer;
begin
//ініціалізація підсистеми відео
if SDL_Init(SDL_INIT_VIDEO) < 0 then Halt;
SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN, @sdlWindow1, @sdlRenderer);
if (sdlWindow1 = nil) or (sdlRenderer = nil) then Halt;
//заповнити кожен в'юпорт кольором фону і намалювати в ньому чорну точку
SDL_RenderSetViewport(sdlRenderer, @Viewport1);
SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, nil);
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, @BlackDot);
SDL_RenderSetViewport(sdlRenderer, @Viewport2);
SDL_SetRenderDrawColor(sdlRenderer, 255, 255, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, nil);
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, @BlackDot);
SDL_RenderSetViewport(sdlRenderer, @Viewport3);
SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, nil);
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, @BlackDot);
//візуалізувати у вікно на 2 секунди
SDL_RenderPresent(sdlRenderer);
SDL_Delay(2000);
//очистити пам'ять
SDL_DestroyRenderer(sdlRenderer);
SDL_DestroyWindow (sdlWindow1);
//вимкнути підсистему відео
SDL_Quit;
end.
Результат буде виглядати так:
![](https://www.freepascal-meets-sdl.net/wp-content/uploads/sdl2_viewports.jpg)
![Creative Commons License](https://i.creativecommons.org/l/by/4.0/80x15.png)
Три в'юпорти з різним кольором фонуі чорною точкою в верхньому лівому кутку.
Спочатку ми заадаємо декілька прямокутників SDL2
const
Viewport1: TSDL_Rect = (x: 0; y: 0; w: 400; h: 500);
Viewport2: TSDL_Rect = (x: 400; y: 0; w: 100; h: 300);
Viewport3: TSDL_Rect = (x: 400; y: 300; w: 100; h: 200);
BlackDot: TSDL_Rect = (x: 10; y: 10; w: 3; h: 3);
“Viewport1” представляє червоний в'юпорт (зліва), “Viewport2” - жовтий (зверху справа) і “Viewport3” - зелений (знизу-справа) в'юпорти на результуючому зображенні.
Зверніть увагу, як ми просто готуємо один прямокутник “BlackDot” для чорної точки розміром 3 × 3 пікселі в розташуванні (10/10).
Після налаштування SDL2, візуалізатора та вікна, як вже нам відомо, ми починаємо налаштовувати перший (червоний, лівий) в'юпорт.
//заповнити кожен в'юпорт кольором фону і намалювати в ньому чорну точку
SDL_RenderSetViewport(sdlRenderer, @Viewport1);
SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, nil);
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(sdlRenderer, @BlackDot);
Це так просто. Використовуйте функцію SDL_RenderSetViewport(візуалізатор, вказівник на прямокутник) для встановлення в'юпорта. Ця функція повертає 0 при успіху або -1 при невдачі.
SDL_RenderSetViewport(renderer: PSDL_Renderer; const rect: PSDL_Rect)
Після того, як ми встановили в'юпорт, ми встановлюємо колір малювання функцією SDL_SetRenderDrawColor(візуалізатор, червоний, зелений, синій, альфа) в червоний (255/0/0/непрозорий). Тоді ми використовуємо SDL_RenderFillRect(візуалізатор, вказівник на прямокутник) щоб заповнити весь в'юпорт не вказуючи прямокутника (nil). Обидві функції відомі з попередніх частин.
Тоді колір встановлюється в чорний і крихітні прямокутники 3×3 пікселя малюються за розміщенням (10/10).
Ця процедура повторюється для двох інших в'юпортів. Знову зверніть увагу, як ми використовуємо цей же прямокутник для чорної точки і де це показано на результуючому зображенні. Чорна точка завжди малюється в позиції (10/10) відносно розміщення відповідного в'юпорта!
Застосовується як загальне правило:
Координати завжди відносно до поточного в'юпорта.
Що ж, решта коду, що залишився, не надає нічого нового, просто візуалізації на 2 секунди і трохи процедур очистки.
Давайте завершимо з кількома корисними зауваженнями.
Для в'юпортів не треба використовувати SDL_RenderClear!
Не використовуйте SDL_RenderClear(візуалізатор). Ця функція ігнорує в'юпорти і очищає ціле вікно кольором малювання.
Скидання в'юпорта
Скидання викоонуєится просто викликом SDL_RenderSetViewport(візуалізатор, nil)як і слід було очікувати.
Немає коментарів:
Дописати коментар