반응형
# 라이브러리 정리 한번 함. 여태까지 샘플에서 만들었던 도형 클래스를 라이브러리로 옮겼다.
<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)
{
}
}반응형