Студопедия

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

Разделы сайта

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






Техника созданий параллакса






Вы, конечно, не раз обращали внимание, глядя из окна автомобиля, что близлежащие объекты перемещаются гораздо быстрее, чем удаленные. Этот эффект получил пугающее название — параллакс. В повседневной жизни вы настолько часто наблюдаете это явление, что, скорее всего, считаете его чем-то само собой разумеющимся.

Параллакс является только одним из многих эффектов нашего визуального восприятия. Другой хорошо известный эффект - это перспектива. Перспектива и параллакс вкупе с другими ощущениями, такими как равновесие и слух, формируют завершенную картину окружающей среды.

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

Еще кое-что о режиме 13h

Прежде чем заняться разработкой первой программы, реализующей параллакс давайте еще раз поговорим об избранном видеорежиме. Как мы уже обсуждали в пятой главе «Секреты VGA-карт», наиболее популярным видеорежимом для программирования игр является режим 13h. Причиной номер 1 является его совместимость с различными микросхемами VGA. Другая причина, вероятно заключается в простоте программирования. Все нижеследующее является кратким обзором приемов программирования VGA в режиме 13h. Для более глубокого обзора необходимо вернуться к пятой главе. С другой стороны, если вы в совершенстве овладели программированием VGA-карт, то без ущерба можете пропустить этот раздел.

Режим 13h поддерживает разрешение 320х200 пикселей при одновременном отображении 256 цветов, где каждый пиксель представлен одним байтом. Следовательно, видеобуфер имеет размер 64000 байт. Эти 64К отображаются в область памяти, начиная с адреса А000: 0000.

Все, что требуется для изображения пикселя в режиме 13h, это записать в видеобуфер байт. Проще всего это сделать, используя следующий код:

char far *VideoMem =MK_FP(0xA000, 0);

Чтобы изобразить отдельный пиксель в позиции (200, 100) с цветовым значением равным 2, вам необходимо только рассчитать смещение байта относительно начала видеопамяти. Смещение вычисляется путем умножения Y-координаты на 320 (поскольку в строке 320 пикселей) и добавлением Х-координаты:

PixelOffset = у * 320 + х;

После этого вы можете обращаться к видеопамяти как к элементам обычного одномерного массива:

VideoMem[PixelOffset] = 2;

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

Например, следующий фрагмент копирует 320 байт из массива Scr в видеобуфер:

memcpy(VideoMem, Scr, 320);

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

Вся графика сначала выводится в буфер, расположенный в системной памяти (в дублирующий буфер), а затем, когда кадр полностью сформирован, он копируется на дисплей единым блоком также с помощью функции memcpy().

Это все, что необходимо на данный момент времени знать по поводу режима 13h, так что двинемся дальше.

Примечание по поводу демонстрационной программы

Я привожу некоторые небольшие демонстрационные программы для иллюстрации технических приемов, описанных в этой главе- По указанным выше причинам все программы работают в видеорежиме 13h. Я старался сделать их максимально удобочитаемыми, поэтому написаны они не самым оптимальным образом и не слишком эффективны.

Внимание

Все программы в этой главе написаны на Borland C++ 3.1 и Турбо ассемблере 3.1. Однако все примеры на Си были написаны с максимальной осторожностью, без привлечения особенностей Borland С. Так что они должны легко компилироваться любыми трансляторами C/C++ без внесения значительных изменений. Программы на ассемблере писались с использованием ключа IDEAL. Обратите внимание, что они не используются в демонстрационном примере, приведенном в этой главе, поскольку здесь же приведены их аналоги на Си.

Первый шаг

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

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

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

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

Запомните положение логической границы, разделяющей изображение на две части. Полученное число будет соответствовать ширине левой части изображения. Теперь назовем это число LeftHalf и установим начальную ширину левой части равной одному пикселю.

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

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

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

Затем обе части изображения выводятся на экран. Делается это так. Начиная с левой границы экрана, рисуется правая логическая часть изобраяжения:

§ Сначала выводится строка пикселей изображения, начиная со столбца определенного переменной LeftHalf. Количество рисуемых писелей равно общей ширине изображения минус LeftHalf;

§ Продолжайте рисование пикселей от левого края изображения до столбца LeftHalf.

Если положение логического разрыва изменить и перерисовать изображение заново, оно будет выглядеть движущимся по экрану.

Взгляните на следующий пример, демонстрирующий рисование двух половинок строки развертки изображения (вспомните, что разверткой называется полная горизонтальная строка пикселей).

// нарисовать левую половину изображения

memcpy(Screen+320-LeftHalf, Bitmap, LeftHalf);

// нарисовать „правую часть изображения

memcpy(Screen, Bitmap+LeftHalf, 320-LeftHalf);

где Screen - указатель на видеопамять, LeftHalf - ширина логической левой части изображения, a Bitmap - указатель на битовую карту изображения, загруженную в память. Этот процесс повторяется для каждой строки развертки изображения.

Каждый раз, когда вы увеличиваете значение LeftHalf на единицу, вы должны убедиться, что оно не превышает общей ширины изображения:

§ Если LeftHalf больше ширины изображения, присвойте ей значение, равное единице;

§ Если LeftHalf меньше единицы, присвойте ей значение, равное общей ширине изображения.

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

Листинг 17.1 - это файл заголовка PARAL.H, в котором содержатся объявления различных констант, структур данных, а также прототипы функций, используемых в демонстрационной программе из Листинга 17.2 (PARAL.C).






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.