Лабораторная работа № 4
Тема: Реализация палитры. Понятие видеостраниц и работа с ними.
Цель: Изучение способов описания палитры и приобретение практических навыков работы с видеостраницами.
Ход работы.
1. Включить ПЗВМ.
2. Загрузить компилятор С++.
3. Ознакомиться с правилами создания и изменения палитры.
3.1. Работа с EGA адаптером.
Наиболее простым случаем является использование палитры EGA-адаптера, где каждому из 16 цветов (значений пиксела) отводится 6 бит (по 2 на каждую из цветовых компонент). Байт цвета имеет вид: 00rgbRGB, где r, g, b, R, G, B равны 0 или 1.
Для того, чтобы для 16 логических цветов (Color) задать любой из 64 физических (ColorValue) служит функция:
void far setpalette ( int Color, int ColorValue );
Для получения текущей палитры применяют функцию:
void far getpalette ( struct palettetype far * palette );
где структура палитры (struct palettetype) описывается, как функция следующим образом:
struct palettetype
{
unsigned char size;
signed char colors [MAXCOLORS + 1];
};
Пример 1. Использование палитры для получения 4 оттенков красного цвета.
// example1.cpp
#include <conio.h>
#include <graphics.h>
#include <process.h>
#include <stdio.h>
// show 4 shades of red
main ()
{
int driver = DETECT;
int mode;
int res;
int I;
initgraph ( &driver, &mode, “” );
if ( ( res = graphresult () ) != grOk )
{
printf ( “\nGraphics error: %\n”, grapherrormsg (res);
exit (1);
}
setpalette ( 0, 0 );
setpalette (1, 32 );
setpalette (2, 4 );
setpalette (3, 36 );
bar ( 0, 0, getmaxx (), getmaxy () );
for ( I = 0; I < 4; I++ )
{
setfillstyle ( SOLID_FILL, I );
bar (120 + I*100, 75, 219 + I*100, 274 );
}
getch ();
closegraph ();
}
3.2. 16- цветный режим VGA.
Реализация палитры сложнее, т.к. помимо поддержки EGA режима, видеоадаптер дополнительно содержит 256 специальных DAC-регистов, где для каждого цвета хранится его 18 битовое представление (по 6 на каждую компоненту). При этом исходному логическому номеру цвета с использованием 6-битовых регистров EGA сопоставляются значения от 0 до 63 (как и ранее), но это уже не RGB -разложение цвета, а номер соответствующего DAC-регистра, содержащего физический цвет.
Для установки DAC- регистров применяют функцию:
void far setrgbpalette ( int Color, int Red, int Green, int Blue );
где Сolor — номер логического цвета; Red, Green, Blue — параметры DAC-регистров.
Следующий пример программы поясняет это отличие.
Пример 2. Переопределение 16 цветов VGA в 16 градаций серого.
//examp2.cpp
#include <conio.h>
#include <graphics.h>
#include <process.h>
#include <stdio.h>
main ()
{
int driver = VGA;
int mode = VGAHI;
int res;
palettetype pal;
initgraph ( &driver, &mode, “”);
if ( ( res = graphresult () ) != grOk )
{
printf (“\nGraphics error: %s\n”, grapherrormsg (res) );
exit (1);
}
getpalette ( &pal );
for (int I =0; I < pal.size; I++ );
{
setrgbpalette ( pal.colors [I], (63*I)/15, (63*I)/15, (63*I)/15 );
setfillstyle (SOLID_FILL, I );
bar (I*40, 100, 39 + I*40, 379 );
}
getch ();
closegraph ();
}
4. Понятие видеостраниц. Работа с ними.
Для многих режимов (например EGAHI) объем нужной видеопамяти для хранения изображения составляет не более 256 Kб, что меньше половины доступных аппаратных ресурсов. Поэтому всю видеопамять делят на равные части. Их количество равно 2n, где n = 1,2,… Например, для EGAHI имеется две части (страницы): 0-я (адрес 0xA000:0) и 1-я (адрес 0xA000:8000).
• Видеостраница — кратное значение размера видеопамяти, достаточное для хранения видеоизображения.
Видеоадаптер отображает на экране, в один момент, только одну из имеющихся страниц. Она называеися — в и д и м о й, и определяется функцией:
void far setvisualpage ( int Page );
где Page — номер указанной страницы (нумерация — с 0).
Графическая библиотека также может работать со страницами. Текущая называется а к т и в н о й, и определяется функцией:
void far setactivepage (int Page);
где Page — номер активной страницы на которую производится весь вывод.
Примечание! Данные методы находят широкое применение в мультипликации. Для того, чтобы избежать непрятного мерцания (смены кадров), используют частую смену активной и невидимой видеостраниц. Пока на активной существует образ, невидимая очищается и рисует новый кадр, после чего становится активной. Как это происходит видно из примера.
Пример 3. Программа прорисовки мультпроцесса в многостраничном режиме.
//examp3.cpp
#include <conio.h>
#include <graphics.h>
#include <process.h>
#include <stdio.h>
int xc = 450, yc = 100; // center of circle
int vx = 7, vy = 5; // velocity
int r = 20; // radius
void DrawFrame ( int n )
{
if ( ( xc += vx ) >= getmaxx () — r || xc < r)
{
xc = vx; vx = -vx;
}
if ( ( yc += vy ) >= getmaxy () — r || yc < r)
{
yc = vy; vy = -vy;
}
circle ( xc, yc, r );
}
main ()
{
int driver = EGA;
int mode = EGAHI;
initgraph ( &driver, &mode, “”);
if ( ( res = graphresult () ) != grOk )
{
printf (“\nGraphics error: %s\n”, grapherrormsg (res) );
exit (1);
}
DrawFrame ( 0 );
setactivepage ( 1);
for ( int frame = 1; ; frame++ )
{
clearviewport ();
DrawFrame ( frame );
setactivepage ( frame & 2 );
setvisualpage ( 1 — ( frame & 2) );
if ( kbhit () ) break;
}
getch ();
closegraph ();
}
Примечание! Не все режимы поддерживают работу с несколькими страницами. Например, VGAHI работает только с одной.
Практическое задание.
Разработать программу для описания VGA — палитры, работающей с одной видеостраницей, и описывающей 8 градаций одного цвета ( на выбор ).
