Добрый день, сегодня я объясню основные функции: инициализацию, флаги и манипуляцию. Тут самое сложное - запомнить дефайны (define - замена неявных параметров функций и т.п. на слова).
Еще один момент, я пересел в QT Creator под линуксом. Вся разница в нашем коде будет выглядеть так:
//Linux: #include "SDL2/SDL.h" //Windows: #include <SDL2.h>
Начнем пожалуй по порядку:
int main(int argc, char* args[])
И только так, это одно из немногих ограничений, которое накладывает SDL, вы можете никогда и не использовать эти параметры. Немного полезной информации: сюда можно передавать параметры запуска. Например при вызове программы из консоли: a.exe test. Можно написать программу так, что ключ test будет для отладки, а без ключа уже обычный - рабочий запуск.
//Какое окно будет рендерится SDL_Window* window = NULL; //Поверхность окна SDL_Surface* screenSurface = NULL; //Включим SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL не смог запуститься! SDL_Error: %s\n", SDL_GetError()); }
SDL_Window* window - всего лишь указатель на окно, считайте это его именем, по которому мы будем знать что это именно оно. Пока всего лишь пустой указатель. Параметры чуть позже.
SDL_Surface* screenSurface - Поверхность. Еще точнее - некоторое 2D изображение. Можем нарисовать сами или загрузить картинкой. Опять же пока только указатель.
SDL_Init(SDL_INIT_VIDEO) - после создания окна и поверхности вызовем подсистему SDL, нельзя использовать какие-либо функции SDL без запуска SDL (Логично?). Передадим флаг SDL_INIT_VIDEO, для наших простых нужд этого будет достаточно. Если получим ошибку, то SDL_Init вернет -1, можно узнать точнее посмотрев в консоль, куда SDL_GetError() посредством строки передаст подробную информацию.
С первым куском кода вроде все просто, а если флагов будет больше?
else { //Создаем окно window = SDL_CreateWindow("Урок1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Окно не может быть создано! SDL_Error: %s\n", SDL_GetError()); } else { //Получаем поверхность screenSurface = SDL_GetWindowSurface(window); //Заполняем ее белым цветом SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); //Обновляем поверхность SDL_UpdateWindowSurface(window); //Ждем две секунды SDL_Delay(2000); } }
window = SDL_CreateWindow("Урок1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
Чуть раньше мы создали указатель на окно, теперь добавим информацию:
Параметры:
1) Имя окна
обычная последовательность символов (const char*)
2) Положения окна по оси х
int пиксель начала, SDL_WINDOWPOS_UNDEFINED - для неявного поведения, SDL_WINDOWPOS_CENTERED - по центру.
3) положение окна по оси у
Тоже самое что и для оси х.
4) ширина окна обычный int
5) высота окна обычный int
6) Дополнительные флаги:
пока ограничимся "окно видимое".
if (window == NULL) - означает, что параметры которые мы передали не записались.
screenSurface = SDL_GetWindowSurface(window);
SDL_GetWindowSurface(window) - вернет нам поверхность window, именно с ней мы и будем работать, либо NULL при ошибке.
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); тут чуть сложнее.
SDL_FillRect принимает параметры: указатель на окно, указатель на заполнитель, и флаг Uint32 формата.
по порядку: Передаем указатель на поверхность, здесь все ясно. Передаем NULL в качестве заполнителя - означает, что заполняем всю область. флаг Uint32? Unsigned INT32 (Uint32) - простая структура из 4 unsigned int, красный цвет, зеленый цвет, синий цвет, и альфа канал - прозрачность.
SDL_MapRGB - укажем формат заполнения (член screenSurface -> format) просто передадим все 3 цвета как 255, ведь цвет принимает значение от 0 до 255, в результате получим белый цвет. Альфа канал можно не трогать, по умолчанию он равен 100% (непрозрачный).
После всех манипуляций обязательно обновлять поверхность из оперативной памяти. Ведь отрисовка идет процессором или видеокартой, а изменения сейчас в оперативной памяти. SDL_UpdateWindowSurface(window);
И самая простая задержка - SDL_Delay(2000);
где один параметр - мс задержки.
Правилом хорошего тона является очистка памяти:
SDL_DestroyWindow(window); - удаляет окно с именем window.
И завершение работы SDL - SDL_Quit();
Весь код:
//подключим SDL и stdio #include "SDL2/SDL.h" #include <cstdio> //Некоторые константы нашего окна const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; int main(int argc, char* args[]) { //Какое окно будет рендерится SDL_Window* window = NULL; //Поверхность окна SDL_Surface* screenSurface = NULL; //Включим SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL не смог запуститься! SDL_Error: %s\n", SDL_GetError()); } else { //Создаем окно window = SDL_CreateWindow("Урок1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Окно не может быть создано! SDL_Error: %s\n", SDL_GetError()); } else { //Получаем поверхность screenSurface = SDL_GetWindowSurface(window); //Заполняем ее белым цветом SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); //Обновляем поверхность SDL_UpdateWindowSurface(window); //Ждем две секунды SDL_Delay(2000); } } //И удаляем из памяти окно SDL_DestroyWindow(window); //Выход из SDL SDL_Quit(); return 0; }
В результате получим вот такое окно: