
여러 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;
};
턴제 시스템을 상태 패턴으로 작성
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;
};
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);
}
HWND 초기화 전에 DirectInput에서 Acquire()를 실행하면 E_ACCESSDENIED를 반환하는 문제가 있었다. WndProc()에서 WM_ACTIVATE 내에 Acquire()를 실행해주니 해결되었다.