Как компилировать | Содержание | Урок 2 |
И так, будем считать, что вы установили и настроили библиотеку SDL. Теперь просто подключаем файл
заголовков SDL к нашему первому проекту и начинаем работать. Делаем это вот таким вот
образом:
#include "SDL.h"
Инициализация SDL делается при помощи функции
SDL_Init()
. Эта функция возвращает значение,
меньшее нуля при неудачной инициализации и принимает всего один параметр: что инициализировать.
Например, чтобы инициализировать видео подсистему, передайте в качестве аргумента константу
SDL_INIT_VIDEO
. Чтобы инициализировать аудио подсистему, соответственно,
SDL_INIT_AUDIO
. А чтобы инициализировать сразу обе подсистемы, передавайте
SDL_INIT_VIDEO | SDL_INIT_AUDIO
. На самом деле, есть еще несколько значений аргумента
функции SDL_Init()
. Чтобы передать несколько констант, разделяйте их оператором |. Вот
несколько констант, которые можно передавать:
SDL_INIT_TIMER
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_JOYSTICK
SDL_INIT_EVERYTHING
SDL_INIT_NOPARACHUTE
SDL_INIT_EVENTTHREAD
И так, если нам надо инициализировать видео и аудио подсистемы, то делаем так:
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ){ printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } |
SDL_GetError()
возвратит строку с описанием ошибки.
При выходе из программы, использующей библиотеку SDL, вы должны обязательно использовать функцию
SDL_Quit()
. Если же вы не выполните ее, то могут произойти весьма странные весщи. Есть
изящный способ выполнять эту функцию перед выходом из программы. Делается это при помощи
atexit()
, а в качестве аргумента подставляем функцию, которую надо выполнить перед выходом из
программы:
atexit(SDL_Quit());
SDL_Surface
. Чтобы получить доступ к экрану, можно
сделать например так:
SDL_Surface *screen;
SDL_SetVideoMode()
таким вот образом:
screen = SDL_SetVideoMode(640,480,32, SDL_HWSURFACE|SDL_DOUBLEBUF);
SDL_HWSURFACE (SDL_SWSURFACE)
. Вот флаги которые можно передать функции:SDL_HWSURFACE|SDL_DOUBLEBUF
или в случае ошибки
SDL_SWSURFACE.
SDL_SetVideoMode()
возвращает указатель на структуру SDL_Surface
, а в случае ошибки
возвращает NULL. Вы обязательно должны проверять ошибки:
screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF); if ( screen == NULL ){ printf("Unable to set 640x480 video: %s\n", SDL_GetError()); exit(1); } |
SDL_WM_SetCaption("SDL Gfx Example #1","ex1"); SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"), NULL); |
Uint8 - эквивалентно unsigned char
Uint16 - 16 бит (2 байта) беззнаковое целое (unsigned int)
Uint32 - 32 бита (4 байта) unsigned int
Uint64 - 64 бита (8 байт) unsigned int
Sint8 - эквивалентно signed char
Sint16 - 16 бит (2 байта) целое со знаком (signed int)
Sint32 - 32 бита (4 байта) signed int
Sint64 - 64 бита (8 байт) signed int
SDL_WasInit()
можно проверить
произошла ли инициализация той или иной подсистемы. Вот пример кода на проверку инициализации аудио подсистемы:
Uint32 init = SDL_WasInit(SDL_INIT_AUDIO); if(init & SDL_INIT_AUDIO){ sound = 1; // Audio init successful, use sound }else{ sound = 0; // Audio init unsuccessful, don't use sound } |
/* ------------------------------------------------------ */ 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: // Assuming 8-bpp { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; *bufp = color; } break; case 2: // Probably 15-bpp or 16-bpp { Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; } break; case 3: // Slow 24-bpp mode, usually not used { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3; if(SDL_BYTEORDER == SDL_LIL_ENDIAN){ bufp[0] = color; bufp[1] = color >> 8; bufp[2] = color >> 16; }else{ bufp[2] = color; bufp[1] = color >> 8; bufp[0] = color >> 16; } } break; case 4: // Probably 32-bpp { Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = color; } break; } } |
Посмотрите на экран своего монитора очень близко (Внимание! Если делать это долго, то можно повредить
зрение!). Посмотрите на белый участок изображения. Вы видите много мелких точек: красные, зеленые и синие.
А теперь посмотрите на участок изображения другого цвета: вы видете все те же точки, но светящие с другой
яркостью. С помощью всего трех цветов (красный, зеленый, синий) вы можете составить практически любой
цвет! Эти основные цвета известны как RGB триплет. Смешивая их в разных пропорциях, получаем какой угодно
цвет, например комбинация RGB(255,255,0) кодирует желтый цвет, а RGB(255,255,255) - белый.
|
SDL_MUSTLOCK(SDL_Surface *screen)
проверяет надо ли
блокировать экран, а функции SDL_LockSurface(SDL_Surface *screen) и SDL_UnlockSurface(SDL_Surface
*screen)
соответственно блокируют и разблокируют экран. Вот пара функций, которые очень просто
реализуют сей процесс:
/* ------------------------------------------------------ */ void Slock(SDL_Surface *screen){ if ( SDL_MUSTLOCK(screen) ){ if ( SDL_LockSurface(screen) < 0 ){ return; } } } /* ------------------------------------------------------ */ void Sulock(SDL_Surface *screen){ if ( SDL_MUSTLOCK(screen) ){ SDL_UnlockSurface(screen); } } |
Slock(screen)
, чтобы заблокировать и Sulock(screen)
,
чтобы разблокировать экран.
#include <stdio.h> #include <stdlib.h> #include "SDL.h" //Код функций не показан для экономии места void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B); void Slock(SDL_Surface *screen); void Sulock(SDL_Surface *screen); /* ------------------------------------------- */ int main(int argc, char *argv[]){ if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ){ printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); SDL_Surface *screen; screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF); if ( screen == NULL ){ printf("Unable to set 640x480 video: %s\n", SDL_GetError()); exit(1); } //ТУТ КОД РИСОВАНИЯ return 0; } |
Slock(screen)
, а после него функцию Sulock(screen)
. DrawPixel()
рисует цветные точки на поверхности буфера и мы будем использовать функцию SDL_Flip
чтобы
вывести буфер на экран монитора.
Slock(screen); for(int x=0;x<640;x++){ for(int y=0;y<480;y++){ DrawPixel(screen, x,y,y/2,y/2,x/3); } } Sulock(screen); SDL_Flip(screen); |
DrawScene()
. В функции main()
создадим
главный игровой цикл. Игровой цикл (game loop) - это цикл, который работает все время, пока выполняется
программа. Как только мы выходим из этого цикла, программа завершает работу. В нашей программе главный
цикл будет выполняться, пока специальная переменная равна нулю:int done=0; while(done == 0){ //Здесь код } |
SDL_Event
. Нам всего лишь нужно создать экземпляр этой
структуры, чтобы обрабатывать события.
SDL_Event event;
while ( SDL_PollEvent(&event) ){ } |
SDL_PollEvent
мы проверяем тип события:
while ( SDL_PollEvent(&event) ){ if ( event.type == SDL_QUIT ){ done = 1; } if ( event.type == SDL_KEYDOWN ) { //Код проверки клавиш } } |
if ( event.key.keysym.sym == SDLK_ESCAPE ){ done = 1; } |
SDLK_
. Загляните в файл SDL_keysym.h, чтобы посмотреть все значения.
После проверки событий мы вызываем нашу функцию рисования DrawScene(screen)
. Вот собственно и
все! Загрузите исходный текст этого урока и тренеруйтесь.
Как компилировать | Содержание | Урок 2 |
©opyleft PLG, 2003.