Рисование точки
Однажды я сказал: «Дайте мне адрес видеобуфера и я переверну экран. ..». Это весьма правдивое высказывание. Во всех системах с отображением адресов видеопамяти на область адресов памяти обычной, как это делается в ПК; рендеринг был бы более простой и доступной вещью, если бы видеобуфер имел хоть каплю логики в своей организации. Собственно, организация и логика есть: видеобуфер - это один большой массив. И все.
Как мы узнали чуть раньше, для рисования точки нам достаточно вычислить адрес смещения относительно начала видеобуфера (А000:0000) и записать байт, отображающий ее цвет. Больше ничего делать не надо. Листинг 5.4 содержит фрагмент кода, который рисует точку определенного цвета с координатами Х и Y.
Листинг 5.4. Рисование точки в позиции (х,у).
void Plot_Pixel(int x,
int у, unsigned char color)
{
// эта функция отображает точку выбранного цвета. Каждая строка
// занимает 320 байт, поэтому для вычисления адреса надо умножить Y
// на 320 и прибавить значение Х
video_buffer[y*320+x]=color;
} // конец функции
Итак, рисование точки довольно просто. Я думал, все окажется сложнее, и поэтому так много написал об этом, но то, что мы использовали режим 13h, значительно упростило дело. Функция Plot_Pixel получилась простой, это всего одна строка кода. Тем не менее, давайте попробуем ее оптимизировать.
В книге есть целая глава, посвященная оптимизации, но эта единственная строка, содержащая операцию умножения, меня сводит с ума. Давайте избавимся от умножения. Кстати, возьмем за правило избегать операций умножения и вообще, откажемся от действий с плавающей запятой. Итак, посмотрим, что мы можем сделать с вычислением у х 320?
Вспомним, что мы используем двоичную арифметику и все числа в ПК также представлены в двоичном виде. Если вы берете двоичное число и сдвигаете его влево или вправо, это аналогично его умножению или делению на два.
Рисунок 5.3 поясняет это.
Поскольку операция сдвига выполняется примерно в 2-10 раз быстрее, чем умножение, то мы получим быстрые функции для рисования. Единственная сложность состоит в том, что число 320 — это не степень двух, но чтобы выйти из положения, мы применим маленькую хитрость. Представим выражение 320 х у, как 256 х, у + 64 х у. Листинг 5.5 показывает код для быстрого рисования точки.
Листинг 5.5. Программа быстрого рисования точки.
void Plot_Pixel_Fast ( int x, int y, unsigned char color )
{
// эта функция рисует точку несколько быстрее за счет замены
// операции умножения на сдвиг
// учитываем, что 320*у=256*у+64*у=у<<8+у<<б
video_buffer[((у<<8) +(у<<6)) + х ] = color;
} // конец функции
Эта функция работает примерно в два раза быстрее — вот что значит оптимизация. Позже мы научимся оптимизировать программы так, что парни из Microsoft перестанут нам верить.
Теперь, когда у нас есть функция рисования точки, надо дополнить нашу графическую библиотеку функцией рисования линии.