Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 8.1. Новая функция масштабирования спрайтов (без отсечения).
void Scale_Sprite(sprite_ptr sprite, int scale) //Эта функция масштабирует спрайт (без отсечения). Масштабирование // производится с использованием заранее рассчитанной таблицы, // которая определяет, как будет изменяться каждый вертикальный // столбец. Затем другая таблица используется для учета // масштабирования этих столбцов по оси Х char far *work_sprite; // текстура спрайта int *row_у; // указатель на масштабированные // по оси Y данные (заметьте, что это // ближний указатель) int far *row_x; // указатель на масштабированные // по оси Х данные (заметьте, что это // дальний указатель) unsigned char pixel; // текущий текстель int x, // рабочие переменные y, column, work_offset, video_offset, video_start; // если объект слишком мал, то и рисовать его не стоит if (scale< 1) return; // рассчитываем необходимые для масштабирования данные row_у = scale_table_y [scale]; row_x = scale_table_x[scale]; // выбираем соответствующий кадр спрайта work_sprite = sprite-> frames[sprite-> curr_frame]; // рассчитываем начальное смещение video_start = (sprite-> y < < 8) + (sprite-> y < < 6} + sprite-> x; // изображение рисуется слева направо и сверху вниз for (х=0; x< scale; x++) { // пересчитываем адрес следующего столбца video_offset = video_start + x; // определяем, какой столбец должен быть отображен, //исходя из индекса масштабирования по оси Х column = row_x[x]; // наконец рисуем столбец обычным образом for (y=0; y_scale; y++) { // проверка на " прозрачность" pixel = work_sprite[work_offset+column]; if (pixel) double_buffer[video_offset] = pixel; // индекс следующей строки экрана и смещение в области // хранения текстуры video_offset += SCREEN_WIDTH; work_offset = row_y[y]; } // конец цикла по У } // конец цикла по Х } // конец Scale_Sprite Как видите, это простая и короткая функция. Это достигается благодаря использованию двух таблиц масштабирования. В них расположены индексы масштабирования: в одной — для масштабирования по координате X, а в другой - по У. Две таблицы нужны на тот случай, если ширина и длина спрайта окажутся не одинаковыми. Таким образом, если спрайт всегда имеет размеры МхМ, то алгоритм масштабирования может быть еще более упрощен. Отметим, что таблицы соответствия находятся в разных сегментах памяти: ближнем (NEAR) и дальнем (FAR). Это сделано для скорости. Таблица соответствия во внутреннем цикле масштабирования (по оси У) должна быть в ближнем сегменте данных для ускорения доступа. Таблица соответствия во внешнем цикле (масштабирование по оси X) может располагаться в дальнем сегменте, так как доступ к ней обычно осуществляется только несколько десятков раз. В общем, было бы, конечно, лучше поместить обе таблицы в ближнем сегменте данных. Однако в результате этого можно очень быстро исчерпать его, что осложнит размещение глобальных переменных. Основное правило при работе с таблицами соответствий на языке Си состоит в следующем: пытайтесь расположить наиболее часто используемые таблицы в ближнем сегменте, а менее употребимые — в дальнем. Это правило не касается того случая, когда есть возможность уместить и таблицу, и глобальные переменные в 64К ближнего сегмента данных. Теперь посмотрим на нашу новую процедуру масштабирования в действии. Я написал программу, которая загружает ряд заранее отсканированных изображений размером 80х48 пикселей. Эти изображения были сделаны с помощью макета космического корабля, который фотографировался под разными углами в моей импровизированной студии (о ней я уже рассказывал в начале главы). Эта программа (VYREN.C) показывает вращающийся на некотором расстоянии от наблюдателя (то есть от вас) космический корабль и позволяет передвигать его по оси Z с помощью клавиш > (правая угловая скобка или «меньше») и < (левая угловая скобка или «больше»), (На самом деле, в нижнем регистре это будут клавиши с символами запятой и точки соответственно.) Вы увидите, что новый метод с использованием таблиц существенно быстрее прежнего. Текст этой программы приведен в Листинге 8.2. Потратьте некоторое время и постарайтесь понять, как работает эта программа. Как обычно, программа должна быть скомпонована с нашей растущей графической библиотекой, GRAPHICS.С, и скомпилирована с использованием модели памяти MEDIUM. Для завершения работы программы, следует нажать клавишу Q.
|