Интерактивное
управление положением и ориентацией
Теперь хочется
рассмотреть трехмерный объект с разных сторон. Удобнее это делать с помощью
мыши. Документация MSDN содержит весьма скудные сведения относительно aux-функций,
но в примерах все же можно найти какую-то информацию. Оказывается для введения
реакции на мышиные события надо ввести в main следующие строки и, конечно, написать
функции обработки
auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSELOC,OnLMouseMove);
auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSELOC,OnRMouseMove); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,OnButtonDown);
auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSEDOWN,OnButtonDown);
Обратите внимание,
что дих разделяет WM_MOUSEMOVE на две (в общем случае на три) кнопки. Это нам
как раз подходит, так как мы хотим левой кнопкой вращать, а правой удалять-приближать
(делать zooming) изображение. События отпускания кнопок нам не понадобились
по причине того, что обработчики AUX_MOUSELOC (читай WM_MOUSEMOVE) вызываются
только в случае, если соответствующие кнопки нажаты. Поэтому не нужно поднимать
и отпускать флаг захвата объекта мышью. Именно это нам и нужно. Как легко, когда
кто-то все продумал! Мы не делаем различия между нажатиями левой и правой кнопки,
так как задача у них общая — запомнить текущие координаты указателя мыши. Вставьте
декларации четырех функций, а затем приступим к их созданию. Так как сейчас
мы не имеем классов для инкапсуляции переменных состояния мыши, то придется
добавить глобальные переменные:
int
giX, giY; // Текущая позиция указателя мыши
Тела глобальных
функций обработки вы должны вставить до того места, в котором они вызываются.
Алгоритм изменения параметров gdAngleX, gdAngleX и gdTransZ очевиден, но обратите
внимание на детали. Например, как добывать координаты курсора мыши. Их присылает
система, a AUX хранит их в структуре data, информацию о которой вы можете получить
разве что в файле заголовков Glaux.h:
static
void _stdcall OnButtonDown(AUX_EVENTREC
*pEvent)
{
//======
Запоминаем координаты мыши
giX
= pEvent->data[AUX_MOUSEX];
giY
= pEvent->data[AUX_MOUSEY];
}
static
void _stdcall OnLMouseMove(AUX_EVENTREC *pEvent)
{
//======
Узнаем текущие координаты
int
x = pEvent->data[AUX_MOUSEX];
int
у = pEvent->data[AUX_MOUSEY];
//======
Изменяем углы поворота пропорционально
//======
смещению мыши
gdAngleX
+= (у - giY)/10.f;
gdAngleY
+= (x - giX)/10.f;
//======
Запоминаем координаты мыши
giX
= x
; giY = у; >
Static
void _stdcall OnRMouseMove(AUX_EVENTREC *pEvent)
int
x = pEvent->data[AUX_MOUSEX];
int
у = pEvent->data[AUX_MOUSEY] ;
//=====<=
На сколько удалить или приблизить
double
dx = (x - giX)/200.f;
double
dy = (y - giY)/200.f;
//======
Удаляем или приближаем
gdTransZ
+= (dx + dy)/2.f;
//======
Запоминаем координаты мыши
giX
= x; giY = y;
}
Запустите и
опробуйте. Кубик должен управляться, но в обработке мышиных событий присутствует
явная ошибка. Для того чтобы ее увидеть, нажмите правую кнопку и выведите курсор
мыши за пределы окна влево. Изображение исчезло. один из слушателей наших курсов
(Халип В. М. E-mail: viktor@mail.ru) самостоятельно нашел объяснение этому казусу
и устранил дефект. Для того чтобы обнаружить его, вставьте в список директив
препроцессора еще одну — #include <stdio.h>, а в функцию OnRMouseMove
— вызов printf ("\n%d",x);. Теперь координата курсора мыши будет выводиться
в текстовое окно консольного приложения. Повторите опыт с правой кнопкой и убедитесь
в том, что при выходе за пределы окна (влево), координата х получает недопустимое
значение (>65000). Для устранения дефекта достаточно заменить строки:
int
x = pEvent->data[AUX_MOUSEX];
int
у = pEvent->data[AUX_MOUSEY];
на
short
x
= pEvent->data[AUX_MOUSEX];
short
у = pEvent->data[AUX_MOUSEY];
в функциях
OnLMouseMove и OnRMouseMove. Теперь повторите опыт и убедитесь в том, что, переходя
через границу окна, координата х изменяется монотонно и приобретает отрицательные
значения. Чтобы быть последовательным, замените тип глобальных данных для хранения
текущей позиции курсора мыши. Вместо int giX, giY; вставьте short giX, giY;.
Объяснение эффекта мы оставляем читателю в качестве упражнения по информатике.