| Как компилировать | Содержание | Урок 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.