공부 중 메모/DirectX

4. Primitive Type

라이피 (Lypi) 2018. 12. 18. 21:45
반응형

Primitive Type

  # 여러가지 Topology 타입을 소개하기 위한 예제이지만 이후에는 이미지 디버깅 용도로 사용하게 된다.
  # 상수 버퍼를 사용하는 예제에서의 쉐이더를 쓰면 선이 안 나오니 주의. 그래서 상수 버퍼 예제를 이 다음으로 옮겼다.

샘플 업데이트

sample.h

#pragma once
#pragma comment(lib, "TLib.lib")

#include "zCore.h"
#include "mathHeader_L.h"

namespace Lypi
{

	class Sample : public zCore
	{
		// 버텍스 버퍼 및 레이아웃
		ID3D11Buffer*         m_pVertexBuffer;    //정점 버퍼 인터페이스
		ID3D11InputLayout*	  m_pVertexLayout;    //정점 레이아웃 인터페이스

												  // 버텍스 및 픽셀 쉐이더
		ID3D11VertexShader*     m_pVS;   //정점 쉐이더 인터페이스
		ID3D11PixelShader*      m_pPS;	 //픽셀 쉐이더 인터페이스

										 // 이미지 디버그용
		UINT    m_uPrimType;    //토폴로지 타입
		UINT    m_uCullMode;    //컬링모드
		UINT    m_uFillMode;    //와이어 프레임만 렌더링

		ID3D11RasterizerState*      m_pRS;   //래스터라이저 상태

	public:
		HRESULT		CreateVertexBuffer();  // 정점 버퍼 생성

		HRESULT		LoadShaderAndInputLayout();  // 정점 및 픽쉘 쉐이더 로딩 및 생성

		HRESULT		RSChange();                  // 래스터라이저 세팅 변경

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

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

}

sample.cpp

#include "sample.h"

namespace Lypi
{
	Sample::Sample(LPCTSTR LWndName) : zCore(LWndName)
	{
		m_pVertexBuffer = NULL;

		m_pVertexLayout = NULL;

		m_pVS = NULL;
		m_pPS = NULL;

		m_uPrimType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
		m_uCullMode = D3D11_CULL_BACK;
		m_uFillMode = D3D11_FILL_SOLID;
	}

	HRESULT Sample::CreateVertexBuffer()
	{
		HRESULT hr = S_OK;

		//시계 방향으로 지정할 것.
		Vector3 vertices[] =
		{
			{-0.75f, -0.5f, 0.1f},
			{-0.5f, 0.5f, 0.1f},
			{-0.25f, -0.5f, 0.1f},

			{0.0f, 0.5f, 0.5f},
			{0.25f, -0.5f, 0.5f},
			{0.5f, 0.5f, 0.5f},
		};

		UINT numVertices = sizeof(vertices) / sizeof(vertices[0]);
		// CD3D11_BUFFER_DESC : 버퍼 크기와 버퍼 용도만 결정하면 나머지는 기본값으로 생성해주는 구조체.
		CD3D11_BUFFER_DESC cbc(sizeof(Vector3) * numVertices, D3D11_BIND_VERTEX_BUFFER);

		D3D11_SUBRESOURCE_DATA InitData;
		ZeroMemory(&InitData, sizeof(D3D11_SUBRESOURCE_DATA));
		InitData.pSysMem = vertices;

		V_FRETURN(g_pD3dDevice->CreateBuffer(&cbc, &InitData, &m_pVertexBuffer));
		return hr;
	}

	HRESULT Sample::LoadShaderAndInputLayout()
	{
		HRESULT hr = S_OK;

		DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined( _DEBUG ) || defined( _DEBUG )
		dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

		ID3DBlob* pVSBuf = NULL;
		V_FRETURN(D3DX11CompileFromFile(L"../../INPUT/DATA/Shader/sample/VS.hlsl", NULL, NULL, "VS", "vs_5_0", dwShaderFlags, NULL, NULL, &pVSBuf, NULL, NULL));
		V_FRETURN(g_pD3dDevice->CreateVertexShader((DWORD*)pVSBuf->GetBufferPointer(), pVSBuf->GetBufferSize(), NULL, &m_pVS));

		SIZE_T vsSize = pVSBuf->GetBufferSize();

		ID3DBlob* pPSBuf = NULL;
		V_FRETURN(D3DX11CompileFromFile(L"../../INPUT/DATA/Shader/sample/PS.hlsl", NULL, NULL, "PS", "ps_5_0", dwShaderFlags, NULL, NULL, &pPSBuf, NULL, NULL));
		V_FRETURN(g_pD3dDevice->CreatePixelShader((DWORD*)pPSBuf->GetBufferPointer(), pPSBuf->GetBufferSize(), NULL, &m_pPS));

		SIZE_T psSize = pPSBuf->GetBufferSize();


		const D3D11_INPUT_ELEMENT_DESC layout[] =
		{
			//정점쉐이더안의 POSITION시멘틱의 의미를 지정.
			{ "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};

		V_FRETURN(g_pD3dDevice->CreateInputLayout(layout, 1, pVSBuf->GetBufferPointer(), vsSize, &m_pVertexLayout));

		SAFE_RELEASE(pVSBuf);
		SAFE_RELEASE(pPSBuf);
		return hr;
	}

	HRESULT		Sample::RSChange()
	{
		HRESULT hr = S_OK;
		SAFE_RELEASE(m_pRS);

		D3D11_RASTERIZER_DESC RSDesc;
		ZeroMemory(&RSDesc, sizeof(D3D11_RASTERIZER_DESC));

		RSDesc.FillMode = (D3D11_FILL_MODE)m_uFillMode;
		RSDesc.CullMode = (D3D11_CULL_MODE)m_uCullMode;
		V_FRETURN(g_pD3dDevice->CreateRasterizerState(&RSDesc, &m_pRS));

		g_pD3dContext->RSSetState(m_pRS);
		return hr;
	}

	bool Sample::Init()
	{
		if (FAILED(CreateVertexBuffer()))
		{
			MessageBox(0, _T("CreateVertexBuffer  실패"), _T("Fatal error"), MB_OK);
			return false;
		}

		if (FAILED(LoadShaderAndInputLayout()))
		{
			MessageBox(0, _T("LoadShaderAndInputLayout  실패"), _T("Fatal error"), MB_OK);
			return false;
		}

		return true;
	}

	bool Sample::Frame()
	{
		if (I_Input.IsKeyDownOnce(DIK_F1)) {
			(m_uPrimType + 1 > 5) ? (m_uPrimType = 1) : (m_uPrimType += 1);
		}

		if (I_Input.IsKeyDownOnce(DIK_F2)) {
			(m_uCullMode + 1 > 3) ? (m_uCullMode = 1) : (m_uCullMode += 1);
			RSChange();
		}

		if (I_Input.IsKeyDownOnce(DIK_F3)) {
			(m_uFillMode + 1 > 3) ? (m_uFillMode = 2) : (m_uFillMode += 1);
			RSChange();
		}

		return true;
	}

	bool Sample::Render()
	{
		m_Font.SetAlignment(DWRITE_TEXT_ALIGNMENT_CENTER, DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
		m_Font.SetTextColor(ColorF(1.0f, 1.0f, 1.0f, 1.0f));
		m_Font.SetlayoutRt(0, 0, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);

		TCHAR TopologyBuffer[256];
		ZeroMemory(TopologyBuffer, sizeof(TCHAR) * 256);

		switch (m_uPrimType) {
			case 1: { _tcscpy_s(TopologyBuffer, L"POINTLIST"); } break;
			case 2: { _tcscpy_s(TopologyBuffer, L"LINELIST"); } break;
			case 3: { _tcscpy_s(TopologyBuffer, L"LINESTRIP"); } break;
			case 4: { _tcscpy_s(TopologyBuffer, L"TRIANGLELIST"); } break;
			case 5: { _tcscpy_s(TopologyBuffer, L"TRIANGLESTRIP"); } break;
		}

		TCHAR CullModeBuffer[256];
		ZeroMemory(CullModeBuffer, sizeof(TCHAR) * 256);

		switch (m_uCullMode) {
			case 1: { _tcscpy_s(CullModeBuffer, L"CULL_NONE"); } break;
			case 2: { _tcscpy_s(CullModeBuffer, L"CULL_FRONT"); } break;
			case 3: { _tcscpy_s(CullModeBuffer, L"CULL_BACK"); } break;
		}

		TCHAR FillModeBuffer[256];
		ZeroMemory(FillModeBuffer, sizeof(TCHAR) * 256);

		switch (m_uFillMode) {
			case 2: { _tcscpy_s(FillModeBuffer, L"WIREFRAME"); } break;
			case 3: { _tcscpy_s(FillModeBuffer, L"SOLID"); } break;
		}


		TCHAR pBuffer[256];
		ZeroMemory(pBuffer, sizeof(TCHAR) * 256);

		_stprintf_s(pBuffer, L"%s\n%s\n%s", TopologyBuffer, CullModeBuffer, FillModeBuffer);

		m_Font.DrawText(pBuffer);

		// Set the input layout
		g_pD3dContext->IASetInputLayout(m_pVertexLayout);

		// Shaders
		g_pD3dContext->VSSetShader(m_pVS, NULL, 0);
		g_pD3dContext->PSSetShader(m_pPS, NULL, 0);

		// // Set vertex buffer
		UINT stride = sizeof(Vector3);
		UINT offset = 0;

		g_pD3dContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
		g_pD3dContext->IASetPrimitiveTopology((D3D_PRIMITIVE_TOPOLOGY)m_uPrimType);
		g_pD3dContext->Draw(6, 0);

		return true;
	}

	bool Sample::Release()
	{
		SAFE_RELEASE(m_pVertexBuffer);    // 정점 버퍼 릴리즈

		SAFE_RELEASE(m_pVertexLayout);    // 정점 레이아웃 릴리즈

		SAFE_RELEASE(m_pVS);              // 정점 쉐이더 릴리즈
		SAFE_RELEASE(m_pPS);              // 픽쉘 쉐이더 릴리즈

		SAFE_RELEASE(m_pRS);

		return true;
	}

	Sample::~Sample() { }
}


반응형