[DirectX 11] 8. Raw Mouse Input (마우스의 상대적 좌표 나타내기)

psj98·2022년 11월 16일
0

개요

이전 단계인 "7. Mouse Input (마우스 입력)" 에서는 Mouse 이벤트를 처리했습니다.

이번 단계에서는 마우스의 상대적 좌표를 나타내보려고 합니다.


MouseClass

  • MouseEvent 타입과 좌표를 저장하는 OnMouseMoveRaw() 함수를 추가합니다.

MouseClass.h

#pragma once
#include "MouseEvent.h"
#include <queue>

using namespace std;

class MouseClass
{
public:
	/* 각 타입에 따라 mouseBuffer에 마우스 이벤트 타입, x, y 좌표 저장 */
	/* 동일 */
	void OnMouseMoveRaw(int x, int y);
    
    /* 동일 */
};

MouseClass.cpp

#include "MouseClass.h"

/* 마우스를 움직였을 때 (상대적 좌표) */
void MouseClass::OnMouseMoveRaw(int x, int y)
{
	this->mouseBuffer.push(MouseEvent(MouseEvent::EventType::RAW_MOVE, x, y));
}

WindowContainer

  • 구조체로 마우스의 좌표인 x, y를 선언합니다.
    마우스 이벤트 타입을 Enum으로 선언합니다.
    마우스 이벤트에 따라 type과 key를 지정합니다.

WindowContainer.h

#pragma once
#include "RenderWindow.h"
#include "Keyboard/KeyboardClass.h"
#include "Mouse/MouseClass.h"

class WindowContainer
{
public:
	WindowContainer(); // 추가
	LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
	RenderWindow render_window;
	KeyboardClass keyboard;
	MouseClass mouse;
private:

};

WindowContainer.cpp

#include <memory>
#include "WindowContainer.h"

/* RAW INPUT에 대한 구조체 생성 및 등록 */
WindowContainer::WindowContainer()
{
	static bool raw_input_initialized = false;
	if (raw_input_initialized == false)
	{
    	/* 구조체 생성 */
		RAWINPUTDEVICE rid;
		rid.usUsagePage = 0x01; // 원시 데스크탑 컨트롤
		rid.usUsage = 0x02; // 마우스
		rid.dwFlags = 0;
		rid.hwndTarget = NULL;

		if (RegisterRawInputDevices(&rid, 1, sizeof(rid)) == FALSE)
		{
			ErrorLogger::Log(GetLastError(), "Failed to register raw input devices.");
			exit(-1);
		}

		raw_input_initialized = true;
	}
}

LRESULT WindowContainer::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
    /* -- 키보드 메시지 -- */
	/* 동일 */

	/* -- 마우스 메시지 -- */
	/* 동일 */
    
    /* RAW_INPUT을 가져옴 */
	case WM_INPUT:
	{
		UINT dataSize;
        /* dataSize를 얻어냄 */
		GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER));

		if (dataSize > 0)
		{
			unique_ptr<BYTE[]> rawdata = make_unique<BYTE[]>(dataSize); // 크기 재조정
			if (GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, rawdata.get(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
			{
				RAWINPUT* raw = reinterpret_cast<RAWINPUT*>(rawdata.get());
				if (raw->header.dwType == RIM_TYPEMOUSE)
				{
                	// x, y방향의 동작
					mouse.OnMouseMoveRaw(raw->data.mouse.lLastX, raw->data.mouse.lLastY);
				}
			}
		}

		return DefWindowProc(hwnd, uMsg, wParam, lParam); // WM_INPUT 메시지 처리
	}

	default:
		/* 처리되지 않은 모든 메시지의 디폴트 처리를 수행 */
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
}

GetRawInputData 함수

  1. 매개변수
  • HRAWINPUT : RAWINPUT 구조체에 대한 핸들
  • UINT : 명령 플래그
    • RID_HEADER : RAWINPUT 구조체에서 헤더 정보를 가져옴
    • RID_INPUT : RAW INPUT 구조체에서 RAW DATA를 가져옴
  • LPVOID : RAWINPUT 구조체에서 오는 데이터에 대한 포인터
    • pData가 NULL이면 필요한 버퍼 크기가 *pcbSize에 반환됨
  • PUINT : pData에 있는 데이터의 크기(바이트)
  • UINT : RAWINPUTHEADER 구조체의 크기(바이트)
  1. 반환값
  • pData가 NULL이고 함수가 성공하면 반환 값은 0
  • pData가 NULL이 아니고 함수가 성공하면 반환 값은 pData에 복사된 바이트 수
  • 오류가 있는 경우 반환 값은 (UINT)-1
  1. 참고자료 : GetRawInputData 함수

Engine.cpp

  • RAW INPUT 테스트
  • 실행 시, 상대적 위치로 나타납니다.
    • ex) X : 0, Y : 1 / X : -1, Y : 1 ...
void Engine::Update()
{
	/* RAW INPUT 테스트 */
	while (!mouse.MouseBufferIsEmpty())
	{
		MouseEvent me = mouse.ReadEvent();
		if (me.GetType() == MouseEvent::EventType::RAW_MOVE)
		{
			string outmsg = "X : ";
			outmsg += to_string(me.GetPosX());
			outmsg += ", Y : ";
			outmsg += to_string(me.GetPosY());
			outmsg += "\n";
			OutputDebugStringA(outmsg.c_str());
		}
	}
}
profile
SSAFY 9기

0개의 댓글