Понедельник, 11.08.2025, 13:08
Personal dimanche13 site
Главная | Регистрация | Вход Приветствую Вас Гость | RSS
Категории каталога
Мои статьи [22]
BlitzMax [17]
раздел содержит статьи относящиеся к языку программирования BlitzMax
SDL [9]
раздел содержит статьи на тему SDL
Code::Blocks [3]
в этом разделе рассказывается как прикрутить движок к интегрированной среде разработки(IDE) Code::Blocks
Форма входа
Поиск
Друзья сайта
Главная » Статьи » SDL

Основы SDL (часть№1 инициализация)
Введение.
Довольно теплые отзывы о статье по установке SDL на CodeBlocks, сподвигли меня на написание еще нескольких статей по этому движку. Конечно, я не буду приводить головокружительные алгоритмы и описывать все хитрости программирования. Я лишь дам самые простые, но тема не менее полезные(надеюсь ;) ) первые шаги для тех, кто только начинает изучать СДЛ. В сети миллионы туториалов, одни слишком просты и размыты, другие никак не связанные между собой статьи, третьи просто изложены на непонятном языке(даже не на английском), что кстати, говорит о международной признательности движка)))  Туториалов на русском я почти не видел... Странно, неужели в нашей стране он менее популярен чем в других? (поправьте, если я не прав) Тем не менее, я задался целью, открыть двери в увлекательный мир программирования на СДЛ. 
 
Задачи.
 Когда я только начинал программировать, для меня очень важным было увидеть результат выполенеия программы на экране. Но кроме вывода в командную строку, я тогда ничего делать не умел. Для вывода же окна в Виндовз или какой-нибудь даже самой паршивой картинки, надо было написать столько кода, что мне становилось скучно при одной тока мысли об этом... Наверное и вы испытывали подобные чуства. Хочется творить, программировать свои миры, узнав все азы программирования от указателей до ООП, хочется уже сделать что-то такое, что можно показать друзьям или родителям, это должно быть воистину большим, чем командная строка, пусть даже и выводящая результаты расчетов каких-нибудь функций Эйлера. Согласитесь, смешно тыкать пальцем в монитор и гордо заявлять друзьям, что вот эта вот строчка на черном фоне- результат вашей гениальнейшей программы. Так вот для меня СДЛ это в первую очередь средство отображения моей информации на мониторе, окна, заголовка окна, картинок в нем и всего остального. Причем делающее это, очень простым путем.  Вот так неспешно мы подошли к первой нашей задаче на сегодня. Вывести наше окно на экран. Конечно я надеюсь, что вы уже настроили вашу ИДЕ для работы с СДЛ. Если-нет, то могу вам посоветовать обратиться к моей статье с разъяснениями об этом. Либо поищите еще где-нибудь в интернете )))
А для самых нетерпеливых, расскажу как это сделать в 4 шага.
1) скачиваем последнюю версию SDL с офф.сайта 
 
2) распаковываем и кидаем папку "SDL-1.2.13" прямо в папку c Code::Blocks
3) запускаем Code::Blocks и жмыхаем создать новый проект (Create a new project )
4) указываем папки где лежат include & lib SDL. Все. 
О том как подключить SDL к "Visual Studio .NET" можно прочитать здесь: http://pgdc.purdue.org/sdltutorial/sdl_setup.html (осторожно траффик! много картинок, но зато всё понятно)
Инициализация. 
Все примеры начинаются с подключения хидеров(заголовочных файлов) для СДЛ, коде-генератор сформировал мне вот такие хидеры:
#ifdef __cplusplus
  #include <cstdlib>
#else
  #include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif

Я думаю, вы в курсе и вам не надо напоминать, что выполнение программы на C/C++ начинается с функции main(). Здесь (прямо в main() ) мы и будем писать весь код. Но для начала нам надо инициализировать SDL. (Большинство SDL функций и констант этой библиотеки, начинаются с символов SDL_. ) Делается это просто: для этого есть функция int SDL_Init(Uint32 flags), которая принимает в себе параметр, который указывает какую подсистему инициализировать в СДЛ.
 
SDL_Init( SDL_INIT_VIDEO );
 
Вот так инициализируется видео подсистема SDL. Чтобы, например, инициализировать аудио подсистему надо сделать так:
 
SDL_Init( SDL_INIT_AUDIO );
 
Чтобы не инициализировать каждую из подсистем в отдельности можно их объединять символом (| - or) вот так:
 
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO );
 
Всего есть несколько подсистем, которые нам пригодится знать :
 
SDL_INIT_TIMER -> The timer subsystem  -> подсистема таймера
SDL_INIT_AUDIO -> The audio subsystem -> аудио
SDL_INIT_VIDEO -> The video subsystem -> видео
SDL_INIT_CDROM -> The cdrom subsystem -> сидюк
SDL_INIT_JOYSTICK -> The joystick subsystem -> джойстик, вестимо.
 
Если вам необходимо инициализировать все системы, а перечислять через "|" их лень, то для этого существует константа SDL_INIT_EVERYTHING :
 
SDL_Init( SDL_INIT_EVERYTHING );
 
Эту функцию надо обязательно выполнять до всех остальных и это очевидно, по всем правилам очередности, чтоб движок работал правильно, его надо сначала инициализировать.
Теперь стоит сказать, о том что функция SDL_Init() возвращает. Если выбранная/ые подсистемы инициализировались правильно, то функция вернет 0, а в противном случае функция возвращает -1. Это надо отслеживать, ведь если инициализировать SDL не удалось, то и не имеет смысла продолжать дальнейшее выполнение программы. Тогда здравый смысл нам диктует обернуть SDL_Init в конструкцию if, которая проверяет результат ее выполнения:
 
   if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
    {
        printf("SDL_Init failed: %s\n", SDL_GetError() ); return false;
    }
 
Если все-таки что-то пошло не так и мы получили -1, то неплохо бы узнать что же  произошло. Для этого существует функция SDL_GetError(), которая возвращает описание ошибки в текстовой форме. 
Обратная инициализации функция -это деинициализация. Выполняется она функцией SDL_Quit(void) она сбрасывает все инициализированные подсистемы и освобождает ресурсы занятые ими. Она должна быть выполнена по завершении работы с SDL. Итак наша первая программа может выглядеть вот так:
 
int main() {
     
   if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
    {
        printf("SDL_Init failed: %s\n", SDL_GetError() ); return false;
    }
    
    SDL_Quit();
    return 0;
}
 
пусть она и выполняется, но не дает, то чего мы запланировали, а именно вывести окно на экран. Тогда идем дальше. Ну, то есть бежим. 
 
Окно.
Теперь нам надо вывести на экран окошко. Инициализация окна делается немногим сложнее, чем инициализация самого движка, но не расстраивайся заранее. Вот функция, которая поможет "отцу русской демократии":
 
SDL_Surface *SDL_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags);
 
Ничего страшного в ней нет, кроме того что она возвращает указатель на SDL_Surface. С этим мы разберемся потом, а пока посмотрим, что означают параметры функции. Очевидно, это ширина и высота будующего окна, бит_на_пиксель или глубина цвета по другому, и последний параметр флаги. Первые 3 параметра могут быть нулями. В таком случае размеры окна и глубина цвета, будут выбраны такими же, как и в текущем видеорежиме. На флагах остановимся подробнее:
 
SDL_SWSURFACE - Создание видео поверхности в системной памяти.
SDL_HWSURFACE - Создание видео поверхности в видео памяти.
SDL_ASYNCBLIT - Позволяет использовать асинхронное обновление поверхности дисплея.
SDL_RESIZABLE - Экранная поверхность может изменять размеры
SDL_HWACCEL - Поверхность использует аппаратное ускорение
SDL_ANYFORMAT - Обычно, если видео поверхность в запросе bits-per-pixel(bbp) не доступна, SDL будет эмулировать одну из теневых поверхностей. SDL_HWPALETTE - Дает SDL доступ к эксклюзивной палитре. С этим флагом вы можете не всегда получить цвета которые запросили с SDL_SetColors или SDL_SetPalette.
SDL_DOUBLEBUF - Включает хардварную двойную буферизацию; только при правильном SDL_HWSURFACE. Вызывая SDL_Flip будет отображать содержимое буфера и обновлять экран. Вся прорисовка будет вестись на не отображонной поверхности в этот момент. Если двойная буфферизация будет не возможна, тогда SDL_Flip будет выполнятся как SDL_UpdateRect на всем экране.
SDL_FULLSCREEN - SDL попытается использовать полноэкранный режим. Если хардварное разрешение не возможно(по некоторым причинам), следующее более высокое разрешение будет использовано для отображения окна центрировано на черном фоне.
SDL_OPENGL - Создает контекст представления OpenGL.
SDL_OPENGLBLIT - Эта опция оставлена только для совместимости и может быть удалена в новых версиях. Ее использование не рекомендуется.
 
Эти флаги так же могут совмещаться знаком "|". Так например, чтобы создать полноэкранное окно с двойной буфферизацией, текущей глубиной цвета и размером 800 на 600 пикселей надо вызвать эту функцию так:
 
SDL_SetVideoMode( 800, 600, 0, SDL_FULLSCREEN | SDL_DOUBLEBUF );
 
Но полноэкранное приложение мы пока делать не будем, для начала нам хватит и оконного режима. К тому же этот режим нам понадобится, для того чтобы в дальнейшем узнать как изменять название окна (App Title). Но для начала, я хочу поговорить о поверхностях(surface). В СДЛ полно сурфейсов. Да куда ни плюнь всё сурфейс. Вы можете рисовать на сурфейсах, а можете рисовать один сурфес на другой. Так картинка - это тот же сурфейс, вы можете рисовать в ней, а можете отобразить эту картинку(сурфейс) на экране, ведь экран тоже сурфейс.
Грубо говоря и не вдаваясь в подробности, можно сказать, что функция установки видео режима SDL_SetVideoMode() как раз таки и возвращает экранную поверхность, на которую будут рисоваться другие поверхности. Поэтому все видео объекты выводятся на специально созданную для них поверхность. По окончании работы с поверхностью, они должны быть удалены/освобождены функцией:
 
 SDL_FreeSurface(my_surface);
 
Это относится ко всем сурфейсам, кроме экранной поверхности созданной функцией SDL_SetVideoMode(). Эта поверхность освобождается функцией SDL_Quit().
Итак мы узнали что функция задания видеорежима SDL_SetVideoMode() создает окно с нужными параметрами и возвращает нам экранную поверхность, на которой мы позже будем рисовать. Сначала объявим ее:
SDL_Surface* screen = NULL; // сначала ее нет
Инициализируем окно:
screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_DOUBLEBUF); 
Если инициализация прошла, то поверхность не будет равна NULL. И для начала необходимо убедиться что поверхность создана.
if ( screen == NULL )

  printf("Unable to set 640x480 video: %s\n", SDL_GetError());return false;
}
Отлично теперь все готово. А нееет, погодите не всё. Если мы сейчас запустим нашу программу, то она сразу закроется после выполнения, да так быстро что мы даже не сможем разглядеть с таким трудом созданное окошко. Что же делать? Пока мы не изучали события(events) в СДЛ. Они бы нам очень помогли, но я думаю это оставить на другой раз. Потому как есть более простой способ посмотреть на наше окно. Это функция SDL_Delay() она приостановит выполнение программы на несколько секунд, чтобы мы все успели увидеть. Передается ей время в миллисекундах, в 1 секунде - 1000 миллисекунд. Так если хотите задержку в 1 секунду, то передаем 1000, в 3 секунды - 3000. Нам хватит 3 секунд на любование результатами нашей первой программой. 
Итак код:
int main ( )
{

  SDL_Surface* screen = NULL; // сначала ее нет

  if(SDL_Init( SDL_INIT_EVERYTHING ) == -1) // инициализируем видео-подсистему
  {
  printf("SDL_Init failed: %s\n", SDL_GetError() ); return false;
  }

   // инициализируем экранную поверхность
  screen = SDL_SetVideoMode( 640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF );

  if ( screen == NULL )
  {
  printf("Unable to set 640x480 video: %s\n", SDL_GetError()); return false;
  }

  // ждем 3 секунды
  SDL_Delay(3000);

  // освобождаем ресурсы подсистем и экранную поверхность
  SDL_Quit();

  return 0;

}
Вот так незатейливо это делается))) Можно также поменять title-окна, то есть строчку SDL_app выводящуюся в заголовке окна. Делается это так же элементарно, достаточно вставить строку  
SDL_WM_SetCaption( "My first SDL application", 0 ); 
между инициализацией видео-подсистемы и инициализации поверхности экрана. Наличие в функции символов SDL_WM означает, что эта функция относится к функциям работы с окном. Их несколько:
  SDL_WM_SetCaption - Установить имя окна
  SDL_WM_GetCaption - Получить имя окна
  SDL_WM_SetIcon - Установить иконку для окна
  SDL_WM_IconifyWindow - Свернуть (минимизировать) окно
  SDL_WM_ToggleFullScreen - Переключить полноэкранный/оконный режим
  SDL_WM_GrabInput - Захватывать все события от мыши и клавиатуры

Вот что мы должны наблюдать:
Иконку окна давайте установим потом, когда узнаем как загружать картинки. 
На этом разрешите откланиться, мы выполнили, то что первоначально задумали, а именно - вывели окно СДЛ на экран. Надеюсь это было просто. Чао! 


Категория: SDL | Добавил: dimanche13 (07.03.2009)
Просмотров: 8141 | Комментарии: 6 | Рейтинг: 5.0/3 |
Всего комментариев: 4
4 Germ23  
0
Для приличия ссылку бы на оригинал оставили чтоли

3 RR  
0
Очень интересная и полезная статья статья, огромная благодарность автору)

1 J3d1  
1
Спасибо за статью. При компиляции в OC Windows избежать создания консольного окна можно если в Project>Properties>Build targets вместо Type: Console application выставить GUI application. Еще: чтобы существенно сократить размер получившегося исполняемого файла можно выставить флаг strip all symbols from binary (minimize size) [s] в Project build options. Это "освободит" выходной файл от отладочной информации.

2 dimanche13  
0
о, спасибо J3d1 очень полезная информация. smile

Имя *:
Email *:
Код *:
Copyright MyCorp © 2025