Заняття №1 Налаштування та робота з вікнами
Заняття №1
01_hello_SDL.cpp
#if defined(__linux)
#include <SDL2/SDL.h>
#elif defined(WIN32)
#include <SDL.h>
#endif
#include <iostream>Буду старатися використовувати розумний менеджмент пам’яті. Тому підключаємо необхідні для цього заголовки.
#include <memory>Створимо структуру яка при вихоід з області видимоті автоматично викличе SDL_Quit().
Це обов’язково. А для початку треба ініціалізувати все, що нам потрібно функцією
SDL_Init(Uint32), яка проініціалізує потрібні нам системи.
SDL_INIT_TIMER | timer subsystem |
SDL_INIT_AUDIO | audio subsystem |
SDL_INIT_VIDEO | video subsystem; automatically initializes the events subsystem |
SDL_INIT_JOYSTICK | joystick subsystem; automatically initializes the events subsystem |
SDL_INIT_HAPTIC | haptic (force feedback) subsystem |
SDL_INIT_GAMECONTROLLER | controller subsystem; automatically initializes the joystick subsystem |
SDL_INIT_EVENTS | events subsystem |
SDL_INIT_EVERYTHING | all of the above subsystems |
Можна ініціалізувати всі потрібні системи одразу, або згодом при необхідності SDL_InitSubSystem(Uint32) ініціалізувати конкретну систему, або зупинити SDL_QuitSubSystem(Uint32) вже не потрібну систему. При виклику SDL_Quit() зупиняються всі системи.
struct SDL_Guard {
SDL_Guard(Uint32 flags) {
if (0 > SDL_Init(flags))
throw std::runtime_error("SDL could not initialize! SDL_Error:" +
std::string(SDL_GetError()));
}
~SDL_Guard() { SDL_Quit(); }
};Для вікна ми використаємо розумний вказівник який розглянемо трохи пізніше.
using UniqueWindow = std::unique_ptr<SDL_Window, void (*)(SDL_Window*)>;Оголосимо main функцію для різних операційних систем
#if defined(_WIN32)
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
#elif defined(__APPLE__)
int main(int argc, char** argv)
#elif defined(__linux)
int main(int argc, char** argv, char** env)
#else
int main(int argc, char** argv)
#endif
try {Нарешті тут ініціалізуємо всі системи у “розумні структурі”
SDL_Guard sdl_guart(SDL_INIT_EVERYTHING);
const int WINDOW_WIDTH{680}, WINDOWS_HEIGHT{480};Створюємо вікно функцією SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags). Перший параметр це заголовок (назва) вікна і є собою c-string параметром. Інші параметри вказують на позицію та розміри вікна.
| - | - |
|---|---|
| - | - |
| - | - |
| - | - |
| - | - |
|---|---|
| SDL_WINDOW_FULLSCREEN | fullscreen window |
| SDL_WINDOW_OPENGL | window usable with OpenGL context |
| SDL_WINDOW_SHOWN | window is visible |
| SDL_WINDOW_HIDDEN | window is not visible |
| SDL_WINDOW_BORDERLESS | no window decoration |
| SDL_WINDOW_RESIZABLE | window can be resized |
| SDL_WINDOW_MINIMIZED | window is minimized |
| SDL_WINDOW_MAXIMIZED | window is maximized |
| SDL_WINDOW_MOUSE_GRABBED | window has grabbed mouse input |
| SDL_WINDOW_INPUT_FOCUS | window has input focus |
| SDL_WINDOW_MOUSE_FOCUS | window has mouse focus |
| SDL_WINDOW_FULLSCREEN_DESKTOP | |
| SDL_WINDOW_FOREIGN | window not created by SDL |
| SDL_WINDOW_ALLOW_HIGHDPI | window should be created in high-DPI mode if supported. On macOS NSHighResolutionCapable must be set true in the application’s Info.plist for this to have any effect. |
| SDL_WINDOW_MOUSE_CAPTURE | window has mouse captured (unrelated to MOUSE_GRABBED) |
| SDL_WINDOW_ALWAYS_ON_TOP | window should always be above others |
| SDL_WINDOW_SKIP_TASKBAR | window should not be added to the taskbar |
| SDL_WINDOW_UTILITY | window should be treated as a utility window |
| SDL_WINDOW_TOOLTIP | window should be treated as a tooltip |
| SDL_WINDOW_POPUP_MENU | window should be treated as a popup menu |
| SDL_WINDOW_KEYBOARD_GRABBED | window has grabbed keyboard input |
| SDL_WINDOW_VULKAN | window usable for Vulkan surface |
| SDL_WINDOW_METAL | window usable for Metal view |
| SDL_WINDOW_INPUT_GRABBED | equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility |
UniqueWindow the_window{
SDL_CreateWindow("Example", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOWS_HEIGHT,
SDL_WINDOW_SHOWN),Завжди створене вікно по завершеннютреба знищувати SDL_DestroyWindow(SDL_Window*)
SDL_DestroyWindow};Переред початком роботи з вікном потрібно перевірити чи вдалося його створити.
if (!the_window)
throw std::runtime_error("Error creating window: " +
std::string(SDL_GetError()));Отримуємо вкзівник на поверхню по якій бужемо малювати
SDL_Surface* winSurface{SDL_GetWindowSurface(the_window.get())};Перевіряємо чи вдалося отримати вказіник на поверхню
if (!winSurface)
throw std::runtime_error("Error getting surface: " +
std::string(SDL_GetError()));
SDL_FillRect(winSurface, NULL,
SDL_MapRGB(winSurface->format, 0xFF, 0xFF, 0xFF));
SDL_Event e;
bool quit{false};
do {
SDL_UpdateWindowSurface(the_window.get());
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
quit = true;
break;
default:
break;
}
}
} while (!quit);
return EXIT_SUCCESS;
}
catch (const std::exception& e) {
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (...) {
std::cout << "Something wrong\n";
return -EXIT_FAILURE;
}CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(Lesson01)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} SDL2)Збирання проекту
cmake -B build -G="Unix Makefiles"
cmake --build ./build -j$(nproc)
./Lesson01