Читайте также: |
|
Plot_Pixel_Asm(int x,int у,int color)
{
_asm{
les di,video_buffer // загрузить регистр es значением
// сегмента видеобуфер
mov di,y // поместить в di у-координату пикселя
shl di,6 // умножить на 64
mov bx,di // сохранить результат
shl di,2 // умножить еще на 8 (итого, на 256)
add di,bx // сложить результаты
add di,x // прибавить х-компонент
mov al,BYTE PTR color // записать цвет в регистр аl
mov es:[di],al // нарисовать пиксель
}
}
Ладно, покончим с этим. Ассемблерный вариант работает всего лишь на 2 процента быстрее, чем версия на Си. На то есть две причины:
§ Во-первых, компилятор Си проделывает неплохую работу, транслируя программу в машинные коды. Хотя, как вы знаете, мы можем сделать это вручную, используя ассемблер;
§ Во-вторых, когда вы используете встроенный ассемблер, он сохраняет все регистры и позже восстанавливает их. Единственный способ избавления от этого - написать внешние ассемблерные функции с использованием MASM. В данном случае это вполне допустимо, поскольку мы оптимизируем такую важную операцию как построение пикселя.
Наконец, я хочу показать вам последний пример оптимизации, которая позволяет ускорить вывод на экран в два раза.
Оптимизация изображаемой линии
Игры типа DOOM и Wolfenstein 3-D не используют все известные техники трехмерных графических преобразований, как это делают, например, имитаторы полетов. В них применяются совершенно гениальные методы для создания трехмерных образов. Эти методы базируются на изображении большого количества линий, проходящих в одном направлении. Обычно рисуются обычно вертикальные или горизонтальные линии и только в удаленных предметах присутствуют диагональные прямые. Следовательно, мы должны научиться максимально быстро проводить горизонтальные и вертикальные линии. Сейчас мы поговорим о горизонтальных прямых.
Как мы проходили в пятой главе «Секреты VGA-карт», для изображения горизонтальной линии лучше всего применить функцию memcpy () (см. Листинг 5.6). Начальный и конечный адреса вычисляются из Х-координат крайних точек линии. Вернувшись назад к этому методу, приходится признать, что он не совсем совершенен, поскольку memcpyO для перемещения данных использует тип BYTE. Но профессионалы в программировании игр знают, что VGA-карта работает быстрее с данными типа WORD. Следовательно, нужно попытаться исправить этот недостаток и записывать в видеобуфер WORD вместо BYTE. Сейчас я собираюсь переписать функцию изображения горизонтальных линий, учитывая это пожелание.
Это не так легко, как кажется, потому что конечной целью должна быть забота о работоспособности. Вы видите, что когда вы пишите WORD в видеобуфер, вы в сущности строите два пикселя. Вы должны быть осторожны, принимая это во внимание во время рисования линий. Скажем, мы хотели изобразить линию, тянущуюся от точки (51,100) до точки (100,100). У нас получится линия, которая выглядит чем-то похожей на рисунок 18.4.
Завершим анализ изображения этой линии тем, что каждая конечная точка в действительности занимает один байт, а не два. Следовательно, мы должны написать программу, которая может управлять состоянием, когда конечные точки BYTE или WORD граничат. Программа из Листинга 18.6 делает это.
Дата добавления: 2015-07-12; просмотров: 66 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Листинг 18.2. Функции библиотеки системы с фиксированной запятой (FIX.C). | | | Листинг 18.6. Программа, изображающая горизонтальную линию и использующая для этого тип WORD (HLINEF.C). |