- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Графика для Windows средствами DirectDraw - Стэн Трухильо
Шрифт:
Интервал:
Закладка:
Листинг 6.3. Функция QwertyWin::DrawScene()
void QwertyWin::DrawScene() {
static char key[256];
keyboard->GetDeviceState(sizeof(key), &key);
//---------- Клавиши QWERTY --------
if (key[DIK_Q] & 0x80) BltSurface(backsurf, q_dn, 213, 70);
else BltSurface(backsurf, q_up, 213, 70);
if (key[DIK_W] & 0x80) BltSurface(backsurf, w_dn, 251, 70);
else BltSurface(backsurf, w_up, 251, 70);
if (key[DIK_E] & 0x80) BltSurface(backsurf, e_dn, 298, 70);
else BltSurface(backsurf, e_up, 298, 70);
if (key[DIK_R] & 0x80) BltSurface(backsurf, r_dn, 328, 70);
else BltSurface(backsurf, r_up, 328, 70);
if (key[DIK_T] & 0x80) BltSurface(backsurf, t_dn, 361, 70);
else BltSurface(backsurf, t_up, 361, 70);
if (key[DIK_Y] & 0x80) BltSurface(backsurf, y_dn, 393, 70);
else BltSurface(backsurf, y_up, 393, 70);
//---------------- LEFT CONTROL ---------------
if (key[DIK_LCONTROL] & 0x80) BltSurface(backsurf, lctrl_dn, 50, 180);
else BltSurface(backsurf, lctrl_up, 49, 180);
//---------------- RIGHT CONTROL ---------------
if (key[DIK_RCONTROL] & 0x80) BltSurface(backsurf, rctrl_dn, 490, 180);
else BltSurface(backsurf, rctrl_up, 490, 180);
//---------------- LEFT ALT ---------------
if (key[DIK_LMENU] & 0x80) BltSurface(backsurf, lalt_dn, 100, 260);
else BltSurface(backsurf, lalt_up, 100, 260);
//---------------- RIGHT ALT ---------------
if (key[DIK_RMENU] & 0x80) BltSurface(backsurf, ralt_dn, 440, 260);
else BltSurface(backsurf, ralt_up, 440, 260);
//---------------- SPACE -----------------
if (key[DIK_SPACE] & 0x80) BltSurface(backsurf, space_dn, 170, 340);
else BltSurface(backsurf, space_up, 170, 340);
//---------- ESCAPE -------------
if (key[DIK_ESCAPE] & 0x80) {
BltSurface(backsurf, esc_dn, 0, 0);
esc_pressed=TRUE;
} else {
BltSurface(backsurf, esc_up, 0, 0);
if (esc_pressed) PostMessage(WM_CLOSE);
}
primsurf->Flip(0, DDFLIP_WAIT);
}
Состояние устройства определяется функцией GetDeviceState() интерфейса DirectInputDevice. Тип и размер второго аргумента GetDeviceState() зависят от типа устройства, а также от формата данных, заданного функцией SetDataFormat(). Для клавиатуры функция должна получать массив из 256 байт, где каждый байт соответствует одной клавише. В DirectInput предусмотрен набор клавиатурных констант, которые используются как индексы массива и позволяют ссылаться на нужные клавиши. DirectInput обозначает нажатие клавиши установкой старшего бита того байта, который представляет данную клавишу. Объявление массива и вызов функции GetDeviceState() находятся в верхней части листинга 6.3, я снова привожу их:
static char key[256];
keyboard->GetDeviceState(sizeof(key), &key);
Адрес массива клавиш передается во втором аргументе GetDeviceState(). Первый аргумент определяет размер данных в байтах.
Все готово к проверке элементов массива. Сначала мы проверяем, была ли нажата клавиша Q:
if (key[DIK_Q] & 0x80) BltSurface(backsurf, q_dn, 213, 70);
else BltSurface(backsurf, q_up, 213, 70);
Константа DIK_Q определяет индекс клавиши Q в массиве. Мы проверяем значение старшего бита; если бит установлен, значит, клавиша Q нажата, и мы копируем поверхность, изображающую клавишу Q в нажатом состоянии (q_dn), функцией BltSurface(). Если клавиша не нажата, копируется поверхность q_up.
Обратите внимание: каждой клавише соответствует отдельный элемент массива, даже для функционально одинаковых клавиш. Например, две клавиши Alt обрабатываются по отдельности. Кроме того, DirectInput не отличает прописных букв от строчных. Чтобы учесть регистр буквы, придется дополнительно проверить состояние обеих клавиш Shift.
Оставшаяся часть функции состоит из аналогичных проверок состояния других клавиш. После того как все клавиши будут проверены, функция Flip() интерфейса DirectDrawSurface выводит новое изображение на экран.
Завершение приложенияЗавершить работу DirectInput несложно — для этого достаточно освободить все интерфейсы DirectInput. В нашей программе это происходит в функции OnDestroy():
void QwertyWin::OnDestroy() {
DirectDrawWin::OnDestroy();
if (dinput) dinput->Release(), dinput=0;
if (keyboard) {
keyboard->Unacquire();
keyboard->Release(), keyboard=0;
}
}
Управление версией DirectInput
По умолчанию приложения DirectInput требуют, чтобы версия runtime-части DirectX, установленной на компьютере пользователя, совпадала с версией SDK, использованной для компиляции приложения, или превышала ее. Например, если вы создаете приложение с использованием DirectX 5 и запускаете его на компьютере с установленным DirectX 3, вызов функции DirectInputCreate() закончится неудачей.
В этом нет ничего страшного, если вы уверены, что у всех пользователей имеется обновленная версия runtime-части DirectX. Во многих ситуациях такое предположение выглядит вполне разумно — ведь ваша инсталляционная программа может установить нужную runtime-часть вместе с приложением. Но что делать, если вы не можете включить runtime-часть в свое приложение? Например, если свободное место на диске не позволяет это сделать или приложение распространяется в электронном виде?
Обратную совместимость можно обеспечить двумя способами. Вы можете либо откомпилировать свое приложение для старой версии DirectX SDK, либо распорядиться, чтобы SDK эмулировал старую версию. В приложениях DirectInput этой книги используется второй способ.
Переопределяя стандартную константу DIRECTINPUT_VERSION, программа сообщает заголовочным файлам DirectInput о том, что необходимо обеспечить совместимость с DirectX 3. Это делается так:
#include
#include
#include
#include
#include
#include
#define DIRECTINPUT_VERSION 0x0300
#include
В приведенном фрагменте присутствуют директивы include для всех заголовочных файлов программы. Символическая константа DIRECTINPUT_VERSION должна быть определена до включения файла dinput.h (номер версии определяется старшим байтом).
В результате программа будет компилироваться как версией 3, так и версией 5 DirectX SDK (Microsoft пропустила версию DirectX 4). Получившиеся выполняемые файлы будут работать с runtime-частью DirectX 3 и выше. Поскольку Windows NT Service Pack 3 включает поддержку DirectX 3 для DirectInput, программы успешно компилируются и работают в Windows NT.
Программа Smear
Перейдем к поддержке мыши в DirectInput. Она будет рассматриваться на примере программы Smear, которая отображает поверхность в центре экрана и затем сдвигает изображение в соответствии с перемещением мыши (см. рис. 6.2).
Структура приложенияХотя программа Smear демонстрирует работу с мышью, она также использует клавиатуру для проверки клавиши Escape. Работа с клавиатурой уже рассматривалась на примере программы Qwerty, поэтому мы не будем надолго задерживаться на ней.
Рис. 6.2. Программа Smear
Если работа с клавиатурой в обеих программах построена на непосредственных данных, то ввод с мыши в программе Smear осуществляется с помощью буферизованных данных. При этом необходимо задать размер буфера (для непосредственных данных это не нужно). По умолчанию размер буфера равен нулю, поэтому для работы с буферизованными данными необходимо выбрать подходящее значение. Хотя для ввода с мыши можно было бы воспользоваться и непосредственными данными, в нашем приложении это приведет к худшему результату. С помощью буферизованных данных можно определить не только новое положение мыши, но и путь, по которому она туда попала. Эта информация обеспечивает более гладкий и точный вывод.
Часть программы Smear, работающая с DirectDraw, отличается от всех остальных программ книги, потому что в данном случае не применяется переключение страниц — вместо этого мы непосредственно обновляем содержимое экрана. Такой подход имеет ряд последствий.
Во-первых, отсутствие вторичного буфера затрудняет модификацию программы и включение в нее нескольких поверхностей. Поскольку все поверхности будут напрямую записываться на первичную поверхность, в случае их перекрытия возникнет неприятное мерцание.
Во-вторых, мы уже не можем просто стереть фоновое изображение. В других программах мы стираем весь вторичный буфер, строим новый кадр и обновляем экран; никакого мерцания при этом не возникает. Стирание вторичного буфера в программе Smear вызовет заметное мерцание, потому что стертый фон будет отображаться во время вывода нового кадра. Программа названа Smear (то есть «размазывание») как раз потому, что фон не стирается, в результате при перемещении поверхности остается смазанный след.
В-третьих, программа работает быстрее (именно поэтому данная методика использована в этой программе). Обновление экрана происходит более эффективно, потому что оно не сопровождается стиранием буфера и переключением страниц.
Класс SmearWinОсновная функциональность программы Smear обеспечивается классом SmearWin (см. листинг 6.4).