Всем привет! Решил, вот, посмотреть на SDL 2, но на русском ничего толкового не нашел. Решил написать свое, питаясь вдохновением отсюда.

Установку SDL 2 я пропущу, а начну сразу с написания программ, итак:

Ваше первое окно


начнем с подключения SDL 2.

#include <SDL2/SDL.h>

Здесь же объявим несколько глобальных переменных.

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

Далее открываем всем знакомую функцию main.

int main (int argc, char ** args) {
    
    if( SDL_Init( SDL_INIT_EVERYTHING ) != 0 )
    {
        return 1;
    }

    SDL_Surface* screen_surface = NULL;

    SDL_Window* window = NULL;

Давайте немного разберем код. В main из командной строки принимаются параметры командной строки, их нужно обязательно принять. Далее мы инициализируем SDL 2 функцией SDL_Init(). Мы передали в нее SDL_INIT_EVERITHING, что означает, что мы инициализируем все модули SDL (видео, аудио и т. д.). Есть еще несколько флагов для SDL_Init:

Flags
SDL_INIT_TIMER — подключение таймера;
SDL_INIT_AUDIO — подключение аудио;
SDL_INIT_VIDEO — подключение видео, автоматически подключаются события;
SDL_INIT_JOYSTICK — подключение управления джойстиком;
SDL_INIT_HAPTIC — тактильная подсистема (не знаю что это, если честно);
SDL_INIT_GAMECONTROLER — подключает управление, автоматически подключается джойстик;
SDL_INIT_EVENTS — подключает обработку событий;
SDL_INIT_EVERYTHING — подключает всё, выше перечисленное;
SDL_INIT_NOPARACHUTE — проверка на совместимость.

Далее создаем окно функцией SDL_CreateWindow(). Если что-то пошло не так, как задумывалось, возвращаем 1.

    window = SDL_CreateWindow("Hello, SDL 2!",SDL_WINDOWPOS_UNDEFINED, 
    SDL_WINDOWPOS_UNDEFINED, SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT, 
    SDL_WINDOW_SHOWN);
    
    if (window == NULL) {
        return 1;
    }

Функция SDL_CreateWindow() принимает значения имени окна, позиции окна по OX, позиции окна по OY, ширину окна, высоту окна и флаги. Сейчас мы обойдемся флагом SDL_WINDOW_SHOWN.

Есть и другие флаги для создания окна.

Flags
SDL_WINDOW_FULLSCREEN — открывает окно в полноэкранном режиме, изменяет разрешение рабочего стола;
SDL_WINDOW_FULLSCREEN_DESCKTOP — открывает окно в полноэкранном режиме с разрешение данного рабочего стола;
SDL_WINDOW_OPENGL — окно с поддержкой OpenGL;
SDL_WINDOW_HIDDEN — окно скрыто;
SDL_WINDOW_BORDERLESS — окно без рамки;
SDL_WINDOW_RESIZABLE — можно изменять размер окна;
SDL_WINDOW_MINIMIZED — окно свернуто;
SDL_WINDOW_MAXIMIZED — окно развернуто;

Если сейчас скомпилировать и запустить программу, то мы увидим окно, размером 640x480, залитое белым цветом, которое через мгновение закрывается. Чудесно! Чтобы немного полюбоваться этим чудом, можем написать SDL_Delay(2000). Оно заставит программу зависнуть на 2 секунды.

Просто окно это, конечно же, хорошо, но рисовать в нем было бы еще круче, согласны? Для этого создадим поверхность, на которой будем все рисовать, т. к. непосредственно в окне рисовать как-то некрасиво, что ли.

   screen_surface = SDL_GetWindowSurface(window);

    SDL_FillRect(screen_surface, NULL, SDL_MapRGB(screen_surface->format, 0, 255, 0));

    SDL_UpdateWindowSurface(window);

Сначала мы получаем поверхность окна функцией SDL_GetWindowSurface(). Она сделана для того, чтобы не надо было указывать размеры поверхности, её формат, а сразу получить готовую поверхность. Так же эту поверхность не надо отрисовывать в окне — она сама всё сделает.

Потом мы используем SDL_FillRect(), чтобы зарисовать нашу поверхность зеленым. Мы написали SDL_MapRGB, сказав тем самым программе, что мы воспользуемся RGB(Red Green Blue) для задания цвета.

И в конце нам следует обновить окно функцией SDL_UpdateWindowSurface(), чтобы в нем отобразилось то, что мы ему сказали.

На данном этапе, при запуске, программа отобразит окно, залитое ярко-зеленым цветом, которое не будет закрываться в течении 2-х секунд.

После завершения программы нам нужно очистить ОЗУ от ненужных файлов, закрыть окно, в целом, обусловить корректное завершение программы. В этом нам помогут специально подготовленные функции.

    SDL_DestroyWindow(window);

    SDL_Quit();

Функция SDL_DestroyWindow() закрывает окно, а функция SDL_Quit() разинициализирует все модули, подключенные ранее функцией SDL_Init().

Ну что же, урок №1 подошел к концу, надеюсь, всё было понятно. Вот такой код у меня вышел в конце:

#include <SDL2/SDL.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main (int argc, char ** args) {
    
    if( SDL_Init( SDL_INIT_EVERYTHING ) != 0 )
    {
        return 1;
    }

    SDL_Surface* screen_surface = NULL;

    SDL_Window* window = NULL;

    window = SDL_CreateWindow("Hello, SDL 2!",SDL_WINDOWPOS_UNDEFINED, 
    SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, 
    SDL_WINDOW_SHOWN);
    
    if (window == NULL) {
        return 1;
    }

    screen_surface = SDL_GetWindowSurface(window);

    SDL_FillRect(screen_surface, NULL, SDL_MapRGB( screen_surface->format, 0, 255, 0));

    SDL_UpdateWindowSurface(window);

    SDL_Delay(2000);

    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;
};

Всем удачи!

Комментарии (8)


  1. poxvuibr
    27.05.2019 17:57
    +1

    начнем с подключения SDL 2

    Вот ссылка на то как подключить: <SDL.h> или <SDL2/SDL.h> . То ли у вас в туториале неправильно, то ли информация из ссылки протухла.


    Далее мы инициализируем SDL 2 функцией SDL_Init(). Мы передали в нее SDL_INIT_EVERITHING

    И тут, если что-то пошло не так, неплохо бы печатать что, а не молча возвращать 1. Вот как по этой ссылке — Функция для правильного выяснения что пошло не так с SDL


  1. Siemargl
    27.05.2019 18:17

    Было бы неплохо указывать целевую платформу примеров. Ну и жиденько содержания.


    1. poxvuibr
      27.05.2019 18:41

      Ну так то SDL кроссплатформенная библиотека, такое должно везде собираться.


  1. akryukov
    27.05.2019 18:44
    +1

    Установку SDL 2 я пропущу

    А зря. Именно установка, настройка окружения и все вот эти предварительные ласки вызывают больше всего проблем.


    Желательно в начале еще написать, какую программу мы вообще делаем, и добавить картинку.


    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED
    принимает значения имени окна, позиции окна по OX, позиции окна по OY

    Что именно значит UNDEFINED?
    Уточните, как именно расположена координатная сетка на экране. У нее есть специфика по сравнению с обычным изображением математической координатной плоскости (на листе бумаги).


    Для этого создадим поверхность, на которой будем все рисовать, т. к. непосредственно в окне рисовать как-то некрасиво, что ли.

    Насколько я понимаю, функция SDL_GetWindowSurface не создает новой поверхности, а получает ссылку на поверхность окна. Так что далее мы рисуем непосредственно в окне.


  1. TheGodfather
    27.05.2019 20:54

    То ли у меня профдеформация уже, то ли это уже вторая статья, где автор не обременяет себя расшифровкой непонятной аббревиатуры. Точнее, понятной, конечно — Secure Development Lifecycle, только вот в статье что-то вообще не о том.


    1. jmdorian
      28.05.2019 08:31

      Возможно, потому что эта статья о Simple DirectMedia Layer?


  1. jmdorian
    28.05.2019 08:33

    Копируйте названия констант из кода, пожалуйста. SDL_INIT_EVERITHING режет глаз.
    А по статье — чуть больше бы хотелось информации. На каком этапе сейчас SDL? Стоит ли она того чтобы начинать ей пользоваться?


    1. playermet
      28.05.2019 15:32

      Зависит от ваших требований. Я бы взял GLFW, он более современный и активней разрабатывается, но у него более узкий спектр фич (окна, мониторы, контексты, ввод-вывод, и пара мелочей), и нет поддержки мобильных платформ (но вроде есть отдельный форк для них). В свою очередь SDL умеет в примитивы, звук, текстуры, шрифты, и т.д, но на базовом уровне.