Direct Input. Мышь.

Содержание статьи:

Введение.
Direct Input – инициализация.
Direct Input - Мышь.

Вступление.

к началу статьи
Сегодня я с чистой душей сел за написание очередной статьи – сессия позади, всё что можно было сдать, сдано. Всё что можно было защитить, защищено. Одним словом лепота. Это нельзя передать словами, когда самый страшный из возможных экзаменов (госэкзамен) остается позади (и вбитые в голову никчемные знания то же). Переполняемый именно такими радостными чувствами я сегодня поведаю Вам о Dirct Input’е. Точнее той его части которая отвечает за обработку мыши. Вы спросите: «Зачем нам это? Ведь win api предлагает хорошие возможности по работе с мышью и клавиатурой?». Оказывается недостаточно хорошие. Ведь если как следует нагрузить рендеррер (до заметных тормозов), то появится эффект последействия – кнопку вы отпустили, а камера/перс/курсор продолжает двигаться. Можно конечно упрятать рендерринг в отдельный поток, но тогда придется сделать у него достаточно низкий приоритет, что бы очередь сообщений, через которую проходят все сообщения от устройств управления, обрабатывалась с должной скоростью. Естественно это приведет к критическому падению производительности. К счастью DirectX предлагает нам удобный API для работы с устройствами ввода. Встречайте – Direct Input.

Direct Input – инициализация.

к началу статьи
Вспомните наши первые шаги в Direct3D – сначала мы создавали объект, затем девайс… Здесь все будет то же самое:
#include <windows.h>
#include <dinput.h>

#pragma comment ( lib , "dinput8.lib" )
#pragma comment ( lib , "dxguid.lib" )

class					cDIObject{
public:
	LPDIRECTINPUT8			Object;

	cDIObject( void ){Object = NULL;}
	~cDIObject(){}

	LPDIRECTINPUT8			operator->(){return( Object );}

	bool				InitDirectInput( HINSTANCE );
	void				Release( void );
};

cDIObject					DIObject;

bool					cDIObject::InitDirectInput( HINSTANCE hInstance ){
	//в этом классе мы создаем только объект
	if( DirectInput8Create( hInstance , DIRECTINPUT_VERSION ,
		IID_IDirectInput8 , ( void ** )&Object , NULL ) != DI_OK ){
			MessageBox( 0 , "Не удалось инициализировать DirectInput." , 
				"Ошибка" , 0 );
			return( false );
	}
	return( true );
}

void					cDIObject::Release( void ){
	if( Object ){
		Object->Release();
	}
}
Здесь ничего сложного нет, поэтому сразу перейдем к классу мыши:

Direct Input - Мышь.

к началу статьи
#define			DI_X		0
#define			DI_Y		1
#define			DI_Z		2

DIMOUSESTATE2	STD_DIMOUSEINPUT2;

class						cMouse{
	LPDIRECTINPUTDEVICE8			DIMouse;
public:
	bool					InitMouse( cDIObject & , HWND );
	~cMouse(){}
	void					Release( void );
	void					GetMouseState( void );
	bool					GetButtonState( int );
	int					GetOffset( int );
};
cMouse Mouse; Значение констант и глобальных объектов я поясню позже, а пока рассмотрим функцию инициализации:
bool					cMouse::InitMouse( cDIObject &DIObject , HWND hWnd ){
	
	//создание девайса
	if( DIObject->CreateDevice( GUID_SysMouse , &DIMouse , NULL ) != DI_OK ){
		MessageBox( 0 , "Ошибка создания девайса для мыши." , "Ошибка" , 0 );
		return( false );
	}

	//установка формата вывода
	//дело в том, что уже давно появились мышки
	//с более чем 3 кнопками, для их поддержки
	//создана структура DIDATAFORMAT
	//и её глобальный объект c_dfDIMouse2
	//если же хотите поддерживать только
	//трехкнопочные мышки, то используйте
	//объект c_dfDIMouse
	if( DIMouse->SetDataFormat( &c_dfDIMouse2 ) != DI_OK ){
		MessageBox( 0 , "Ошибка установки формата мыши." , "Ошибка" , 0 );
		return( false );
	}

	//установка режима работы мыши
	if( DIMouse->SetCooperativeLevel( hWnd , DISCL_BACKGROUND 
			| DISCL_NONEXCLUSIVE ) != DI_OK){
		MessageBox( 0 , "Ошибка установки Cooperative Level'а для мыши." , 
			"Ошибка" , 0 );
		return( false );
	}

	//получаем доступ к мыше
	if( DIMouse->Acquire() != DI_OK ){
		MessageBox( 0 , "Ошибка получения доступа к мыши." , "Ошибка." , 0 );
		return( false );
	}

	return( true );
}
Все самое сложное оказалось позади, теперь научимся считывать состояние мыши
//записываем состояние мыши в глобальный объект STD_DIMOUSEINPUT2
void					cMouse::GetMouseState( void ){
	if( !DIMouse ){
        	MessageBox( 0 , "Мышь не инициализирована." , "Ошибка" , 0 );
		exit( 0 );
	}
    
    	ZeroMemory( &STD_DIMOUSEINPUT2 , sizeof(STD_DIMOUSEINPUT2 ) );
	if( DIMouse->GetDeviceState( sizeof( DIMOUSESTATE2 ), &STD_DIMOUSEINPUT2 ) != DI_OK ){
		MessageBox( 0 , "Ошибка чтения состояния мыши." , "Ошибка" , 0 );
		exit( 0 );
	}
}
…читать состояния кнопок…
//состояние кнопок читается из глобального объекта DIMOUSESTATE2
bool					cMouse::GetButtonState( int mb ){

	if( !DIMouse ){
        	MessageBox( 0 , "Мышь не инициализирована." , "Ошибка" , 0 );
		exit( 0 );
	}

	return( STD_DIMOUSEINPUT2.rgbButtons[ mb ] & 0x80 );
}
...и узнавать на сколько сдвинулся курсор мыши
//кстати после вызова GetDeviceState
//курсор возвращается в исходное положение
int						cMouse::GetOffset( int _MODE ){

	if( !DIMouse ){
        MessageBox( 0 , "Мышь не инициализирована." , "Ошибка" , 0 );
		exit( 0 );
	}

	switch( _MODE ){
		case( DI_X ):return( STD_DIMOUSEINPUT2.lX );break;
		case( DI_Y ):return( STD_DIMOUSEINPUT2.lY );break;
		case( DI_Z ):return( STD_DIMOUSEINPUT2.lZ );break;
	}

	MessageBox( 0 , "cMouse::GetOffset(...) : кривое значение _MODE." , "Ошибка" , 0 );

	return( 0 );
}

//освобождение ресурсов
void					cMouse::Release( void ){
	if( DIMouse )
		DIMouse->Release();
}
Собственно вот и все! Для закрепления материала рассмотрим следующий пример:
//инициализация
if( !DIObject.InitDirectInput( hInstance ) ){
	exit( 0 );
}

if( !Mouse.InitMouse( DIObject , hWnd ) ){
	exit( 0 );
}

//использование

Mouse.GetMouseState();
Mouse.GetOffset( DI_Y );//смещение по оси y
Mouse.GetOffset( DI_Z );//на сколько провернулось колесико мыши
Теперь точно все. Урок был простой, но полезный и важный, поэтому необходимо его быстренько впитать, а результаты быстренько применить на практике.

к началу статьи

ЗЫ: способ связи прежний dodonov_a_a@inbox.ru


Смежные вопросы:
Урок 1. Инициализация. Вершинные буфферы и камера.
Урок 2. Проигрывание медиа-файлов.
Урок 3. Автоматизация загрузки и управления аудио и видео ресурсами.
Урок 4. Текстурирование. Текстурный менеджер.
Урок 5. Шрифты в Direct3D.
Урок 6. Элементы управления.
Урок 7. Вершинные шейдеры версии 1.0.
Урок 8. Система частиц.
Урок 9. Рендерринг в текстуру.
Исходные коды.
© 2004-2005 Savardge.ru


Hosted by uCoz