Лабораторная работа №10
Графика и анимация. Игры.
БИБЛИОТЕКА ГРАФИКИ
Использование графической библиотеки многошаговый процесс, включающий:
-определение типа видеоадаптера;
-установка режима работы видеоадаптера;
-инициализация графической системы в заданном режиме;
Только после этого можно воспользоваться библиотечными подпрограммами для построения основных графических примитивов и вывода текста с использованием различных шрифтов.
В состав библиотеки входит набор так называемых BGI - драйверов, каждый из которых является обработчиком прерывания 10Н и выполняет установку и обновление ряда внешних переменных, которые могут изменяться как подпрограммами операционной системы, так и подпрограммами библиотеки графики Турбо С.
ИНИЦИАЛИЗАЦИЯ И ЗАКРЫТИЕ СИСТЕМЫ ГРАФИКИ
Состоит в загрузке BGI - драйвера, соответствующего адаптеру или режиму, установке начальных значений внешних переменных, выборе шрифта и т. Д. Поддерживаемые библиотекой графические режимы задаются символьными константами, описанными в файле graphics.h в перечислимом типе gtaphics_modes. Некоторые из этих констант:
Константа Разрешение Палитра Режим
CGAC0 320x200 0 4,5
CGAC1 1
CGAC2 2
CGAC3 3
CGAHI 640X200 6
EGALO 640X200 16цветов 0EH
EGAHI 640X350 16цветов 10H
VGALO 640X200 16цветов 0EH
VGAMED 640X350 16цветов 10H
VGAHI 640X480 16цветов 12H
Инициализацию графики выполняет функция
void far initgraph(int far *graphdriver,int far*
graphmode,char far *pathtodriver) - инициализирует графическую систему, загружая BGI - драйвер graphdriver, устанавливает режим graphmode, используя путь доступа к драйверу, заданный строкой pathtodriver.
BGI - драйвер может тоже задаваться символьной константой из набора (приведены некоторые):
Константа Значение Описание
DETECT 0 Автоматическое определение типа драйвера
CGA 1
EGA 3
VGA 9
Если нашей программе больше не нужна графическая библиотека, следует обратиться к функции
void far closegraph(void) - освобождает память под драйверами графики, шрифтами и пр., восстанавливает предыдущий режим адаптера.
Скелет программы, выполняющей всю необходимую подготовку для использования графической библиотеки:
#include graphics.h
int main(void)
{
int graph_driver,graph_mode,graph_error_code;
graph_driver=DETECT;
initgraph(&graph_driver, &graph_mode, c: \\bc\\bgi);
graph_error_code=graphresult();
if(graph_error_code! =grOk){/*Обработка ошибки*/
return 255; }
.
closegraph();
}
Наиболее защищенный способ использования функции инициализации требует предварительного уточнения типа адаптера - для этого либо вызывается initgraph() с драйвером, определенным через DETECT, либо явно вызывается функция:
void far detectgraph(int far *graphdriver,int far * graphmode)
Обработка ошибок
После любого обращения к detectgraph() или initgraph() желательно вызвать функцию
int far graphresult(void), возвращающую код ошибки, а его текстовую расшифровку можно получить с помощью функции
char *far grapherrormsg(int errorcode)
ОПРЕДЕЛЕНИЕ И УСТАНОВКА ГРАФИЧЕСКОГО РЕЖИМА.
После инициализации графической системы можно установить другой, не превышающий максимального, режим видеоадаптера и выбрать цвета для пикселов.
Установку режима выполняет функция setgraphmode().
Целая группа функций - getgraphmode(), getmaxmode(), getmodename(), getmoderange() - упрощает работу по определению текущего установленного видеорежима;
две функции - getmaxx(), getmaxy() - позволяют определить высоту и ширину экрана в пикселах для текущего режима;
функция restorecrtmode() возвращает адаптер в текстовый режим.
Синтаксис и параметры этих функций всегда можно уточнить через help - систему IDE Borland C++.
УПРАВЛЕНИЕ ЦВЕТАМИ И ПАЛИТРАМИ.
CGA - адаптеры в режимах 4,5 320х200 аппаратно поддерживают задание цвета фона и выбор одной из 4-х предопределенных палитр. Код цвета пиксела 0 соответствует цвету фона и может быть выбран равным любому из 16 возможных цветов:
Константа Значение Цвет
BLACK 0 ЧЕРНЫЙ
BLUE 1 СИНИЙ
GREEN 2 ЗЕЛЕНЫЙ
CYAN 3 СИНЕ-ЗЕЛЕНЫЙ
RED 4 КРАСНЫЙ
MAGENTA 5 КРАСНО-СИНИЙ
BROWN 6 КОРИЧНЕВЫЙ
LIGHTGRAY 7 СВЕТЛО СЕРЫЙ
DARKGRAY 8 ТЕМНО-СЕРЫЙ
LIGHTBLUE 9 ЯРКО-СИНИЙ
LIGHTGREEN 10 ЯРКО-ЗЕЛЕНЫЙ
LIGHTCYAN 11 ЯРКИЙ СИНЕ-ЗЕЛЕНЫЙ
LIGHTRED 12 ЯРКО-КРАСНЫЙ
LIGHTMAGENTA 13 ЯРКИЙ КРАСНО-СИНИЙ
YELLOW 14 ЖЕЛТЫЙ
WHITE 15 БЕЛЫЙ
Установку кода цвета фона выполняет функция setbkcolor(), а функция getbkcolor() позволяет узнать код цвета фона в текущий момент. Выбор же палитры осуществляется по символьной константе, задающей режим работы.
У EGA, VGA - адаптеров возможности управления палитрами значительно шире - библиотека графики Турбо С тоже содержит группу функций для определения текущей и установки новой палитры EGA,VGA - адаптеров: getdefaultpalette(), gemaxcolor(), getpalette(), getpalettesize(), setallpalette(), setpalette().
УПРАВЛЕНИЕ ВИДЕОСТРАНИЦЕЙ.
Как уже отмечалось, многие адаптеры позволяют хранить в видеопамяти несколько страниц. Отображаемая в текущий момент называется видимой, а та, на которую выполняется вывод - активной. Первоначально активная и видимая страница имеют номер 0, но могут и не совпадать, в этом случае картинка формируется за кулисами. Для управления страницами в С есть 2 функции:
void far setactivepage(int page)
void far setvisualpage(int page)
ЗАДАНИЕ ЭКРАННОГО ОКНА (VIEWPORT), ОПРЕДЕЛЕНИЕ И УСТАНОВКА ГРАФИЧЕСКИХ КООРДИНАТ.
Графическое окно может иметь отличающиеся от других участков экрана цвета фона и пикселов, маску заполнения и другие характеристики. Для описания окна используется функция
void far setviewport(int left,int top,int right,int bottom,int clip)
Получить текущие характеристики окна можно через обращение к
void far getviewsettings(struct viewporttype far *viewport),
которая заполнит поля структурной переменной.
В графическом окне определены относительные координаты, измеряемые в пикселах относительно левого верхнего угла окна. Текущие координаты доступны через функции getx(),gety(), а установить нужные координаты можно функциями moveto() и moverel().
В Borland C++ есть возможность встроить в .EXE - файл программы необходимые BGI - драйверы. Для этого с помощью утилиты BGIOBJ.EXE (при большом количестве драйверов - с ключом /F) файл драйвера преобразуется в .OBJ - файл, который компонуется с программой после регистрации с помощью функций:
int registerbgidriver(void(*driver)(void))
int far registerfarbgidriver(void far *driver)
Пример: registerfarbgidriver(EGAVGA_driver)
ВЫВОД ТЕКСТА.
Во-первых, вывод текста можно осуществить всеми функциями стандартного вывода - при этом будет задействована функция АН=9 прерывания 10Н со всеми вытекающими последствиями, которые обсуждались ранее.
Библиотека графики позволяет выводить текст на экран различными шрифтами двух типов - битовым и сегментированным (или векторным). Для битового шрифта используется таблица знакогенератора 8х
8. Сегментированные шрифты задают правило рисования каждого символа, описываемого как совокупность отрезков прямых линий или сегментов. Программа может задать масштаб для каждого символа.
В Турбо С доступны 4 сегментированных шрифта: Triplex, Small, SansSerif, Gothic. Файлы сегментированных шрифтов с расширением .CHR, как и .BGI - драйверы, загружаются как оверлеи во время исполнения программы. Выводить в графике текст можно слева направо и снизу вверх, масштаб задается по отношению к знакоместу шрифта 8х8, а для сегментированных шрифтов - и в относительных единицах масштаба по вертикали и по горизонтали. Кроме того, выводимые строки могут по разному выравниваться - влево и вверх, влево и вниз и т. П. Относительно текущей точки отсчета. Поведение графической системы при выводе текста характеризуется набором внутренних переменных, значения которых доступны через функцию:
void gettextsettings(struct textsettingstype far *texttypeinfo), заполняющую поля структурной переменной по шаблону textsettingstype
Интерпретация отдельных полей этой структуры приводится в описании функции:
void settextstyle(int font, int direction, int charsize)
Доступные шрифты задаются символьными константами:
Константа Значение Файл шрифта
DEFAULT_FONT 0 -
TRIPLEX_FONT 1 TRIP.CHR
SMALL_FONT 2 SMAL.CHR
SANS_SERIF_FONT 3 SANS.CHR
GOTHIC_FONT 4 GOTH.CHR
Направление может задаваться HORIZ_DIR, VERT_DIR. Функция:
void far setusercharsize(int multx, int divx, int multy,int divy)
позволяет установить масштабы по горизонтали и вертикали раздельно значениями числителя и знаменателя.
Установленные размеры символов можно узнать через функции textheight(),textwidth().
Способ выравнивания задается функцией settextjustify(int horiz,int vert), horiz может быть LEFT_TEXT, CENTER_TEXT, RIGHT_TEXT, vert может быть BOTTOM_TEXT, CENTER_TEXT, TOP_TEXT.
Собственно вывод осуществляется функциями:
void far outtext(char far *textstring)
void far outtextxy(int x, int y, char far *textstring)
Включение .CHR-файлов в выполняемый файл выполняют аналогично драйверам после регистрации функциями
registerbgifont(),
registerfarbgifont().
Имена шрифтов при регистрации
triplex_font, triplex_font_far
small_font. small_font_far
sansserif_font, sansserif_font_far
gothic_font.gothic_font_far
Вывод графической информации. Параметры и атрибуты графического вывода.
После успешной инициализации графической системы становятся доступными функции графической библиотеки для построения основных графических примитивов: отрезков прямых, дуг, окружностей, эллипсов, прямоугольников, секторных и столбцовых диаграмм и т. д. Многие из замкнутых фигур могут быть залиты текущим цветом с использованием текущего шаблона или маски заполнения. Есть также функции для запоминания прямоугольных областей экрана и восстановления их в заданном месте. Все функции работают в пределах текущего графического окна с использованием текущего цвета пиксела, установленного функцией setcolor().
При выводе отрезков прямых можно определить такой параметр как стиль линий:
void far setlinestyle(int linestyle, unsigned upattern, int thickness)
Аргумент upattern используется только если
linestyle = = USERBIT_LINE - тогда 16 бит upattern задают маску линии.
Линия с определенным пользователем стилем может иметь толщину только в 1 пиксел.
Поддерживается ряд предопределенных стилей и можно описать собственный. Задается стиль целым числом или символьной константой:
Константа Значение Стиль
SOLID_LINE 0 Сплошная
DOTTED_LINE 1 Точечная
CENTER_LINE 2 Штрих-пунктир
DASHED_LINE 3 Штриховая
USERBIT_LINE 4 Определяется пользователем
Толщина может быть 1 или 3 пиксела.
При выводе отрезков прямых можно дополнительно задать режим вывода линий:
void far setwritemode(int mode), при этом mode может быть либо COPY_PUT (0) либо XOR_PUT (1).
Следующие параметры - это маска и стиль заполнения. Маска определяется 8-мибайтовым шаблоном и рассматривается как битовая карта 8х8, вся заполняемая область разбивается на блоки по 8х8 пикселов. Наложение маски осуществляется так: если бит в маске 1, то пиксел имеет код текущего цвета, иначе не меняется. Маска и цвет пикселов задается функцией:
void far setfillpattern(char far * upattern, int color)
По умолчанию - белый цвет и маска с единицами во всех битах. Для удобства в библиотеке предусмотрен ряд предопределенных масок в комбинации с цветами, называемую стилем заполнения и устанавливаемую функцией:
void far setfillstyle(int pattern, int color)
Константа Значение Описание
EMPTY_FILL 0 Цветом фона
SOLID_FILL 1 Текущим цветом
LINE_FILL 2 Символами –
LTSLASH_FILL 3 // нормальной толщины
SLASH_FILL 4 //удвоенной толщины
BKSLASH_FILL 5 \\
LTBKSLASH_FILL 6 \\
HATCH_FILL 7 вертикально-горизонтальная штриховка
XHATCH_FILL 8 редкая штриховка крест-накрест
INTERLEAVE_FILL 9 густая штриховка крест-накрест
WIDE_DOT_FILL 10 редкими точками
CLOSE_DOT_FILL 11 частыми точками
USER_FILL 12 определенная пользователем маска
Для коррекции неквадратности пиксела на некоторых мониторах можно воспользоваться функцией установки коэффициента сжатия:
void far setaspectratio(int far xasp, int far yasp)
ЧТЕНИЕ - ЗАПИСЬ ОТДЕЛЬНЫХ ПИКСЕЛОВ.
Для манипуляции пикселами есть 2 функции:
unsigned far getpixel(int x,int y)
void far putpixel(int x, int y, int pixelcolor )
ВЫВОД ГРАФИЧЕСКИХ ПРИМИТИВОВ
line(int x1,int y1,int x2,int y2); – линия между 2-мя точками
linerel(int dx, int dy); – линия из текущей позиции
lineto(int x, int y); – линия из текущей позиции в заданную точку.
circle(int x, int y, int r); – окружность с центром в точке x,y, и радиусом r
ellipse(int x, int y, int rx, int ry); – эллипс с центром в точке x,y, и радиусами rx и ry
fillellipse(int x, int y, int rx, int ry); – заполненный эллипс с центром в точке x,y, и радиусами rx
и ry, заполнение производится цветом и стилем установленными в setfillstyle
Задания
1. Изобразить некоторое количество (задавать с клавиатуры) цветных кругов. Цвет и радиус задаются случайно.
2. Изобразить в центре экрана квадрат, вращающийся вокруг своего центра.
Пояснение. Концы отрезков (сторон квадрата) можно задать через параметрическое уравнение окружности x=r cos t, y=r sint, t [0,2 ), r-радиус окружности.
3. Изобразить пляшущего человечка.
Пояснение. На первой видеостранице изобразить человечка в одной позиции, на второй – в другой. Меняя видимую видеостраницу с некоторой задержкой выполнения, создаем иллюзию движения.
4. Мультфильм Звездопад. Рисование одной звезды оформить в виде функции с параметрами x, y (координаты центра). Звезды появляются в случайном месте экрана и падают вниз (в исходном положении звезды фотографируются (getimage) и фотография выкладывается (putimage) на экран каждый раз на один пиксел ниже).
5. Игра Ханойская башня. Доска имеет три колышка. На первом нанизано 5 дисков убывающего вверх диаметра. Перенести диски на другой колышек в том же порядке. Диски можно перекладывать с колышка на колышек по одному. Класть больший диск на меньший нельзя.