[GTL] W01 - 게임잼

brights2ella·2025년 4월 5일
0

정글게임테크랩1기

목록 보기
2/14
post-thumbnail

https://youtu.be/gocEd3khGDI

Wrapping DirectX

여러 DirectX 리소스들을 래핑해서 사용.

// @Buffer.h - VertexBuffer, IndexBuffer, ConstantBuffer
template <typename T>
class Buffer {
public:
	Buffer(ID3D11Device* device) : _device(device) {};
	virtual ~Buffer() { 
		if (_buffer)
			_buffer->Release(); 
	};

	ID3D11Buffer* Get() { return _buffer; }
	UINT32 GetStride() { return _stride; }
	UINT32 GetOffset() { return _offset; }
	UINT32 GetCount() { return _count; }

	virtual void Create(const std::vector<T>&) abstract;

protected:
	ID3D11Device* _device;
	ID3D11Buffer* _buffer = nullptr;

	UINT32 _stride = 0;
	UINT32 _offset = 0;
	UINT32 _count = 0;
};

// @Shader.h - VertexShader, IndexShader
class Shader {
public:
	Shader(ID3D11Device* device) : _device(device) {};
	virtual ~Shader() {
		_blob->Release();
	};

	virtual void Create(const std::wstring& path, const std::string& name, const std::string& version) abstract;
	ID3DBlob* GetBlob() { return _blob; }

protected:
	void LoadShaderFromFile(const std::wstring& path, const std::string& name, const std::string& version);

protected:
	std::wstring _path;
	std::string _name;
	ID3D11Device* _device;
	ID3DBlob* _blob;
};

// @States.h - RasterizerState, SamplerState, BlendState
class State {
public:
	State(ID3D11Device* device) : _device(device) {};
	virtual ~State() {};

protected:
	ID3D11Device* _device;
};

State Pattern

턴제 시스템을 상태 패턴으로 작성

class IngameState;
class IngameManager : public GameObject {
	using Super = GameObject;
	static IngameManager* _instance;
	GameObject(nullptr, nullptr) {};
	
public:
	IngameManager();
	~IngameManager();
	static const double TURNTIME;
	
	void Update(double deltaTime) override;
	void ChangeState(IngameState* state);
	void GameOver(int winPlayerIndex);

	std::vector<Player*> players;

	void StartTimer();
	void StopTimer();
	double GetTimerTime();
private:
	IngameState* _state;
	double _startTimerTime;
	bool _timerState;
	
};

class IngameState {
public:
	IngameState(IngameManager* context, int turnedPlayerIndex);
	virtual ~IngameState() {};
	virtual void Reserve() abstract;
	virtual void Update() abstract;

protected:
	IngameManager* _context;
	int _turnedPlayerIdx;
};


class InitReadyState: public IngameState {
	using Super = IngameState;
public:
	InitReadyState(IngameManager* context, int turnedPlayer) : Super(context, turnedPlayer) {};
	void Reserve() override;
	void Update() override;
};

class MoveAndShotState : public IngameState {
	using Super = IngameState;
public:
	MoveAndShotState(IngameManager* context, int turnedPlayer) : Super(context, turnedPlayer) {};
	void Reserve() override;
	void Update() override;
};

class WaitingAfterShotState : public IngameState {
	using Super = IngameState;
public:
	WaitingAfterShotState(IngameManager* context, int turnedPlayer) : Super(context, turnedPlayer) {};
	void Reserve() override;
	void Update() override;
};

class GameOverState : public IngameState {
	using Super = IngameState;
public:
	GameOverState(IngameManager* context, int winPlayerIndex) : Super(context, winPlayerIndex) {};
	void Reserve() override;
	void Update() override;
};

TroubleShooting

ImGui와 DirectXInput의 호환 문제

Github Commit

DirectXInput을 사용하면서 ImGui를 병행하려니 DirectXInput이 Input을 모두 후킹해버려서 ImGui의 Input이 먹히질 않는 문제가 있었다.

그래서 아래처럼 ImGui::GetIO() 에다가 좌표를 직접 넣어주는 식으로 처리했다.

void GuiController::NewFrame()
{
	ImGui_ImplDX11_NewFrame();
	ImGui_ImplWin32_NewFrame();
	ImGui::NewFrame();

	int mx, my;
	Input::Instance()->GetMouseLocation(mx, my); // DirectXInput에서 얻어온 좌표
	_io->MousePos.x = static_cast<float>(mx);
	_io->MousePos.y = static_cast<float>(my);
	_io->MouseDown[0] = Input::Instance()->IsMouseButtonDown(0);
	_io->MouseDown[1] = Input::Instance()->IsMouseButtonDown(1);
}

그마저도 좌표가 살짝 안맞는 듯이, gui 리사이징이 안 돼서 아래와 같이 수정하였다.

void GuiController::NewFrame()
{
	ImGui_ImplDX11_NewFrame();
	ImGui_ImplWin32_NewFrame();
	ImGui::NewFrame();

	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hWnd, &p); // HWND에서 직접 얻어온 좌표
	_io->MousePos.x = static_cast<float>(p.x);
	_io->MousePos.y = static_cast<float>(p.y);
	_io->MouseDown[0] = Input::Instance()->IsMouseButtonDown(0);
	_io->MouseDown[1] = Input::Instance()->IsMouseButtonDown(1);
}

DirectXInput

Github Commit

HWND 초기화 전에 DirectInput에서 Acquire()를 실행하면 E_ACCESSDENIED를 반환하는 문제가 있었다. WndProc()에서 WM_ACTIVATE 내에 Acquire()를 실행해주니 해결되었다.

참고: https://linkmemo.tistory.com/4

0개의 댓글