공부 중 메모/DirectX

2. Timer, Input, Write

라이피 (Lypi) 2018. 12. 17. 20:51
반응형

# Timer : 게임내 시간을 측정하는 기능
# Input : 키 입력을 받는 기능
# Write : 화면에 간단한 텍스트를 띄우는 기능.

# 타이머와 입력한 키에 대한 정보를 텍스트로 띄어주는 내용.

# 여기까지 1차적인 라이브러리 내용이다.

DxTimer.h

#pragma once
#include "stdHeader_L.h"

namespace Lypi
{
	class DxTimer
	{
	private:
		LARGE_INTEGER  m_liFrequency;  //초당 주파수
		LARGE_INTEGER  m_liCurTime;    //현재 프레임에서의 시간
		LARGE_INTEGER  m_liBefTime;    //이전 프레임에서의 시간
		LARGE_INTEGER  m_liBef1sTime;  //1초전 시간

		float m_dGameTime;
		float m_dSPF;
		int   m_iFPS;

		int   m_iFPSGether;   //초당 프레임 누적용

		LARGE_INTEGER m_BefTickTime;
		LARGE_INTEGER m_curTickTime;


	public:
		bool	Init();
		bool	Frame();
		bool	Render();
		bool	Release();

		bool    tickAlram(double tick);

		float  getGameTime();
		float  getSPF();
		int     getFPS();
	public:
		DxTimer();
		virtual ~DxTimer();
	};
}

DxTimer.cpp

#include "DxTimer.h"

namespace Lypi
{
	float g_dSPF;

	DxTimer::DxTimer()
	{
		m_liFrequency.QuadPart = 0;
		m_liCurTime.QuadPart = 0;
		m_liBefTime.QuadPart = 0;
		m_liBef1sTime.QuadPart = 0;

		m_iFPSGether = 0;

		m_BefTickTime.QuadPart = 0;
		m_curTickTime.QuadPart = 0;

		//시스템의 주파수 변동폭을 얻어옴 //
		QueryPerformanceFrequency((LARGE_INTEGER*)&m_liFrequency);
	}

	bool	DxTimer::Init()
	{
		//일단 카운터 가져오기
		QueryPerformanceCounter(&m_liBefTime);
		QueryPerformanceCounter(&m_liBef1sTime);
		QueryPerformanceCounter(&m_BefTickTime);

		//타이머 지원 여부 확인
		if (m_liBefTime.QuadPart == 0) {
			return false;
		}

		m_iFPSGether = 0;

		return true;
	}

	bool	DxTimer::Frame()
	{
		//현재 시간 확인
		QueryPerformanceCounter(&m_liCurTime);
		m_dSPF = static_cast<float>(m_liCurTime.QuadPart - m_liBefTime.QuadPart) / static_cast<float>(m_liFrequency.QuadPart);
		g_dSPF = m_dSPF;
		m_liBefTime = m_liCurTime;

		m_dGameTime += m_dSPF;

		static double fpsPivot;

		fpsPivot += m_dSPF;
		m_iFPSGether++;
		if (fpsPivot >= 1.0)
		{
			m_iFPS = m_iFPSGether;
			m_iFPSGether = 0;
			fpsPivot -= 1.0;
		}

		return true;
	}

	bool	DxTimer::Render()
	{
		return true;
	}
	bool	DxTimer::Release()
	{
		return true;
	}

	bool    DxTimer::tickAlram(double tick)
	{
		QueryPerformanceCounter(&m_curTickTime);
		if (((m_curTickTime.LowPart - m_BefTickTime.LowPart) / (m_liFrequency.LowPart)) >= tick) {
			m_BefTickTime = m_curTickTime;
			return true;
		}
		return false;
	}


	float  DxTimer::getGameTime()
	{
		return m_dGameTime;
	}
	float  DxTimer::getSPF()
	{
		return m_dSPF;
	}
	int     DxTimer::getFPS()
	{
		return m_iFPS;
	}

	DxTimer::~DxTimer()
	{

	}
}

DxInput.h

#pragma once
#include "stdHeader_L.h"

namespace Lypi
{
#define KeyStateCount 256
#define DataBufferSize 16

	enum push
	{
		p_FREE = 0,
		p_DOWN = 1,
		p_HOLD = 2,
		p_UP = 3,
	};

	struct MouseInfo
	{
		POINT xy;

		push left;
		push right;
		push middle;
	};

	class DxInput
	{
	public:
		LPDIRECTINPUT8 m_pDxInput;
		LPDIRECTINPUTDEVICE8 m_pDxKeypad;
		LPDIRECTINPUTDEVICE8 m_pDxMouse;

		BYTE  m_KeyCurState[KeyStateCount];
		BYTE  m_KeyBefState[KeyStateCount];
		DIMOUSESTATE m_MouseCurState;
		DIMOUSESTATE m_MouseBefState;

		MouseInfo m_MouseState;

	public:
		bool Init();
		bool Frame();
		bool Render();
		bool Release();

		bool ResetDevice();
		bool ResetResource();

	public:
		bool InitDirectInput(bool keypad, bool mouse);
		bool KeyProcess();
		bool MouseProcess();

		void SetAcquire(bool bActive);
		void DeviceAcquire();
		void DeviceUnacquire();

		bool IsKeyDown(DWORD dwKey);
		bool IsKeyUP(DWORD dwKey);
		bool IsKeyDownOnce(DWORD dwKey);

		MouseInfo getMouseInfo();

	public:
		static DxInput& GetInstance();

	protected:
		DxInput();
		virtual ~DxInput();
	};

#define I_Input DxInput::GetInstance()
}

DxInput.cpp

#include "DxInput.h"

namespace Lypi
{

	DxInput& DxInput::GetInstance()
	{
		static DxInput inst;
		return inst;
	}

	DxInput::DxInput()
	{
		m_pDxInput = nullptr;
		m_pDxKeypad = nullptr;
		m_pDxMouse = nullptr;
	}

	bool DxInput::Init()
	{
		//프로그램 시작시 한번만 초기화 되면 되는 거면 생성자에서,
		//필요할 때 한번씩 초기화 시켜줘야하는 거면 Init에서.
		ZeroMemory(&m_KeyBefState, sizeof(BYTE)*KeyStateCount);
		ZeroMemory(&m_KeyCurState, sizeof(BYTE)*KeyStateCount);

		ZeroMemory(&m_MouseBefState, sizeof(DIMOUSESTATE));
		ZeroMemory(&m_MouseCurState, sizeof(DIMOUSESTATE));

		return true;
	}

	bool DxInput::Frame()
	{
		if (!KeyProcess() || !MouseProcess()) {
			return false;
		}

		return true;
	}

	bool DxInput::Render()
	{
		return true;
	}

	bool DxInput::Release()
	{
		if (m_pDxInput) {
			if (m_pDxKeypad) {
				m_pDxKeypad->Unacquire();
				m_pDxKeypad->Release();
				m_pDxKeypad = nullptr;
			}

			if (m_pDxMouse) {
				m_pDxMouse->Unacquire();
				m_pDxMouse->Release();
				m_pDxMouse = nullptr;
			}

			m_pDxInput->Release();
			m_pDxInput = nullptr;
		}

		return true;
	}


	bool DxInput::InitDirectInput(bool keypad, bool mouse)
	{
		HRESULT hr;

		if (m_pDxKeypad || m_pDxMouse) {
			return true;
		}

		V_FRETURN(DirectInput8Create(g_hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&m_pDxInput, NULL));

		if (keypad) {
			V_FRETURN(m_pDxInput->CreateDevice(GUID_SysKeyboard, &m_pDxKeypad, NULL));
			V_FRETURN(m_pDxKeypad->SetDataFormat(&c_dfDIKeyboard));

			if (FAILED(hr = m_pDxKeypad->SetCooperativeLevel(g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND | DISCL_NOWINKEY))) {
				while (m_pDxKeypad->Acquire() == DIERR_INPUTLOST);

				if (FAILED(m_pDxKeypad->SetCooperativeLevel(g_hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND | DISCL_NOWINKEY))) {
					return false;
				}
			}

			while (m_pDxKeypad->Acquire() == DIERR_INPUTLOST);
		}

		if (mouse) {
			V_FRETURN(m_pDxInput->CreateDevice(GUID_SysMouse, &m_pDxMouse, NULL));
			V_FRETURN(m_pDxMouse->SetDataFormat(&c_dfDIMouse));

			if (FAILED(m_pDxMouse->SetCooperativeLevel(g_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) {
				while (m_pDxMouse->Acquire() == DIERR_INPUTLOST);

				if (FAILED(m_pDxMouse->SetCooperativeLevel(g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) {
					return false;
				}
			}

			while (m_pDxMouse->Acquire() == DIERR_INPUTLOST);
		}

		return true;
	}

	void DxInput::DeviceAcquire()
	{
		if (m_pDxKeypad) {
			m_pDxKeypad->Acquire();
		}

		if (m_pDxMouse) {
			m_pDxMouse->Acquire();
		}
	}

	void DxInput::DeviceUnacquire()
	{
		if (m_pDxKeypad) {
			m_pDxKeypad->Unacquire();
		}

		if (m_pDxMouse) {
			m_pDxMouse->Unacquire();
		}
	}

	void DxInput::SetAcquire(bool bActive)
	{
		if (bActive) {
			DeviceAcquire();
		}
		else {
			DeviceUnacquire();
		}
	}

	bool DxInput::KeyProcess()
	{
		memcpy(&m_KeyBefState, &m_KeyCurState, sizeof(BYTE) * KeyStateCount);


		ZeroMemory(m_KeyCurState, sizeof(BYTE)*KeyStateCount);
		if (!m_pDxKeypad) {
			return false;
		}

		if (FAILED(m_pDxKeypad->GetDeviceState(KeyStateCount, m_KeyCurState))) {
			while (m_pDxKeypad->Acquire() == DIERR_INPUTLOST) {
				m_pDxKeypad->Acquire();
			}
			return true;
		}

		return true;
	}

	bool DxInput::MouseProcess()
	{
		memcpy(&m_MouseBefState, &m_MouseCurState, sizeof(DIMOUSESTATE));

		ZeroMemory(&m_MouseCurState, sizeof(DIMOUSESTATE));

		if (!m_pDxMouse) {
			return false;
		}

		if (FAILED(m_pDxMouse->GetDeviceState(sizeof(DIMOUSESTATE), &m_MouseCurState))) {
			while (m_pDxMouse->Acquire() == DIERR_INPUTLOST) {
				m_pDxMouse->Acquire();
			}

			return true;
		}

		return true;
	}

	bool DxInput::ResetDevice()
	{
		Release();
		Init();
		return true;
	}

	bool DxInput::ResetResource()
	{
		return true;
	}

#define KEYDOWN(key)	(((m_KeyCurState[key]) & 0x80) ? true : false)
#define KEYUP(key)		(((m_KeyCurState[key]) & 0x80) ? false : true)

	bool DxInput::IsKeyDown(DWORD dwKey)
	{
		if (KEYDOWN(dwKey)) {
			return true;
		}
		return false;
	}

	bool DxInput::IsKeyUP(DWORD dwKey)
	{
		if (m_KeyBefState[dwKey] & 0x80) {
			if (KEYUP(dwKey)) {
				return true;
			}
		}
		return false;
	}

	bool DxInput::IsKeyDownOnce(DWORD dwKey)
	{
		if (!(m_KeyBefState[dwKey] & 0x80)) {
			if (KEYDOWN(dwKey)) {
				return true;
			}
		}
		return false;
	}

	MouseInfo DxInput::getMouseInfo()
	{
		MouseInfo ret;
		POINT MousePos;

		GetCursorPos(&MousePos);
		ScreenToClient(g_hWnd, &MousePos);

		ret.xy = MousePos;

		ret.xy.x = MousePos.x * g_rtClient.right / (g_rtClient.right + g_rtWindow.left);
		ret.xy.y = MousePos.y * g_rtClient.bottom / (g_rtClient.bottom + g_rtWindow.top);

		for (int iB = 0; iB < 3; iB++)
			if (m_MouseBefState.rgbButtons[iB] & 0x80) {
				if (m_MouseCurState.rgbButtons[iB] & 0x80) {
					switch (iB) {
						case 0: ret.left = p_HOLD;
						case 1: ret.right = p_HOLD;
						case 2: ret.middle = p_HOLD;
					}
				}
				else {
					switch (iB) {
						case 0: ret.left = p_UP;
						case 1: ret.right = p_UP;
						case 2: ret.middle = p_UP;
					}
				}
			}
			else {
				if (m_MouseCurState.rgbButtons[iB] & 0x80) {
					switch (iB) {
						case 0: ret.left = p_DOWN;
						case 1: ret.right = p_DOWN;
						case 2: ret.middle = p_DOWN;
					}
				}
				else {
					switch (iB) {
						case 0: ret.left = p_FREE;
						case 1: ret.right = p_FREE;
						case 2: ret.middle = p_FREE;
					}
				}
			}

			for (int iB = 0; iB < 3; iB++) {
				m_MouseBefState.rgbButtons[iB] = m_MouseCurState.rgbButtons[iB];
			}

			return ret;
	}

	DxInput::~DxInput()
	{
		Release();
	}
}

DxWrite.h

#pragma once
#include "stdHeader_L.h"

namespace Lypi
{
	class DxWrite
	{
	protected:
		double m_dDpiScaleX;  //화면 스케일 (출력 영역의 크기를 지정할 때 사용된다.) 
		double m_dDpiScaleY;  //화면 스케일 (출력 영역의 크기를 지정할 때 사용된다.)
		FLOAT m_FDpiX;        //화면의 인치당 도트수 (요즘 모니터는 대부분 96.0F이다.)
		FLOAT m_FDpiY;        //화면의 인치당 도트수 (요즘 모니터는 대부분 96.0F이다.)

		//DXGI에 독립적인 객체
		ID2D1Factory* m_pD2dFactory;       //d2d 팩토리
		IDWriteFactory* m_pDWriteFactory;  //DW 팩토리
		IDWriteTextFormat* m_pTextFormat;  //텍스트포맷

		//DXGI에 종속적인 객체
		ID2D1RenderTarget* m_pD2dRT;       //d2d 렌더타켓뷰
		ID2D1SolidColorBrush* m_pD2dSCB;   //d2d 브러쉬

		//텍스트 포맷 관련
		D2D1_RECT_F m_D2rtLayoutRect;
		D2D1_COLOR_F m_D2dTextColor;

	public:
		//초기화
		bool Init();
		bool Set(IDXGISurface1* m_pSurface);

		//객체 생성 및 소멸
		HRESULT CreateDeviceIR();
		HRESULT CreateDeviceR(IDXGISurface1* pSurface);
		void DiscardDeviceIR();
		void DiscardDeviceR();

		//포맷 변경
		void SetAlignment(DWRITE_TEXT_ALIGNMENT textAlignment, DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment);
		void SetlayoutRt(FLOAT left, FLOAT top, FLOAT right, FLOAT bottom);
		void SetTextPos(const D2D1_MATRIX_3X2_F&amp; transform = Matrix3x2F::Identity());
		ColorF SetTextColor(ColorF color);

		//텍스트 그리기
		void DrawTextBegin();
		bool DrawText(TCHAR* pText);
		void DrawTextEnd();

		//전체 삭제
		bool Release();

	public:
		DxWrite();
		virtual ~DxWrite();
	};

}

DxWrite.cpp

#include "DxWrite.h"

namespace Lypi
{
	DxWrite::DxWrite()
	{
		m_pD2dFactory = nullptr;
		m_pD2dRT = nullptr;
		m_pD2dSCB = nullptr;

		m_pDWriteFactory = nullptr;
		m_pTextFormat = nullptr;

		m_dDpiScaleX = 0;
		m_dDpiScaleY = 0;
		m_FDpiX = 0;
		m_FDpiY = 0;

		//흰색을 기본값으로 함.
		m_D2dTextColor = ColorF(1, 1, 1, 1);
	}

	//객체 생성
	HRESULT DxWrite::CreateDeviceIR()
	{
		HRESULT hr;
		//D2D 팩토리 생성
		hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2dFactory);

		//사실 어차피 96이고 나누면 1이다(..)
		m_pD2dFactory->GetDesktopDpi(&m_FDpiX, &m_FDpiY);
		m_dDpiScaleX = m_FDpiX / 96.0;
		m_dDpiScaleY = m_FDpiY / 96.0;

		//DW 팩토리 생성
		if (SUCCEEDED(hr)) {
			hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), (IUnknown**)&m_pDWriteFactory);
		}

		//텍스트 포맷 생성
		if (SUCCEEDED(hr)) {
			hr = m_pDWriteFactory->CreateTextFormat(
				_T("고딕"),
				NULL,
				DWRITE_FONT_WEIGHT_NORMAL,
				DWRITE_FONT_STYLE_NORMAL,
				DWRITE_FONT_STRETCH_ULTRA_EXPANDED,
				15.0f,
				_T("ko-kr"),
				&m_pTextFormat
			);
		}

		return hr;
	}

	HRESULT DxWrite::CreateDeviceR(IDXGISurface1* pSurface)
	{
		HRESULT hr = S_OK;
		//렌더링 옵션을 설정하는 구조체.
		D2D1_RENDER_TARGET_PROPERTIES props;
		props.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
		props.pixelFormat = PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE);
		props.dpiX = m_FDpiX;
		props.dpiY = m_FDpiY;
		props.usage = D2D1_RENDER_TARGET_USAGE_NONE;
		props.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;

		//D2D렌더타겟 생성
		hr = m_pD2dFactory->CreateDxgiSurfaceRenderTarget(pSurface, &props, &m_pD2dRT);
		if (FAILED(hr)) {
			return hr;
		}

		//정해진 색 사용시 ColorF(ColorF::Coral)
		V_FRETURN(m_pD2dRT->CreateSolidColorBrush(m_D2dTextColor, &m_pD2dSCB));

		return hr;
	}

	//객체 삭제
	void DxWrite::DiscardDeviceIR()
	{
		SAFE_RELEASE(m_pD2dFactory);
		SAFE_RELEASE(m_pDWriteFactory);
		SAFE_RELEASE(m_pTextFormat);
	}

	void DxWrite::DiscardDeviceR()
	{
		SAFE_RELEASE(m_pD2dRT);
		SAFE_RELEASE(m_pD2dSCB);
	}

	//초기화
	bool DxWrite::Init()
	{
		HRESULT hr;
		//독립적인 객체 생성
		V(CreateDeviceIR());
		return true;
	}

	bool DxWrite::Set(IDXGISurface1* m_pSurface)
	{
		HRESULT hr;
		//종속적인 객체 생성 (화면 크기 변경시 재생성함)
		D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2dFactory);
		V(CreateDeviceR(m_pSurface));
		return true;
	}

	//포맷 변경
	void DxWrite::SetAlignment(DWRITE_TEXT_ALIGNMENT textAlignment, DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment)
	{
		//TextFormat 지정
		m_pTextFormat->SetTextAlignment(textAlignment);
		m_pTextFormat->SetParagraphAlignment(paragraphAlignment);
	}

	void DxWrite::SetlayoutRt(FLOAT left, FLOAT top, FLOAT right, FLOAT bottom)
	{
		m_D2rtLayoutRect = RectF(left, top, right, bottom);
	}

	void DxWrite::SetTextPos(const D2D1_MATRIX_3X2_F& transform)
	{
		m_pD2dRT->SetTransform(transform);
	}

	ColorF DxWrite::SetTextColor(ColorF color)
	{
		ColorF oldColor(m_D2dTextColor.r, m_D2dTextColor.g, m_D2dTextColor.b, m_D2dTextColor.a);
		m_D2dTextColor = color;
		m_pD2dSCB->SetColor(m_D2dTextColor);

		return oldColor;
	}

	//DrawText
	void DxWrite::DrawTextBegin()
	{
		m_pD2dRT->BeginDraw();
	}

	bool DxWrite::DrawText(TCHAR* pText)
	{
		//D2D Draw는 Begin과 End사이에서 이루어져야한다.

		if (m_pD2dRT && m_pD2dSCB) {
			//텍스트 출력
			m_pD2dRT->DrawTextW(pText, (UINT)_tcslen(pText), m_pTextFormat, m_D2rtLayoutRect, m_pD2dSCB);
		}

		return true;
	}

	void DxWrite::DrawTextEnd()
	{
		m_pD2dRT->EndDraw();
	}

	//전체 삭제
	bool DxWrite::Release()
	{
		DiscardDeviceIR();
		DiscardDeviceR();

		return true;
	}

	DxWrite::~DxWrite()
	{
		Release();
	}
}


#zCore 업데이트

zCore.h

#pragma once
#include "WinL.h"
#include "DxWrite.h"
#include "DxTimer.h"
#include "DxInput.h"

namespace Lypi
{
	class zCore : public winL
	{
	protected:
		DxTimer    m_GameTimer;
		DxWrite    m_Font;

		bool m_swTimerRender;
		bool m_swKeyRender;
	public:
		bool ResetRT();

	public:
		//게임 전체적인 처리 순서에 대한 함수들. 게임에 관한 부분과 윈도우 생성에 관한 부분을 분리
		bool gameInit() override;
		bool gameRun() override;
		bool gameFrame() override;
		bool gamePreRender() override;
		bool gameRender() override;
		bool gamePostRender() override;
		bool gameRelease() override;

	public:
		//클래스 각각에 대한 처리 순서에 관한 함수들. 
		virtual bool Init() { return true; };
		virtual bool Frame() { return true; };
		virtual bool PreRender() { return true; };
		virtual bool Render() { return true; };
		virtual bool PostRender() { return true; };
		virtual bool Release() { return true; };

		LRESULT	MsgProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

	public:
		zCore(LPCTSTR LWndName);
		virtual ~zCore();
	};

}

zCore.cpp

#include "zCore.h"

namespace Lypi
{

	zCore::zCore(LPCTSTR LWndName) : winL(LWndName)
	{
		m_swTimerRender = true;
		m_swKeyRender = true;
	}

	LRESULT	zCore::MsgProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
	{
		return 1;
	}

	bool zCore::ResetRT()
	{
		IDXGISurface1* pBackBuffer = nullptr;
		HRESULT hr = g_pSwapChain->GetBuffer(0, __uuidof(IDXGISurface), (void**)&pBackBuffer);

		m_Font.Set(pBackBuffer);

		if (pBackBuffer) {
			pBackBuffer->Release();
		}

		return true;
	}

	bool zCore::gameInit()
	{
		//디바이스 생성 작업 실행.
		InitDevice();
		m_GameTimer.Init();

		ResetRT();
		g_pWindow->CenterWindow();

		//SwapChain의 백버퍼 정보로 DXWrite객체 생성 
		IDXGISurface1* pBackBuffer = nullptr;
		g_pSwapChain->GetBuffer(0, __uuidof(IDXGISurface), (void**)&pBackBuffer);
		m_Font.Init();
		m_Font.Set(pBackBuffer);

		if (pBackBuffer) { pBackBuffer->Release(); }

		I_Input.InitDirectInput(true, true); //DXInput Device 생성
		I_Input.Init();	//DXInput 초기화

		Init();

		g_pD3dContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

		return true;
	}

	bool zCore::gameRun()
	{
		gameFrame();
		gamePreRender();
		gameRender();
		gamePostRender();
		return true;
	}

	bool zCore::gameFrame()
	{
		m_GameTimer.Frame();

		I_Input.Frame();
		if (I_Input.IsKeyDownOnce(DIK_9)) { m_swTimerRender = !m_swTimerRender; }
		if (I_Input.IsKeyDownOnce(DIK_0)) { m_swKeyRender = !m_swKeyRender; }

		Frame();


		return true;
	}

	bool zCore::gamePreRender()
	{
		float ClearColor[4] = { 0.1f, 0.2f, 0.3f, 1.0f }; //r,g,b,a
		g_pD3dContext->ClearRenderTargetView(m_pRenderTagetView, ClearColor);
		g_pD3dContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
		g_pD3dContext->OMSetRenderTargets(1, &m_pRenderTagetView, m_pDepthStencilView);

		DXGI_SWAP_CHAIN_DESC CurrentSD;
		g_pSwapChain->GetDesc(&CurrentSD);

		m_Font.DrawTextBegin();

		PreRender();

		return true;
	}

	bool zCore::gameRender()
	{
		Render();

		return true;
	}

	bool zCore::gamePostRender()
	{
		PostRender();

		TCHAR pBuffer[256];
		memset(pBuffer, 0, sizeof(TCHAR) * 256);

		m_Font.SetTextPos();
		m_Font.SetlayoutRt(0, 0, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);

		if (m_swTimerRender) {
			m_Font.SetAlignment(DWRITE_TEXT_ALIGNMENT_LEADING, DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
			m_Font.SetTextColor(ColorF(1, 1, 1, 1));

			_stprintf_s(pBuffer, _T("FPS:%d, SPF:%10.5f, GameTime:%10.2f"),
				m_GameTimer.getFPS(), m_GameTimer.getSPF(), m_GameTimer.getGameTime());
			m_Font.DrawText(pBuffer);
		}

		if (m_swKeyRender) {
			m_Font.SetAlignment(DWRITE_TEXT_ALIGNMENT_LEADING, DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
			m_Font.SetTextColor(ColorF(1, 0, 0, 1));

			int iCount = 0;

			static LONG MousePosX = I_Input.m_MouseCurState.lX;
			static LONG MousePosY = I_Input.m_MouseCurState.lY;
			static LONG MousePosZ = I_Input.m_MouseCurState.lZ;

			MousePosX += I_Input.m_MouseCurState.lX;
			MousePosY += I_Input.m_MouseCurState.lY;
			MousePosZ += I_Input.m_MouseCurState.lZ;

			_stprintf_s(pBuffer, _T("Mouse X:%ld, Y:%ld, Z:%ld"), MousePosX, MousePosY, MousePosZ);

			FLOAT iStartX = 0;
			FLOAT iStartY = (FLOAT)(50 + (20 * iCount));
			m_Font.SetlayoutRt(iStartX, iStartY, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);
			m_Font.DrawText(pBuffer);
			iCount++;

			for (int iKey = 0; iKey < KeyStateCount; iKey++) {
				if (I_Input.m_KeyCurState[iKey] & 0x80) {
					_stprintf_s(pBuffer, _T("Key State : 0x%02x : %d"), iKey, I_Input.m_KeyCurState[iKey]);
					UINT iStartX = 0;
					UINT iStartY = 50 + (20 * iCount);
					m_Font.SetlayoutRt((FLOAT)iStartX, (FLOAT)iStartY, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);
					m_Font.DrawText(pBuffer);

					iCount++;
				}
			}

			for (int iKey = 0; iKey < 4; iKey++) {
				if (I_Input.m_MouseCurState.rgbButtons[iKey] & 0x80) {
					_stprintf_s(pBuffer, _T("Mouse Button State : %02d"), iKey);
					UINT iStartX = 0;
					UINT iStartY = 50 + (20 * iCount);
					m_Font.SetlayoutRt((FLOAT)iStartX, (FLOAT)iStartY, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);
					m_Font.DrawText(pBuffer);

					iCount++;
				}
			}
		}

		//IDXGISwapChain 객체를 사용하여 시연(출력)한다.
		//모든 렌더링 작업들은 present앞에서 이뤄져야 한다.
		m_Font.DrawTextEnd();
		g_pSwapChain->Present(0, 0);
		return true;
	}

	bool zCore::gameRelease()
	{
		Release();

		if (!I_Input.Release()) { return false; }
		if (!m_Font.Release()) { return false; }
		if (!m_GameTimer.Release()) { return false; }
		if (!CreanupDevice()) { return false; }

		return true;
	}


	zCore::~zCore()
	{
	}

}


반응형