Чтение онлайн

ЖАНРЫ

Графика для Windows средствами DirectDraw

Трухильо Стэн

Шрифт:

Переопределяя стандартную константу 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).

Листинг 6.4. Класс SmearWin

class SmearWin : public DirectDrawWin {

public:

 SmearWin;

protected:

 //{{AFX_MSG(SmearWin)

 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

 afx_msg void OnDestroy;

 afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);

 //}}AFX_MSG

 DECLARE_MESSAGE_MAP

private:

 BOOL CreateFlippingSurfaces;

private:

 int SelectDriver;

 int SelectInitialDisplayMode;

 BOOL CreateCustomSurfaces;

 void DrawScene;

 void RestoreSurfaces;

private:

 BOOL InitKeyboard;

 BOOL InitMouse;

private:

 LPDIRECTINPUT dinput;

 LPDIRECTINPUTDEVICE mouse;

 LPDIRECTINPUTDEVICE keyboard;

 LPDIRECTDRAWSURFACE sphere;

 int x, y;

};

В классе объявлены три обработчика:

• OnCreate

• OnDestroy

• OnActivate

Функция OnCreate инициализирует DirectInput, а также готовит к работе мышь и клавиатуру. Функция OnDestroy освобождает объекты DirectInput, инициализированные функцией OnCreate. Функция OnActivate захватывает клавиатуру в начале работы и при повторной активизации приложения.

Затем следует переопределенная функция DirectDrawWin::CreateFlippingSurfaces. Нам не нужна переключаемая первичная поверхность, которая по умолчанию предоставляется классом DirectDrawWin, поэтому мы переопределяем эту функцию и создаем первичную поверхность, неспособную к переключению страниц.

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

Затем класс SmearWin объявляет функции InitMouse и InitKeyboard. Функция OnCreate возлагает на них ответственность за инициализацию устройств.

Наконец, мы объявляем несколько переменных. Переменная dinput — указатель на интерфейс DirectInput, она используется для работы с DirectInput после инициализации. Переменные mouse и keyboard указывают на интерфейсы DirectInputDevice, они инициализируются функциями InitMouse и InitKeyboard соответственно. Указатель на поверхность sphere и целые переменные x и y предназначены для вывода и позиционирования единственной поверхности приложения.

Инициализация DirectInput

Функция OnCreate инициализирует DirectInput, а затем инициализирует мышь и клавиатуру функциями InitMouse и InitKeyboard. Она выглядит так:

int SmearWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {

 HRESULT r=DirectInputCreate(AfxGetInstanceHandle, DIRECTINPUT_VERSION, &dinput, 0);

 if (r!=DI_OK) {

AfxMessageBox("DirectInputCreate failed");

Поделиться с друзьями: