Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Гущин_SDL.pdf
Скачиваний:
168
Добавлен:
17.03.2018
Размер:
1.09 Mб
Скачать

return 1;

}

Draw_FillEllipse(screen, 320, 240, 300, 200, SDL_MapRGB(screen->format, 128, 128, 128));

SDL_Flip(screen); while(SDL_WaitEvent(&event)){

if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE))

{

SDL_Quit(); return 0;

}

}

SDL_Quit(); return 2;

}

4.Из архива SDL-1.2.15-devel-1.2.15-mingw32.tar.gz копируем файл SDL-1.2.15-devel-1.2.15- mingw32.tar\SDL-1.2.15\bin\SDL.dll в каталог с созданным проектом (C:\SDLdrawtest).

5.Из каталога C:\SDL_draw-1.2.13\Dev-Cpp\ копируем файл SDL_draw.dll в каталог с созданным проектом (C:\SDLdrawtest).

6.В параметрах проекта (меню «Проект/Параметры проекта», комбинация клавиш Alt+P), на вкладке «Параметры», добавляем в столбец «Компоновщик» строку:

-lmingw32 -lSDLmain –lSDL –lSDL_draw

7. Собираем и запускаем проект по клавише F9, и он успешно запускается: на черном фоне отображается серый закрашенный эллипс. Выход из программы – по нажатию клавиши Esc или щелчку по системной кнопке закрытия окна в его заголовке.

Создание проектов, использующих библиотеки SDL-1.2.15, SDL_draw-1.2.13 и SDL_ttf-

2.0.11с динамическим связыванием:

1.Сам проект создается аналогично вышеприведенным примерам, в папку с проектом

помещаются все требуемые файлы динамических библиотек и используемых шрифтов (см. примеры).

2. В параметрах проекта (меню «Проект/Параметры проекта», комбинация клавиш Alt+P), на вкладке «Параметры», в столбец «Компоновщик» добавляется строка, подключающая все три библиотеки:

-lmingw32 -lSDLmain –lSDL –lSDL_draw –lSDL_ttf

3. Подключение и инициализация библиотеки SDL

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

#include "SDL.h"

Данный заголовочный файл включает в себя все остальные заголовочные файлы библиотеки SDL, поэтому подключения других не требуется. Заголовочные файлы всех рассматриваемых библиотек содержат для большинства функций достаточно подробные комментарии на английском языке, в том числе явное указание на то, какие функции являются «публичными» – для использования пользователями библиотеки, а какие лишь для ее реализации.

При использовании среды разработки Dev-Cpp 4.9.9.2 следует также обратить внимание на то, что использование библиотеки SDL приводит к переопределению стандартного потока вывода stdout и стандартного потока ошибок stderr на одноименные файлы stdout и stderr в каталоге с исполняемым файлом программы. Также обращаем внимание на необходимость определения функ-ции main в соответствии с сигнатурой, используемой в библиотеке SDL, а именно следующим образом:

int main(int argc, char *argv[])

13

{

/* тело функции main*/

}

Непосредственно перед использованием функций библиотеки SDL необходимо инициализировать соответствующие ее подсистемы с помощью функции SDL_Init:

extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags);

Важным является тип аргумента flags – целое число без знака, представленное 32 битами (4 байта). Для переносимости между платформами и различными компиляторами он объявлен как самостоятельный тип с помощью директив препроцессора, обес-печивающих условную трансляцию. С помощью данного парамет-ра указывается, какие именно подсистемы библиотеки требуется инициализировать и какие глобальные режимы использовать. Для этого объявлен ряд флагов, которые можно комбинировать с помощью операции побитового ИЛИ. Например, для ини-

циализации подсистемы работы с дисплеем служит флаг SDL_INIT_VIDEO, для работы с

таймером –

 

 

SDL_INIT_TIMER,

а для работы с подсистемой обработки звука – SDL_INIT_AUDIO. Для инициализации всех

подсистем

(вместо

комбинации

соот-

ветствующих флагов) служит специальный флаг SDL_INIT_EVERYTHING. Поскольку каждый

отдельный флаг

устанавливает лишь

один бит в параметре

flags, а значение

SDL_INIT_EVERYTHING объявлено как 0x0000FFFF, то его можно рассматривать как указание на инициализацию всех доступных подсистем SDL.

Результат, возвращаемый функцией SDL_Init, указывает на успешность инициализации, если он равен нулю, или на ошибку инициализации в противном случае. При ошибке можно получить описание ошибки (также на английском языке) с помощью функции SDL_GetError:

extern DECLSPEC char * SDLCALL SDL_GetError(void);

Такое объявление позволяет использовать ее для формиро-вания сообщений о произошедших ошибках. Например, для вывода в поток stderr с помощью функции fprintf:

/* объявление переменных */

if (SDL_Init(SDL_INIT_VIDEO)) /* инициализация SDL */

{ /* При ошибке формируем сообщение и выходим */ fprintf(stderr,"Ошибка в SDL_Init: %s\n",SDL_GetError()); return 1;

}

Если инициализация была успешно выполнена, при последую-щем завершении работы программы необходимо вызвать функцию SDL_Quit (не имеющую параметров и не возвращающую никаких значений). Для гарантии вызова данной функции при любом завершении программы желательно установить ее как функцию, автоматически вызываемую при выходе из программы:

/* Cразу после вышеприведенного фрагмента. Оператор выполняется при безошибочной инициализации SDL*/ atexit(SDL_Quit);

Отображение графической информации в библиотеке SDL основано на понятии «поверхность». Поверхность логически представляет собой прямоугольную матрицу, состоящую из пик-селей определенного формата, на которой можно рисовать, изме-няя состояние пикселей. Набор возможных состояний пикселя определяется его форматом. Все пиксели одной поверхности име-ют одинаковый формат. Поэтому его также можно считать «фор-матом поверхности». Возможно и более сложное использование поверхностей, например для формирования изображения нало-жением изображений разных поверхностей. В программе каждая поверхность представляется указателем на структуру SDL_Surface. Данный указатель возвращают функции, создающие поверхности как объекты программы, и впоследствии они используются для указания поверхности при всех операциях с ними. Основное окно программы, возможно полноэкранное,

14

также является поверх-ностью, однако создающейся специальной функцией установки видеорежима SDL_SetVideoMode:

extern DECLSPEC SDL_Surface * SDLCALL SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags);

Она возвращает либо корректный указатель на структуру SDL_Surface, соответствующую поверхности окна программы (или всего экрана), либо NULL в случае ошибки. Это позволяет контролировать возникновение ошибок при установке видео-режима в простейшем случае опять же с помощью функции SDL_GetError:

/* в соответствующем месте объявляем указатель на поверхность: */

SDL_Surface *screen; /* ... */

/* После инициализации собственно SDL и установки atexit(SDL_Quit): */ screen=SDL_SetVideoMode(800,600,32,SDL_ANYFORMAT);

if (!screen)

{

fprintf(stderr,"SDL mode failed: %s\n",SDL_GetError()); return 1;

}

Приведенный фрагмент также иллюстрирует параметры функции SDL_SetVideoMode. Первый параметр задает ширину окна или разрешение по горизонтали для полноэкранного режима, второй

– высоту окна или разрешение по вертикали. Третий пара-метр задает глубину цвета – количество бит для представления цвета одного пикселя (BPP – bit-per-pixel). Если в качестве значе-ния третьего параметра указать ноль, то будет выбрана оптималь-ная глубина цвета для указанного разрешения (т.е. обеспечи-вающая наибольшее количество цветов при наименьших затратах на дополнительные программные преобразования, что определя-ется возможностями сочетания используемой в конкретном устройстве аппаратной части и ее драйверов). Четвертый параметр предназначен для указания специальных флагов задания видео-режима (часть из них применима и к другим поверхностям для рисования), в частности для указания на полноэкранный видео-режим, возможность изменения размера окна пользователем (по умолчанию отключено), определение расположения поверхности в системной памяти или видеопамяти, возможности асинхронного обновления. В простых случаях при использовании современных видеоадаптеров достаточно указать флаг SDL_ANYFORMAT, заставляющий инициализировать поверхность, даже если запрошенная глубина цвета не поддерживается: практически любой современный видеоадаптер для персональных компьютеров, включая встраиваемые или интегрированные с процессором, поддерживают разрешение до 1920 на 1080 пикселей с глубиной цвета 32 бита на пиксель.

Основным отличием поверхности, создаваемой функцией SDL_SetVideoMode, является соответствие каждому ее пикселю единственного пикселя окна программы (его рабочей области) или всего дисплея (при использовании полноэкранного режима). При вызове специальных функций обновления, рассматриваемых далее, это позволяет однозначно изменять состояние видимых на дисплее пикселей в соответствии с состоянием пикселей данной поверхности. Обратное неверно, поскольку, например, при много-оконном пользовательском интерфейсе часть окна программы может быть перекрыта окном другой программы и при его отобра-жении будет утрачена информация, оказавшаяся перекрытой другим окном. Но соответствующая окну поверхность остается неизменной, что позволяет после смещения перекрывшего окна другой программы полностью восстановить изображение в окне программы на дисплее повторным вызовом функции обновления.

Библиотека SDL предусматривает также ряд функций, позво-ляющих проверить поддерживаемые аппаратной частью конкрет-ного компьютера видеорежимы, список видеорежимов или полу-чить параметры для «оптимального» видеорежима. Это функции

SDL_GetVideoInfo, SDL_VideoModeOK, SDL_ListModes, которые рекомендуется рассмотреть самостоятельно.

После инициализации видеорежима имеет смысл установить заголовок окна, соответствующий создаваемой программе. Для этого служит функция SDL_WM_SetCaption:

extern DECLSPEC void SDLCALL SDL_WM_SetCaption (const char *title, const char *icon);

15

Первый параметр – указатель на начало последовательности байтов, заканчивающейся нулем и представляющей текст нового заголовка окна в кодировке utf-8, второй параметр – аналогичный указатель для используемого в некоторых операционных системах текста пиктограммы окна. Если второй параметр равен NULL, то текст пиктограммы не изменяется. Для поддерживаемых ОС семейства Microsoft Windows второй параметр игнорируется. Однако для предотвращения нежелательных эффектов его следует задавать равным NULL. Существует обратная функция SDL_WM_GetCaption, позволяющая получить текущий заголовок окна и текст пиктограммы окна. Фактическое поведение данных функций может зависеть от конкретной операционной системы и режима работы приложения. Например, понятие «заголовок окна» отсутствует в полноэкранном режиме или при задании соответ-ствующих параметров функции SDL_SetVideoMode.

Непосредственное рисование на поверхности путем изменения состояния пикселей – достаточно трудоемкий процесс: требуется вычислить представление каждого компонента цвета для соответ-ствующей данной поверхности глубины цвета и положение битовых последовательностей, отвечающих за соответствующие компоненты конкретного пикселя для их изменения. Приведем лишь пример функции, обеспечивающей установку на поверх-ности screen для пикселя с координатами (x, y) цвета, заданного своими компонентами (R, G, B). Данная функция основана на примерах из введения в SDL (www.libsdl.org). По аналогии с Uint32, типы Uint8 и Uint16 соответствуют целым числам без знака, представляемым одним или двумя байтами. Функция SDL_MapRGB возвращает число, соответствующее ближайшему представимому в формате данной поверхности цвету, заданному своими компонентами. Формат поверхности (формат пикселей поверхности) можно получить с помощью компонента format структуры SDL_Surface. Этот компонент представляет собой указатель на структуру типа SDL_PixelFormat, описывающую формат пикселя поверхности, объем памяти, занимаемой одним пикселем, используемую для преобразования цветов (при необходимости) палитру. Возвращенное функцией SDL_MapRGB число может быть непосредственно записано в область памяти, отвечающую за цвет конкретного пикселя. Система координат в окне или на экране – ось X слева направо, ось Y сверху вниз, верхний левый угол имеет координаты (0,0), нижний правый – на единицу меньше ширины и высоты окна (разрешения экрана). Определение функции DrawPixel будет выглядеть следующим образом:

void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B)

{

Uint32 color = SDL_MapRGB(screen->format, R, G, B); switch (screen->format->BytesPerPixel)

{

case 1: // Используем 8-bpp (бит на пиксель)

{

Uint8 *bufp = (Uint8 *)screen->pixels +

/* pixels – указатель на начало области данных, описывающей состояние пикселей поверхности screen */

y*screen->pitch + x; /* pitch – количество байтов, занимаемых данными

о пикселях одной строки */

*bufp = color;

}

 

break;

 

case 2: // Возможно 15-bpp или 16-bpp

{

Uint16 *bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;

/* Поскольку (Uint16 *)screen->pixels возвращает указатель на целое число, занимающее в памяти 2 байта, при вычислении смещения делим длину строки в байтах

на 2 */

*bufp = color;

}

break;

case 3: // Медленный режим 24-bpp, обычно не применяется

{

Uint8 *bufp = (Uint8 *)screen->pixels +

16

Соседние файлы в предмете Программирование