공부 중 메모/DirectX

8. simpleShape Library

라이피 (Lypi) 2018. 12. 26. 15:23
반응형

# 라이브러리 정리 한번 함. 여태까지 샘플에서 만들었던 도형 클래스를 라이브러리로 옮겼다.


<Library>

stdHeader.h

     // 토폴로지 타입, 컬링모드, 필모드를 전역변수로 뺐다.

#pragma once
#define DIRECTINPUT_VERSION 0x0800
#define _CRT_SECURE_NO_WARNINGS    
#pragma warning( disable:4005) //매크로 재정의 에러 띄우지 않기.

//#define _DISABLE_EXTENDED_ALIGNED_STORAGE //메모리 자동 정렬 사용 안함?

#pragma region //헤더 파일 및 라이브러리 파일 추가

#include <Windows.h>

#include <tchar.h>
#include <time.h>
#include <cassert>

#include <memory> //스마트 포인터 사용
#include <wrl.h> //Windows Runtime C++ Template Library //ComPtr사용

//stl헤더
#include <set>
#include <list>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <iterator>

//dx (순서 주의)
#include "d3dx11.h"  
#include "D3D11.h" 
#include "dxgi.h"
#include "D3Dcompiler.h"
#include "D2D1.h"
#include "D2D1Helper.h"
#include "DWrite.h"
#include "dinput.h"


//라이브러리 포함
#pragma comment (lib, "D3D11.lib")

#if defined(DEBUG) || defined(_DEBUG)
#pragma comment( lib, "d3dx10d.lib" )	
#pragma comment( lib, "d3dx11d.lib" )	
#else
#pragma comment( lib, "d3dx10.lib" )
#pragma comment( lib, "d3dx11.lib" )
#endif

#pragma comment (lib, "dxgi.lib")
#pragma comment (lib, "D3Dcompiler.lib")
#pragma comment (lib, "D2D1.lib")
#pragma comment (lib, "DWrite.lib")
#pragma comment (lib, "dxguid.lib")
#pragma comment (lib, "dinput8.lib")

#pragma endregion

#pragma region //namespace 사용
using namespace std;
using namespace Microsoft::WRL;
using namespace D2D1;
#pragma endregion

namespace Lypi
{
#pragma region	//문자열 타입정의
	typedef basic_string<TCHAR>     T_STR;
	typedef basic_string<wchar_t>   W_STR;
	typedef basic_string<char>      C_STR;
	typedef vector<T_STR>		    T_STR_VECTOR;
#pragma endregion

#pragma region	//매크로
#define str(x) L#x
#define randf(x) (((float)x)*rand()/(float)RAND_MAX) //0~x사이의 랜덤한 실수값을 반환
#define randstep(fMin,fMax) (fMin+randf(fMax-fmin))  //min에서 max까지의 랜덤할 실수값을 반환
#define clamp(x,MinX,MaxX) if (x>MaxX) x=MaxX; else if (x<MinX) x=MinX;  //x값이 min보다 작으면 min으로, max보다 크면 max로 고정시킴.

#define SAFE_NEW(A, B)              { if (!A) A = new B; }                    //A가 널포인트이면 A에 B를 동적할당한다.
#define SAFE_DEL(A)                 { if (A) delete A; (A)=nullptr; }         //A가 널포인트가 아니면 A의 메모리를 해제하고, Nullptr로 설정한다.
#define SAFE_NEW_ARRAY(A, B, C)	    { if (!A && C>0) A = new B[C]; }          //A가 널포인트가 아니고 C가 1이상이면 A에 B를 C개의 배열로 동적할당한다.
#define SAFE_DELETE_ARRAY(A)		{ if (A) delete[] A; (A)=nullptr; }       //A가 널포인트가 아니면 A에 할당된 배열 메모리를 해제하고, nullptr로 설정한다.
#define SAFE_RELEASE(A)				{ if(A) { (A)->Release(); (A)=NULL; } }   //A가 널포인터가 아니면 A를 릴리즈하고 nullptr로 설정한다.

#define V(x)                        { hr = (x); }
#define V_FRETURN(x)                { hr = (x); if( FAILED(hr) ) { return hr; } }


//디버그 메시지 출력용
#define	DEBUGMSG(lpText)\
	{\
		TCHAR szBuffer[256];\
		_stprintf_s(szBuffer, _T("[File: %s][Line: %d]\n[Note : %s]"), _CRT_WIDE(__FILE__), __LINE__, lpText);	\
		MessageBox(NULL, szBuffer, _T("ERROR"), MB_ICONERROR);}



#if defined(DEBUG) | defined(_DEBUG) 
#define H_RETURN(x){ if (FAILED(x)){\
		LPWSTR output;\
		WCHAR buffer[256]={0,};\
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_ALLOCATE_BUFFER,\
		NULL,x,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&output,0,NULL);\
		wsprintf(buffer,L"File=%s\nLine=%s", str(__FILE__),str(__LINE__));\
		MessageBox(NULL, buffer,output,MB_OK); return hr;}\
	}

#define H(x){ if (FAILED(x)){\
		LPWSTR output;\
		WCHAR buffer[256]={0,};\
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_ALLOCATE_BUFFER,\
		NULL,x,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&output,0,NULL);\
		wsprintf(buffer,L"File=%s\nLine=%s", str(__FILE__),str(__LINE__));\
		MessageBox(NULL, buffer,output,MB_OK);}\
	}

#else
#define H_RETURN(x) (x)
#define H(x) (x)
#endif

#pragma endregion

#pragma region //외부변수 정의
	class winL;

	//device_DX
	extern ID3D11Device*             g_pD3dDevice;
	extern ID3D11DeviceContext*      g_pD3dContext;
	extern IDXGISwapChain*           g_pSwapChain;
	extern ID3D11RenderTargetView*   g_pRenderTagetView;	
	extern ID3D11DepthStencilView*   g_pDepthStencilView;  
	extern D3D11_VIEWPORT            g_d3dViewPort;		   

	//WndC_DX
	extern HINSTANCE    g_hInst;      //윈도우의 인스턴스 핸들값
	extern HWND         g_hWnd;       //생성된 윈도우의 핸들값
	extern RECT         g_rtWindow;   //윈도우 영역
	extern RECT         g_rtClient;   //클라이언트 영역 (작업영역)
	extern winL*        g_pWindow;    //현재 생성된 윈도우에 대한 포인터

	extern float        g_dSPF;       //SPF

	extern UINT    g_uPrimType;    //토폴로지 타입
	extern UINT    g_uCullMode;    //컬링모드
	extern UINT    g_uFillMode;    //와이어 프레임만 렌더링

#pragma endregion 

zCore.cpp

     //F1, F2, F3를 누르면 전역변수인 토폴로지 타입, 컬링모드, 필모드의 값이 바뀐다.

#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);

		I_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);
		I_Font.Init();
		I_Font.Set(pBackBuffer);

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

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


		Init();
		g_pD3dContext->IASetPrimitiveTopology((D3D11_PRIMITIVE_TOPOLOGY)g_uPrimType);

		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; }

		if (I_Input.IsKeyDownOnce(DIK_F1)) {
			(g_uPrimType + 1 > 5) ? (g_uPrimType = 1) : (g_uPrimType += 1);
		}

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

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


		Frame();



		return true;
	}

	bool zCore::gamePreRender()
	{
		float ClearColor[4] = {1.f, 1.f, 1.f, 1.f }; //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);

		I_Font.DrawTextBegin();

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

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

		if (m_swTimerRender) {
			m_GameTimer.Render();
		}

		if (m_swKeyRender) {
			I_Input.Render();
		}

		I_Font.SetAlignment(DWRITE_TEXT_ALIGNMENT_CENTER, DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
		I_Font.SetTextColor(ColorF(0.0f, 0.0f, 0.0f, 1.0f));

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

		switch (g_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 (g_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 (g_uFillMode) {
			case 2: { _tcscpy_s(FillModeBuffer, L"WIREFRAME"); } break;
			case 3: { _tcscpy_s(FillModeBuffer, L"SOLID"); } break;
		}

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

		I_Font.SetlayoutRt(0, 0, (FLOAT)g_rtClient.right, (FLOAT)g_rtClient.bottom);
		I_Font.Drawtxt(pBuffer);

		////IDXGISwapChain 객체를 사용하여 시연(출력)한다.
		////모든 렌더링 작업들은 present앞에서 이뤄져야 한다.
		I_Font.DrawTextEnd();

		PreRender();

		return true;
	}

	bool zCore::gameRender()
	{

		Render();

		return true;
	}

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

		g_pSwapChain->Present(0, 0);
		return true;
	}

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

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

		if (!CreanupDevice()) { return false; }

		return true;
	}


	zCore::~zCore()
	{
	}

}

ShapeHeader.h

#pragma once
#include "stdHeader_L.h"
#include "mathHeader_L.h"
#include "DxInput.h"

namespace Lypi
{
	struct P_VERTEX
	{
		float3 position;
	};

	struct PC_VERTEX
	{
		float3 position;
		float4 color;
	};


}

simpleShape.h

     // 텍스쳐가 포함되지 않은 도형을 그리는 클래스. 

#pragma once
#include "ShapeHeader.h"

namespace Lypi
{
	class simpleShape   
	{
		// 버텍스 버퍼 및 레이아웃
		ComPtr<ID3D11InputLayout>	  m_pVertexLayout;    //정점 레이아웃 인터페이스
									  
		ComPtr<ID3D11Buffer>          m_pVertexBuffer;    //정점 버퍼 인터페이스
		ComPtr<ID3D11Buffer>          m_pIndexBuffer;     //인덱스 버퍼 인터페이스
		ID3D11Buffer*                 m_pStreamTo;        //SO에서 IA로 되돌릴 버퍼
		ID3D11Buffer*                 m_pDrawFrom;        //출력용 버퍼

		UINT m_uCull_S;
		UINT m_uFill_S;

		// 버텍스 및 픽셀 쉐이더
		ComPtr<ID3D11VertexShader>     m_pVS;    //정점 쉐이더 인터페이스
		ComPtr<ID3D11PixelShader>      m_pPS;	 //픽셀 쉐이더 인터페이스
		ComPtr<ID3D11GeometryShader>   m_pGS;    //기하 쉐이더 인터페이스
		ComPtr<ID3D11GeometryShader>   m_pSO;    //Stream Output Stage용

		ComPtr<ID3D11RasterizerState>  m_pRS;   //래스터라이저 상태

	public:
		HRESULT		CreateVertexBuffer(PC_VERTEX* vertexArray, int aSize);        // 정점 버퍼 생성
		HRESULT     CreateIndexBuffer(DWORD* indexArray, int aSize);         // 인덱스 버퍼 생성
		HRESULT		LoadShaderAndInputLayout();  // 정점 및 픽쉘 쉐이더 로딩 및 생성

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

		HRESULT     HandleEffects(ID3D11Buffer* pBuffer); // 

	public:
		bool Init(PC_VERTEX* vertexArray, int vaSize, DWORD* indexArray, int iaSize);
		bool Frame();
		bool Render();
		bool Release();

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

simpleShape.cpp

#include "simpleShape.h"

namespace Lypi
{
	// 이미지 디버그용
	UINT    g_uPrimType;    //토폴로지 타입
	UINT    g_uCullMode;    //컬링모드
	UINT    g_uFillMode;    //와이어 프레임만 렌더링

	simpleShape::simpleShape()
	{
		m_pVertexBuffer = nullptr;
		m_pIndexBuffer = nullptr;

		m_pVertexLayout = nullptr;

		m_pStreamTo = nullptr;
		m_pDrawFrom = nullptr;

		m_pVS = nullptr;
		m_pGS = nullptr;
		m_pSO = nullptr;
		m_pPS = nullptr;

		g_uPrimType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
		g_uCullMode = D3D11_CULL_BACK;
		g_uFillMode = D3D11_FILL_SOLID;

		m_uCull_S = g_uCullMode;
		m_uFill_S = g_uFillMode;
	}

	HRESULT simpleShape::CreateVertexBuffer(PC_VERTEX* vertexArray, int aSize)
	{
		HRESULT hr = S_OK;

		//시계 방향으로 지정할 것.

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

		D3D11_SUBRESOURCE_DATA InitData;
		InitData.pSysMem = vertexArray;

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

	HRESULT simpleShape::CreateIndexBuffer(DWORD* indexArray, int aSize)
	{
		HRESULT hr = S_OK;

		UINT iNumIndex = aSize;

		// Create an Index Buffer
		CD3D11_BUFFER_DESC cib(iNumIndex * sizeof(DWORD), D3D11_BIND_INDEX_BUFFER);

		D3D11_SUBRESOURCE_DATA ibInitData;
		ZeroMemory(&ibInitData, sizeof(D3D11_SUBRESOURCE_DATA));
		ibInitData.pSysMem = indexArray;

		V_FRETURN(g_pD3dDevice->CreateBuffer(&cib, &ibInitData, &m_pIndexBuffer));

		return hr;
	}

	HRESULT simpleShape::LoadShaderAndInputLayout()
	{

		HRESULT hr = S_OK;

		ID3DBlob* pErrors = nullptr;
		DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined( _DEBUG ) || defined( _DEBUG )
		dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
		ID3DBlob* pVSBuf = nullptr;
		hr = D3DX11CompileFromFile(L"../../INPUT/DATA/Shader/sample/VS.hlsl", nullptr, nullptr, "VS", "vs_5_0", dwShaderFlags, NULL, nullptr, &pVSBuf, &pErrors, nullptr);
		V_FRETURN(hr);
		V_FRETURN(g_pD3dDevice->CreateVertexShader((DWORD*)pVSBuf->GetBufferPointer(), pVSBuf->GetBufferSize(), nullptr, &m_pVS));

		ID3DBlob* pGSBuf = nullptr;
		V_FRETURN(D3DX11CompileFromFile(L"../../INPUT/DATA/Shader/sample/GS.hlsl", nullptr, nullptr, "GS", "gs_5_0", dwShaderFlags, NULL, nullptr, &pGSBuf, &pErrors, nullptr));
		V_FRETURN(g_pD3dDevice->CreateGeometryShader((DWORD*)pGSBuf->GetBufferPointer(), pGSBuf->GetBufferSize(), nullptr, &m_pGS));

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

		//중요! 출력 슬롯의 정점 버퍼에있는 정점 요소에 대한 설명
		// ...예를 들어 위치의 y 및 z 구성 요소로만 출력하려면 StartComponent가 1이고 ComponentCount가 2여야합니다. 
		D3D11_SO_DECLARATION_ENTRY pDecl[] =
		{
			{ 0, "SV_POSITION", 0, 0, 3, 0 },
			{ 0, "COLOR", 0, 0, 4, 0 },
		};

		UINT elems = ARRAYSIZE(pDecl);
		// == UINT elems = sizeof(pDecl) / sizeof(pDecl[0]);	 
		// == UINT elems = sizeof(pDecl) / sizeof(D3D11_SO_DECLARATION_ENTRY);

		UINT stride[] = { sizeof(PC_VERTEX) }; // SO에서 반환되는 정점 한개의 크기.
											   //UINT stride = 7 * sizeof(float); // *NOT* sizeof the above array!

		V_FRETURN(g_pD3dDevice->CreateGeometryShaderWithStreamOutput(pGSBuf->GetBufferPointer(), pGSBuf->GetBufferSize(), pDecl, elems, stride, 1, 0, NULL, &m_pSO));

		UINT m_nBufferSize = 100000; // Streamoutput Stage를 돌리면 정점이 기하급수적으로 늘어남으로 최대치로 잡는 것이 좋다.
									 //그렇다고 너무 크게 잡으면 디바이스가 멈춤... 어느정도가 최대치인지는 잘 모르겠다.

		CD3D11_BUFFER_DESC bufferDesc(m_nBufferSize, D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT);

		//동일한 기하 쉐이더 버퍼2개 생성	
		V_FRETURN(g_pD3dDevice->CreateBuffer(&bufferDesc, NULL, &m_pDrawFrom));
		V_FRETURN(g_pD3dDevice->CreateBuffer(&bufferDesc, NULL, &m_pStreamTo));

		const D3D11_INPUT_ELEMENT_DESC layout[] =
		{
			{ "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "COLOR",  0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};
		V_FRETURN(g_pD3dDevice->CreateInputLayout(layout, 2, pVSBuf->GetBufferPointer(), pVSBuf->GetBufferSize(), &m_pVertexLayout));

		SAFE_RELEASE(pVSBuf);
		SAFE_RELEASE(pGSBuf);
		SAFE_RELEASE(pPSBuf);
		SAFE_RELEASE(pErrors);

		RSChange();

		//스트림 출력( 스트림 출력 스테이지 )
		//처음에 VertexBuffer로 한번은 꼭 돌려야한다.
		HandleEffects(m_pVertexBuffer.Get());

		//for (int iCnt = 0; iCnt < 1; iCnt++) 	//기하 쉐이더를 몇번 돌릴지 결정.
		//{
		//	HandleEffects(m_pDrawFrom);
		//}

		return hr;
	}

	HRESULT simpleShape::RSChange()
	{
		HRESULT hr = S_OK;
		m_pRS.Reset();

		D3D11_RASTERIZER_DESC RSDesc;
		ZeroMemory(&RSDesc, sizeof(D3D11_RASTERIZER_DESC));
		RSDesc.DepthClipEnable = TRUE;
		RSDesc.CullMode = (D3D11_CULL_MODE)g_uCullMode;
		RSDesc.FillMode = (D3D11_FILL_MODE)g_uFillMode;
		V_FRETURN(g_pD3dDevice->CreateRasterizerState(&RSDesc, &m_pRS));

		return hr;
	}

	HRESULT simpleShape::HandleEffects(ID3D11Buffer* pBuffer)
	{
		HRESULT hr = S_OK;

		g_pD3dContext->IASetInputLayout(m_pVertexLayout.Get());

		g_pD3dContext->VSSetShader(m_pVS.Get(), NULL, 0);
		g_pD3dContext->GSSetShader(m_pSO.Get(), NULL, 0); //SO로 세팅되면 PS로 넘어가지 않음

		UINT stride = sizeof(PC_VERTEX);
		UINT Offsets[] = { 0 };
		ID3D11Buffer* pVB[] = { pBuffer };

		g_pD3dContext->SOSetTargets(1, &m_pStreamTo, Offsets);   //삼각형당 쪼개진 데이터가 저장되서 나옴.
		g_pD3dContext->IASetVertexBuffers(0, 1, pVB, &stride, Offsets);
		g_pD3dContext->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);

		g_pD3dContext->RSSetState(m_pRS.Get());
		g_pD3dContext->IASetPrimitiveTopology((D3D11_PRIMITIVE_TOPOLOGY)g_uPrimType);

		if (m_pVertexBuffer.Get() == pBuffer) {
			(g_pD3dContext->DrawIndexed(3, 0, 0));
		}
		else {
			(g_pD3dContext->DrawAuto());
		}

		//더블버퍼링과 같은 개념
		ID3D11Buffer* pTemp = m_pStreamTo;
		m_pStreamTo = m_pDrawFrom;
		m_pDrawFrom = pTemp;

		//여기에 있어야 함. 중요함.
		pVB[0] = NULL;
		g_pD3dContext->SOSetTargets(0, pVB, Offsets);

		return hr;
	}

	bool simpleShape::Init(PC_VERTEX* vertexArray, int vaSize, DWORD* indexArray, int iaSize)
	{
		if (FAILED(CreateVertexBuffer(vertexArray, vaSize)))
		{
			MessageBox(0, _T("CreateTrangle  실패"), _T("Fatal error"), MB_OK);
			return false;
		}

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

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

		return true;
	}

	bool simpleShape::Frame()
	{
		//D키를 누르면 분할한다.
		if (I_Input.IsKeyDownOnce(DIK_D)) {
			HandleEffects(m_pDrawFrom);
		}

		if (m_uCull_S != g_uCullMode || m_uFill_S != g_uFillMode) {
			RSChange();
			m_uCull_S = g_uCullMode;
			m_uFill_S = g_uFillMode;
		}

		return true;
	}

	bool simpleShape::Render()
	{
		// Shaders
		g_pD3dContext->VSSetShader(m_pVS.Get(), NULL, 0);
		g_pD3dContext->PSSetShader(m_pPS.Get(), NULL, 0);

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

		UINT stride[] = { sizeof(PC_VERTEX) };
		UINT offset[] = { 0 };

		// Set vertex buffer
		g_pD3dContext->IASetVertexBuffers(0, 1, &m_pDrawFrom, stride, offset);
		g_pD3dContext->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
		g_pD3dContext->RSSetState(m_pRS.Get());
		g_pD3dContext->IASetPrimitiveTopology((D3D_PRIMITIVE_TOPOLOGY)g_uPrimType);

		//쪼개진 이후이므로 DrawAuto로 출력해야 제대로 분할된게 출력된다.
		/*g_pD3dContext->DrawIndexed(3, 0, 0);*/
		g_pD3dContext->DrawAuto();
		return true;
	}

	bool simpleShape::Release()
	{
		return true;
	}

	simpleShape::~simpleShape()
	{

	}

	
}

<sample>

sample.h

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

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

namespace Lypi
{
	class Sample : public zCore
	{
		simpleShape m_sShape;
		simpleShape m_sShape2;

	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)
	{

	}

	bool Sample::Init()
	{

		PC_VERTEX vertices[] =
		{
			{ float3(-0.0f, +0.7f, 0.5f), float4(1.f,1.f,1.f,1.f) },
			{ float3(+0.5f, -0.2f, 0.5f), float4(1.f,1.f,1.f,1.f) },
			{ float3(-0.5f, -0.2f, 0.5f), float4(1.f,1.f,1.f,1.f) },
		};

		PC_VERTEX vertices2[] =
		{
			{ float3(-1.0f, -1.0f, 0.5f), float4(1.f,1.f,1.f,1.f) },
			{ float3(-0.5f, -0.5f, 0.5f), float4(1.f,1.f,1.f,1.f) },
			{ float3(-0.5f, -1.0f, 0.5f), float4(1.f,1.f,1.f,1.f) },
		};

		DWORD indices[] =
		{
			0,1,2,
			//0,2,3,
		};

		m_sShape.Init(vertices, sizeof(vertices)/sizeof(vertices[0]), indices, sizeof(indices) / sizeof(indices[0]));
		m_sShape2.Init(vertices2, sizeof(vertices2) / sizeof(vertices2[0]), indices, sizeof(indices) / sizeof(indices[0]));

		return true;
	}

	bool Sample::Frame()
	{
		m_sShape.Frame();
		m_sShape2.Frame();

		return true;
	}

	bool Sample::Render()
	{
		m_sShape.Render();
		m_sShape2.Render();
	
		return true;
	}


	bool Sample::Release()
	{
		return true;
	}

	Sample::~Sample(void)
	{
	}


}


반응형