Графика с использованием SDL. Урок 1. Начало работы с SDL. |
- Statistics
- Participants
- Translate into Russian
- Translation result
- Translation complete.
Приветствую Вас на первом уроке серии "Графика с использованием SDL".
Подключаем SDL в Dev-C++
Первое, что необходимо сделать - это скачать несколько файлов. Они находятся в ZIP-архиве sdlDevCPP-1.2.4.zip. Распакуйте этот архив в директорию Dev-C++ так, чтобы файлы из папок lib и include оказались в соответствующих папках. Например, в моей системе Dev-C++ установлен в директорию c:\Dev-C++. Таким образом после распаковки архива файлы libSDL.a, libSDL.la, libSDLmain.a и SDL.dll появились в каталоге c:\Dev-C++\lib, а множество файлов с расширением .h - в каталоге c:\Dev-C++\include\SDL.
Теперь нужно создать новый консольный проект (console project). В его свойствах (их можно найти в меню Project) в поле "Further object files or linker options:" нужно вписать "-lmingw32 -lSDLmain -lSDL" (без кавычек) и нажать кнопку ОК.
Одно замечание: в Dev-C++ при подключенных к проекту библиотеках SDL функция printf(...) выводит текст не на экран, а в файл stdout.txt.
Вот и все, что касается Dev-C++.
Подключаем SDL в Microsoft Visual C++ 6.0
Для применения SDL в MSVC6 нужно скачать файл SDL-devel-1.2.4-VC6.zip (свежую его версию можно найти на сайте www.libsdl.org). В нём находятся две важные папки - include и lib. Извлеките содержимое папки lib в папку lib вашего MSVC6. В моей системе это C:\Program Files\Microsoft Visual Studio\VC98\Lib. Теперь создайте новую папку с именем SDL в директории include MSVC6 и скопируйте в нее (на моей системе это C:\Program Files\Microsoft Visual Studio\VC98\Include\SDL), а также в саму директорию include (C:\Program Files\Microsoft Visual Studio\VC98\Include) все .h файлы из каталога include ZIP-архива.
Теперь создайте новый пустой проект: выберите "WIN32 Application" (приложение WIN32) и установите флажок напротив пункта 'an empty project' (пустой проект). После этого нужно создать .cpp файл для Вашего проекта. Нажмите File->New и выберите "c++ source file", назовите его main.cpp. В настройках проекта (пункт меню Project->Settings) перейдите на вкладку LINK и в конец списка "Object/library modules" допишите через пробел "sdl.lib sdlmain.lib" (без кавычек). На вкладке C/C++ в выпадающем списке "Use run-time library" выберите пункт "Multithreaded DLL". Вот и всё, ваш MSVC6 готов к работе :).
SDL.dll
Для работы с SDL необходим файл SDL.dll (он включен в архивы для Dev-C++ и MSVC6). Чтобы запускать программы, написанные с использованием библиотеки SDL, следует разместить этот файл в папку %WINDIR%\system (Win95,98,ME) или %WINDIR%\system32 (где %WINDIR% - папка, в которую установлен Windows, обычно это c:\windows), либо можно скопировать его в ту же папку, в которой находится исполняемый файл программы. Если вы хотите поделиться своей SDL-программой с друзьями, вы должны также предоставить им файл SDL.dll. Так что скопируйте этот файл из c:\Dev-C++\lib в c:\windows\system или c:\windows\system32 (для Windows NT, 2000, XP) и распространяйте его вместе с исполняемыми файлами.
Начинаем работу с SDL
Итак, у вас все готово для работы. Единственное, что осталось - это включить заголовочный файл SDL/SDL.h в первых строках программы следующим образом:
#include <SDL/SDL.h>
Инициализирует SDL функция SDL_Init(). SDL_Init() в случае успешного выполнения возвращает значение меньше нуля. Функция принимает всего один параметр: то что нужно инициализировать. Чтобы провести инициализировать изображение, нужно передать в функцию аргумент SDL_INIT_VIDEOб, звук - SDL_INIT_AUDIO. Чтобы инициализировать и изображение, и звук нужно передать в качестве аргумента SDL_INIT_VIDEO|SDL_INIT_AUDIO. Таким образом можно передавать в эту функцию много других значений, разделяя их знаком |. Вот список параметров, которые можно передавать:
SDL_INIT_TIMER
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_JOYSTICK
SDL_INIT_NOPARACHUTE
SDL_INIT_EVENTTHREAD
SDL_INIT_EVERYTHING
Так, если мы хотим инициализировать одновременно видео и аудио, нужно ввести:
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) <0 )
{
printf("Инициализация SDL невозможна: %s\n", SDL_GetError());
return 1;
}
Если возникнет ошибка, функция SDL_GetError() возвратит строку с её описанием.
В конце выполнения программы необходимо отключить режим SDL. Для этого есть функция SDL_Quit(). Она очистит все следы выполнения программы. Если вы её не вызовите, могут возникнуть странные ошибки. Чтобы вызвать SDL_Quit() авоматически используйте:
atexit(SDL_Quit);
Таким образом вам не нужно вызывать SDL_Quit() после каждого return[nr]; в функции main().
В SDL всё является поверхностью (surface). Вы можете рисовать на поверхности, даже рисовать поверхностью по поверхности. Экран также является поверхностью. Поверхность в нашей программе это указатель на структуру SDL_Surface. Чтобы получить поверхность экрана, выполните следующее:
SDL_Surface *screen;
Надеюсь, вы видели когда-нибудь в вашей жизни игры, в которых требовалось установить разрешение экрана. Если нет - БОЛЬШЕ ИГРАЙТЕ В ИГРЫ :). Если вы будете использовать поверхность экрана (запомните, экран - это всего лишь имя указателя на структуру SDL_Surface), как поверхность, на которой можно рисовать, используйте функцию SDL_SetVideoMode();
screen = SDL_SetVideoMode(640, 480, 32,
SDL_HWSURFACE|SDL_DOUBLEBUF);
Первые три параметра: ширина (width), высота (height) и количество бит на пиксел (BPP). Если ввести 0 в поле BPP, то SDL автоматически выберет оптимальное количество бит. Четвертый параметр используется для задания специальных флагов. Для рисования на экране следует (почти всегда) устанавливать флаг SDL_HWSURFACE (или SDL_SWSURFACE):
* SDL_SWSURFACE - создаёт видео поверность в системной памяти
* SDL_HWSURFACE - создаёт видео поверность в видео памяти
* SDL_ASYNCBLIT - включает использование асинхронных обновлений показываемых поверхностей. Приводит к замедлению работы на однопроцессорных машинах, но может увеличить скорость на SMP системах.
* SDL_ANYFORMAT - обычно если не доступна видео поверхность запрошенного бит на пиксель (bits-per-pixel - bpp), SDL проэмулирует bbp теневой поверхностью. Использование SDL_ANYFORMAT предотвращает это и заставляет 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_GL_SetAttribute.
* SDL_OPENGLBLIT - аналогичен предыдущему, но позволяет использовать blit-операции. Экранная поверхность (2D) может иметь альфа-канал, по этой причине необходимо использовать SDL_UpdateRects для обновления экранной поверхности.
* SDL_RESIZABLE - создает окно с изменяемыми размерами. Если размеры окна изменяются пользователем, вызывается событие SDL_VIDEORESIZE. Для нового размера можно вызвать функцию SDL_SetVideoMode.
* SDL_NOFRAME - производится попытка создать окно без заголовка или без рамок. Полноэкранный режим автоматически включает данный флаг.
Моя рекомендация: сначала задайте SDL_HWSURFACE|SDL_DOUBLEBUF и, в случае ошибки, попытайтесь снова, задав флаг SDL_SWSURFACE.
В случае успешного выполнения функция SDL_SetVideoMode возвращает указатель на SDL_Surface, в ином случае - NULL. Для проверки на ошибки используйте следующий блок кода:
if ( screen == NULL )
{
printf("Невозможно установить режим 640x480: %s\n", SDL_GetError());
return 1;
}
Это все, что требуется знать про инициализацию SDL. Теперь можно начинать рисовать. Но для начала следует узнать про некоторые типы данных, предоставляемых SDL:
Uint8 - эквивалент типа unsigned char (8-битные беззнаковые целые числа)
Uint16 - 16-битные (2-байтные) беззнаковые целые числа
Uint32 - 32-битные (4-байтные) беззнаковые целые числа
Uint64 - 64-битные (8-байтные) беззнаковые целые числа
Sint8 - эквивалент типа signed char (8-битные целые числа со знаком)
Sint16 - 16-битные (2-байтные) целые числа со знаком
Sint32 - 32-битные (4-байтные) целые числа со знаком
Sint64 - 64-битные (8-байтные) целые числа со знаком
Следует также уточнить: иногда при получении ошибок во время инициализации нет необходимости полностью завершать работу. Например, если инициализация SDL_INIT_VIDEO проходит без ошибок, а SDL_INIT_AUDIO нет, то можно продолжать выполнение программы, но без звука. Для проверки (например) успешности инициализации звука используйте функцию SDL_WasInit():
Uint32 init = SDL_WasInit(SDL_INIT_AUDIO);
if(init & SDL_INIT_AUDIO)
{
sound = 1; // Аудио инициализировано, можно использовать звук
} else {
sound = 0; // Аудио не инициализировано, будем работать без звука
}
Этот кусок кода следует разместить сразу после кода инициализации:
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) <0 )
{
printf("Инициализация SDL не возможна: %s\n", SDL_GetError());
return 1;
}
размещайте его в своих программах (в данных уроках этот код применяться не будет для упрощения).
Попиксельное рисование на первый взгляд не очень просто, но если есть функция, реализующая данную задачу, то нет ничего проще. Используемая мною функция для рисования пикселей взята из введения в SDL (находится на www.libsdl.org). Выглядит она так:
ПРИМЕЧАНИЕ: понимать как это все работает не обязательно, достаточно просто знать, что оно работает.
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;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2: // Возможно 15-bpp или 16-bpp
{
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
Original (English): GFX with SDL. Lesson 1: Getting started with SDL
