Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Листинг 5.8. Создание и отображение цветовой палитры (PALDEMO.C)





// ВКЛЮЧАЕМЫЕ ФАЙЛЫ ///////////////////////////////////////////////////////////////////////

#include <io.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <dos.h>

#include <bios.h>

#include <fcntl.h>

#include <memory.h>

#include <math.h>

#include <string.h>

 

// определения /////////////////////////////////////

#define ROM_CHARSET_SEG 0xF000

#define ROM_CHAR_SET_OFF 0xFA6E

#define VGA256 0x13

#define TEXT_MODE 0х03

#define PALETTE_MASK ОхЗc6

#define PALETTE_REGISTER_RD.Ox3c7 #define PALETTE_REGISTER_WR 0x3c8

#define PALETTE_DATA 0x3c9

#define SCREEN_WIDTH (unsigned int)320

#define SCREEN_HEIGHT (unsigned int)200

// структуры данных////////////////////////////////////////

// структура, сохраняющая RGB

typedef struct RGB_color_typ

{

unsigned char red; // красный компонент 0-63

unsigned char green; // зеленый компонент 0-63

unsigned char blue; // синий компонент 0-63

} RGB_Color, *RGB_color_ptr;

// ВНЕШНИЕ ФУНКЦИИ //////////////////////////////////

extern Set_Mode(int mode);

// ПРОТОТИПЫ //////////////////////////////////////////

void Set_Palette Register(int index, RGB_color_ptr color);

void Get_Palette_Register(int index, RGB_color_ptr color);

void Create_Cool__Palette();

void V_Line(int y1,int y2,int x,unsigned int color);

// ГЛОБДЛЬНЫЕ ПЕРЕМЕННЫЕ ////////////////////////////

// указатель на начало видеопамяти (для операций с байтами)

unsigned char far *video_buffer = (char far *)0xA0000000L;

// указатель на начало видеопамяти (для операций со словами)

unsigned int far *video_buffer_w= (int far *)0xA0000000L;

// ФУНКЦИИ //////////////////////////////////////////

void Set_Palette_Register (int index, RGB_color_ptr color)

{

// Эта функция устанавливает значение одного элемента таблицы

// цветов. Номер регистра задается переменной index, структура

// color содержит значения красной, зеленой и синей составляющих

// цвета

// указываем VGA карте, что мы будем обновлять содержимое

// регистра палитры

_outp(PALETTE_MASK,Oxff);

// какой из регистров мы хотим обновить?

_outp(PALETTE_REGISTER_WR, index);

// теперь обновляем RGB

_outp(PALETTE_DATA,color->red);

_outp(PALETTE_DATA,color->green);

_outp(PALETTE_DATA,color->blue);

} // конец функции

/////////////////////////////////////////////////////

void Get_Palette_Register(int index, RGB_color_ptr color)

{

// эта функция читает данные элемента таблицы цветов и помещает их

// в поля структуры color

// установить маску регистра палитры

_outp(PALETTE_MASK,Oxff);

// сообщаем VGA, какой из регистров мы будем читать

_outp(PALETTE_REGISTER_RD, index);

// читаем данные

color->red = _inp(PALETTE_DATA);

color->green = _inp(PALETTE_DATA);

color->blue = _inp(PALETTE_DATA);

} // конец функции /////////////////////////////////////////////////

void Create_Cool_Palette(void) {

// эта функция создает палитру, содержащую по 64 оттенка серого,

// красного, зеленого и синего цветов

RGB_color color;

int index;

// проходим по элементам таблицы цветов и создаем 4 банка

// по 64 элемента

for (index=0; index < 64; index++)

{

// оттенки серого

color.red = index;

color.green = index;

color.blue = index;

Set_Palette_Register(index, (RGB_color_ptr)&color);

// оттенки красного

color.red = index;

color.green = 0;

color.blue = 0;

Set_Palette_Register(index+64, (RGB_color_ptr)&color);

// оттенки зеленого

color.red = 0;

color.green = index;

color.blue = 0;

Set_Palette_Register(index+128, (RGB_color_ptr)&color);

// оттенки синего

color.red = 0;

color.green = 0;

color.blue = index;

Set_Palette_Register(index+192, (RGB_color_ptr)&color);

} // конец цикла for

} // конец функции

///////////////////////////////////////////////////////

void V_Line(int y1,int y2,int x,unsigned int color)

{

// рисуем вертикальную линию у2 > yl

unsigned int line_offset, index;

// вычисляем начальную позицию

line_offset = ((y1<<8) + (y1<<6)} + x;

for (index=0; index<=y2-y1; index++)

{

video_buffer[line_offset] = color;

line_offset+==320; // переходим к следующей линии

} // конец цикла for

} // конец функции

// ОСНОВНАЯ ПРОГРАММА /////////////////////////////////

void main(void)

{

int index;

RGB_color color,color_1;

// установить режим 320х200х256

Set_Mode(VGA256);

// создать палитру цветов

Create_Cool_Palette();

// рисуем по одной вертикальной линии для каждого цвета

for (index=0; index<320; index++) V_Line(0,199,index,index);

// ждем реакции пользователя

while(!kbhit())

{

Get_Palette_Register(0,(RGB_color_ptr)&color 1);

Get_Palette_Register(0,(RGB_color_ptr)&color_l);

for (index=0; index<=254; index++)

{

Get_Palette_Register(index+l,(RGB_color_ptr)&color);

Get_Palette__Register(index+l, (RGB_color_ptr)&color);

Set Palette Register(index,(RGB color_ptr)&color);

} // конец цикла for

Set_Palette_Register(255,(RGB_color_ptr)&color_1);

} // конец цикла while

// переходим обратно в текстовый режим

Set_Mode(TEXT_MODE);

} // конец функции

Программа из Листинга 5.8 создает новую палитру, которая содержит 64 оттенка всех основных цветов, включая серый. Затем, она разделяет каждый цвет вертикальными линиями и после этого перемешивает их.

Вроде, хватит об этом. Теперь стоит поговорить о том, как целиком прочитать файл с образом. Начнем с формата PCX-файлов.

Графический формат PCX

В индустрии компьютерной графики существует так много стандартов, что само слово «стандарт» уже потеряло свой первоначальный смысл. Сегодня существует несколько наиболее известных стандартов: PCX, GIF, RGB, TGA, TIF и многие другие. Нам интересен формат PCX потому, что сегодня он является самым распространенным.

Файл в формате PCX представляет собой закодированное представление изображения. Кодирование необходимо для уменьшения размера файла, поскольку только один образ 320х200 пикселей уже займет 64К памяти. Рисованные объекты обладают большой цветовой избыточностью, и это обстоятельство используется для сжатия изображения.

Примечание

Отсканированные фотографии, как правило, содержат большое количество цветов, более ли менее равномерно распределенных по всему изображению. Таким образом, фотографические изображения с трудом поддаются сжатию. Однако, поскольку большинство картинок в компьютерных играх выполняется вручную, мы можем не особенно ломать голову над проблемами, возникающими при работе с оцифрованными фотографиями.

Давайте посмотрим на рисунок 5.5 (файл CH19\WARINTR2.PCX на дискете). Это копия экрана из игры Warlock. Как вы можете заметить, там не слишком много цветов. Более того, на нем присутствует множество больших, одинаково окрашенных областей.

Как правило, в экранных изображениях используется лишь ограниченное число цветов. Так почему бы не подсчитать количество пикселей одинакового цвета и не сохранить их как целые группы, вместе с позицией и цветом. Это можно сделать. В общем, подобная технология, правда, в несколько усовершен­ствованном виде, и применена в PCX-формате. Для сжатия информации этот формат использует так называемое RLE-кодирование. При этом изображение обрабатывается построчно без учета расположения пикселей по вертикали.

Посмотрите на рисунок 5.6. Преобразование экранного файла в PCX-формат происходит следующим образом; просматривается очередная строка изображения, и если это возможно, сжимается. Сжатие выполняется в том случае, если найдена последовательность пикселей одинакового цвета. При этом сохраняется

количество повторений пикселей и значение их цвета. Повторяется это до тех пор, пока все изображение не окажется сжатым.

Такая методика неплохо работает для большинства изображений, но в некоторых случаях может не срабатывать, например, когда изображение имеет слишком мало одинаковых участков. В этом случае размер файла, напротив, увеличится, так как для записи одиночных пикселей требуется не один, а два байта.

Файл формата PCX состоит из трех секций:

§ Первая секция PCX-файла длиной 128 байт содержит различную служеб­ную информацию;

§ Вторая секция — это данные сжатого образа, которые могут оказаться любой длины;

§ Третья секция размером в 768 байт содержит цветовую палитру, если она есть. В нашем случае она будет присутствовать, поскольку мы используем 256-цветный режим 13h. Эти 768 байт хранят значения RGB от 0 до 255.

Суммируя вышесказанное, можно нарисовать структуру PCX-файла (рис. 5.7).

Получение информации из заголовка несложно: достаточно прочитать первые 128 байт и отформатировать их в соответствии со структурой, представленной в Листинге 5-9.


 

Date: 2015-09-18; view: 401; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию