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