|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вступление
Здравствуйте! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ТеорияИтак мы уже немного (или уже много?) поработали с библиотекой bgi. И смогли оценить её недостатки и достоинства. Сегодня мы напишем собственную графическую библиотеку... Конечно она будет обладать меньшим набором функций и процедур, нежели BGI, но это будет НАША библиотека, и этим она будет хороша. Но сначал как всегда немного теории.... Как вы знаете, существуют графический и текстовый режимы. Сегодня нас в первую очередь интересует именно графический режим. В графическом режиме мы имеем возможность управлять цветом каждой точки экрана независимо от других. Основными характеристиками режима являются его разрешение и количество бит на пиксель. Разрешение экрана - это высота и ширина экрана в точках (пикселях). Не надо путать размер экрана с его разрешением!!! Размер (например 17 дюймов) - это физическая величина, которую мы изменить не можем. Разрешение (например 800 на 600 пикселей) - это логическая величина, которую можно изменить програмно. Каждая логическая точка (пиксель) состоит из множества физических точек экрана. Пиксель (Pixel) - это сокращение от Picture Element - элемент изображения. Маркировка разрешения (800х600) говорит нам о количестве пикселей в строках (по-горизонтали) - 800 и количестве пикселей в столбцах (по вертикали) - 600. Количество бит видеопамяти, отводимое на пиксель определяет возможное число состояний пикселя. Например его цвет, яркость, мерцание. В самом простом случае - 1 бит на пиксель - возможны только два случая: пиксель или подсвечен или нет. Можно сказать иначе: пиксел чёрный или белый. При этом не стоит называть такой режим чёрно-белым, т.к. это название подразумевает наличие оттенков этих цветов, т.е. получается большее количество чем 2. Четыре цвета (2 бита на пиксель) в своё время доставляли немало удовольствия любителям цветных игрушек. 16 цветов (вот мы добрались и до bgi) - 4 бита на пиксель - были вполне достаточны для многих игр и графических программ. Адаптеры с 256 цветами (8 бит на пиксель) в своё время произвели революцию в мире графики. Сейчас в основном используются режимы High Color (15 бит - 32768 цветов или 16 бит - 65536 цветов) и True Color (24 бит на пиксель - 16,7 миллионов цветов). Так же популярен режим с 32 битами на пиксель, но для цветопередачи по прежнему используются только 24 бита. Давайте рассмотрим логическую организацию видео памяти. В зависимости от количества бит на пиксель она может быть различной. В случае одного или двух бит на пиксель каждая ячейка памяти (байт) соответствует восьми или четырём соседним пикселям. Такой способ отображения называется линейным - последовательности пикселей соответствует линейная последовательность бит видеопамяти. Про не линейный режим (4 бита на пиксель) я расказывать не буду, это сейчас уже не нужно, хотя и очень интересно. При режимах 8, 16 и 24 бит на пиксель вернулись к линейной организации памяти. При этом каждому пикселю соответствует уже байт, слово или три байта. При этом цвет задаётся непосредственно через двоичные коды, которые соответствуют уровням интенсивности 3-х основных цветов: красный, зелёный, синий (для краткости их обозначают RGB - RedGreenBlue). Форматы байт выглядят следующим образом (младший бит справа, U - для формирования цвета бит не используется):
Как известно различные графические адаптеры позволяют использовать различные разреения и количества цветов. Давайте рассмотрим все адаптеры (ну или подчти все) от самых первых - MDA до наиболее популярных сегодня SVGA.
Ну вот так шаг, за шагом мы подобрались к началу нашей библиотеки. С чего начинается работа графической программы? Правильно с установки видео режима! Нам надо написать свою процедуру для инициализации графики и возврата в текстовый режим. Хотя две процедуры писать нам не придётся. Т.к. возврат в текстовый режим сводится к простой установке нового режима. Итак за установку режима отвечает 0 функцая прерывания 10h (это прерывание BIOS). На входе: AL = текущий режим. Сразу скажу, что текстовому режиму (вернее тестовому режиму с "разрешением" 80х25) соответствует значение 3. Теперь пришло время донести до вас одну печальную новость. Наша библиотека будет поодерживать только один режим, а именно 320х200х256. Почему я сделал такой выбор?
Отвечающие соответственно за режимы. И написать процедуру для установки нужного режима:const TextMode = $3; GrMode = $13;
Итак теперь мы в графическом режиме. Теперь надо написать процедуру для подсветки точки на экране. Самый простой метод - напрямую в видеопамять. Для каждого режима надо писать отдельную процедуру, но раз мы договорились, что режим у нас один, то и процедуру мы напишем одну. Смещение относительно сегмента видеопамяти считается по следубщей формуле: offset = y*320+x. Конечно такую процедуру просто реализовать на Паскале (вот вам кстати очередное Д/З - реализуйте процедуру подсветки пикселя на Паскале:). НО графическая библиотека должна быть быстрой - поэтому такую процедуру нужно реализовывать на ассемблере, т.к. скорость при подсветке точек играет большое значени. Ниже приведена процедура для подсветки пикселя с комментариями:
Для работы этой процедуры надо в опциях компилятора выбрать инструкции для 286 процессора. И соответственно нам нужна функция, которая возвратит нам цвет точки. Вот её реализация так же на ассемблере:
Теперь самое время поговорить о палитре. Как говорилось выше, каждый цвет кодируется тремя составляющими - RGB. На каждую компоненту отводится по 6 бит, т.е. она может принимать значения от 0 до 63. За утановку палитры отвечают порты 03C8h и 03C9h. Алгоритм установки цвета такой: пишем в порт 03C8h номер цвета, а затем в порт 03C9h по порядку записываем RGB составляющие. На примере это выглядит так:
Для чтения же необходимо сначала записать в порт 03C7h номер цвета, а потом из порта 03C9h по порядку считать RGB составляющие.Вот на сегодня с теорией и всё. Мы написали первую - низкоуровневую чать нашей библиотеки. На следующем занятии мы продолжим и напишем функции для построения графических примитивов. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ПрограммаСегодня у нас довольно интересная программа - алгоритм огня. Итак каким образом формируются огонь в различных играх? Реально нам нужно написать алгоритм для затухания огня. Присмотритесь на все существующие огни - они "просто " затухают снизу вверх. Т.е. нижняя линия у нас всегда горит. Дальше линия горит меньше, дальше ещё меньше .... и так пока не "выгорят" все точки на линии. Самым простым вариантом затухания является усреднение значения каждой точки с её окружением. Т.е. пусть у нас есть точка цвета А с координатами (х,у). Для получения её нового цвета В мы должны взять цвет 8 соседних точек и точки А, поделив это на 9. Т.е. мы берём цвета:
Кроме того нам надо постоянно "толкать" изменённую линию вверх. А снизу создавать новую. При этом не полностью заполненную.
Наилучшим вариантом будет хранение всего огня в двух мерном массиве. Полный текст программы приведён ниже:
for i := 0 to 255 doЕсли не изменять палитру, то можно получить эффект "плазмы" с единственным недостаткаом - вверху будут отображаться 16 цветов. Связано это с тем, что в начале палитры идут 16 не переливающихся цветов, а уже только потом начинаются плавные переходы. Конечно это самы простой вариант огня. Для получения более рельного изображения надо использовать более сложный алгоритм затухания. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ГолосованиеМоё повествование о Паскале подходит к концу. И поэтому надо думать: что дальше? Мои варианты:
На этой неделе уверенно вырвалось вперёд программирование на Object Pascal. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Это должен посетить каждый!сегдня я дам только одну ссылку, не имеющую отношения к Паскалю, но очень мне понравившуюся :)
|