반응형
원래는 DX11의 EFFECT시스템을 활용하는 예제였을 텐데...
DX12에서 EFFECT시스템이 사라지면서 (아마도 변경되면서) 예제가 간단하게 수정되었다.
그저 정점쉐이더에서 상수버퍼의 정보를 받아, 정점의 색을 시간에 따라 변경해주는 예제이다.
이렇게 하고 나니까 이런 예제는 이미 했던 것 같은데...(..)
어쨌든 obj와 sample, 쉐이더 파일의 내용이 조금씩 변경되었다.
중요한 내용은 sample에 다 있다.
obj의 내용은 이 예제의 내용을 표현하기 위해서 임시로 변경된 정도이다.
obj.h
#pragma once #include "header.h" #include "input.h" enum ShaderName { Vertex = 1, Pixel = 2, Geometry = 3, Hull = 4, Domain = 5, Computer = 6, }; //#include "UserTexture.h" void ClearD3D11DeviceContext(ID3D11DeviceContext* pd3dDeviceContext); HRESULT CompileShaderFromFile(const WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut); ID3D11DeviceChild* LoadSelectShaderFile(ShaderName Select, const void* pShaderFileData, ID3DBlob** ppBlobOut = nullptr, char* pFuntionName = 0, bool bBinary = false); ID3D11InputLayout* CreateInputlayout (DWORD dwSize, LPCVOID lpData, D3D11_INPUT_ELEMENT_DESC* layout, UINT numElements); ID3D11Buffer* CreateVertexBuffer (void *vertices, UINT iNumVertex, UINT iSize, bool bDynamic = false); ID3D11Buffer* CreateIndexBuffer (void *indices, UINT iNumIndex, UINT iSize, bool bDynamic = false); ID3D11Buffer* CreateConstantBuffer (void *data, UINT iNumIndex, UINT iSize, bool bDynamic = false); ID3D11ShaderResourceView* CreateShaderResourceView(const TCHAR* strFilePath); ID3D11DepthStencilView* CreateDepthStencilView(DWORD dwWidth, DWORD dwHeight); class Object_DX { public: ComPtr<ID3D11Buffer> m_pVertexBuffer; // 정점 버퍼 ComPtr<ID3D11Buffer> m_pIndexBuffer; // 인덱스 버퍼 ComPtr<ID3D11Buffer> m_pConstantBuffer; // 상수 버퍼 ComPtr<ID3D11VertexShader> m_pVS; // 정점 쉐이더 ComPtr<ID3D11PixelShader> m_pPS; // 픽셀 쉐이더 ComPtr<ID3D11GeometryShader> m_pGS; // 기하 쉐이더 ComPtr<ID3D11InputLayout> m_pInputLayout; // 인풋 레이아웃 ComPtr<ID3D11ShaderResourceView> m_pTextureSRV; // 텍스쳐 SRV ComPtr<ID3D11BlendState> m_pAlphaBlend; //sampler 변수 ID3D11SamplerState* m_pSamplerState; UINT m_idxFilter; D3D11_FILTER m_dxFilter; UINT m_iTexAddressMode; FLOAT m_MinLod; ComPtr<ID3DBlob> m_pVSBlob; ComPtr<ID3DBlob> m_pPSBlob; ComPtr<ID3DBlob> m_pGSBlob; public: //PNCT구조에서 임시로 변경 P_VERTEX m_pVertexList[4]; uWH m_uImageSize; iLTRB m_uImagePart; fLTRB m_fPRegion; POINT m_ptCenter; D3DXVECTOR3 m_v3Center; public: iLTRB m_uSRegion; bool m_bExist; private: void transStoP(); //화면 -> 투영 void transPtoS(); //투영 -> 화면 void UpdateCP(); //중점 갱신 void UpdateVertexList(); //정점 리스트 갱신 public: HRESULT Create(const TCHAR* pTexFile); void ImagePartialSelect(iXYWH imgXYWH, uWH imgSize); void SetPosition(iXYWH _xywh); void CreateFullImgObj(iXYWH _xywh, const TCHAR* pTexFile); void CreatePartImgObj(iXYWH _xywh, iXYWH imgXYWH, uWH imgSize, const TCHAR* pTexFile); void ImagePartialChange(iXYWH); void ImageFileChange(const TCHAR* pTexFile); void MoveX(float fDis); void MoveY(float fDis); iLTRB getPos(); void spin(float fAngle); void scale(float size); void ColorChange(float r, float g, float b, float a); void Color(); public: virtual bool Init(); virtual bool Frame(); virtual bool Render(); virtual bool Release(); public: Object_DX(); virtual ~Object_DX(); };
obj.cpp
#include "obj.h" //------------- 오브젝트 관련 전역 함수 세팅 시작 ------// void ClearD3D11DeviceContext(ID3D11DeviceContext* pd3dDeviceContext) { // Unbind all objects from the immediate context if (pd3dDeviceContext == NULL) return; ID3D11ShaderResourceView* pSRVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ID3D11RenderTargetView* pRTVs[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ID3D11DepthStencilView* pDSV = NULL; ID3D11Buffer* pBuffers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ID3D11SamplerState* pSamplers[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; UINT StrideOffset[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; // Shaders pd3dDeviceContext->VSSetShader(NULL, NULL, 0); pd3dDeviceContext->HSSetShader(NULL, NULL, 0); pd3dDeviceContext->DSSetShader(NULL, NULL, 0); pd3dDeviceContext->GSSetShader(NULL, NULL, 0); pd3dDeviceContext->PSSetShader(NULL, NULL, 0); // IA clear pd3dDeviceContext->IASetVertexBuffers(0, 16, pBuffers, StrideOffset, StrideOffset); pd3dDeviceContext->IASetIndexBuffer(NULL, DXGI_FORMAT_R32_UINT, 0); pd3dDeviceContext->IASetInputLayout(NULL); // Constant buffers pd3dDeviceContext->VSSetConstantBuffers(0, 14, pBuffers); pd3dDeviceContext->HSSetConstantBuffers(0, 14, pBuffers); pd3dDeviceContext->DSSetConstantBuffers(0, 14, pBuffers); pd3dDeviceContext->GSSetConstantBuffers(0, 14, pBuffers); pd3dDeviceContext->PSSetConstantBuffers(0, 14, pBuffers); // Resources pd3dDeviceContext->VSSetShaderResources(0, 16, pSRVs); pd3dDeviceContext->HSSetShaderResources(0, 16, pSRVs); pd3dDeviceContext->DSSetShaderResources(0, 16, pSRVs); pd3dDeviceContext->GSSetShaderResources(0, 16, pSRVs); pd3dDeviceContext->PSSetShaderResources(0, 16, pSRVs); // Samplers pd3dDeviceContext->VSSetSamplers(0, 16, pSamplers); pd3dDeviceContext->HSSetSamplers(0, 16, pSamplers); pd3dDeviceContext->DSSetSamplers(0, 16, pSamplers); pd3dDeviceContext->GSSetSamplers(0, 16, pSamplers); pd3dDeviceContext->PSSetSamplers(0, 16, pSamplers); // Render targets pd3dDeviceContext->OMSetRenderTargets(8, pRTVs, pDSV); // States FLOAT blendFactor[4] = { 0,0,0,0 }; pd3dDeviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFFF); pd3dDeviceContext->OMSetDepthStencilState(NULL, 0); pd3dDeviceContext->RSSetState(NULL); } HRESULT CompileShaderFromFile(const WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut) { HRESULT hr = S_OK; DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) dwShaderFlags |= D3DCOMPILE_DEBUG; #endif ID3DBlob* pErrorBlob; hr = D3DX11CompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel, dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL); if (FAILED(hr)) { if (pErrorBlob != NULL) { OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); } if (pErrorBlob) { pErrorBlob->Release(); } return hr; } if (pErrorBlob) { pErrorBlob->Release(); } return S_OK; } ID3D11DeviceChild* LoadSelectShaderFile(ShaderName Select, const void* pShaderFileData, ID3DBlob** ppBlobOut, char* pFuntionName, bool bBinary) { ID3D11DeviceChild* pShader = nullptr; HRESULT hr = S_OK; ID3DBlob* pBlob = NULL; LPCVOID lpData = NULL; DWORD dwSize = 0; const char* pFName = pFuntionName; const char* pSLevel = 0; switch (Select) { case Vertex : { if (pFuntionName == 0) { pFName = "VS"; } pSLevel = "vs_5_0"; } break; case Pixel : { if (pFuntionName == 0) { pFName = "PS"; } pSLevel = "ps_5_0"; } break; case Geometry: { if (pFuntionName == 0) { pFName = "GS"; } pSLevel = "gs_5_0"; } break; case Hull: { if (pFuntionName == 0) { pFName = "HS"; } pSLevel = "hs_5_0"; } break; case Domain: { if (pFuntionName == 0) { pFName = "DS"; } pSLevel = "ds_5_0"; } break; case Computer: { if (pFuntionName == 0) { pFName = "CS"; } pSLevel = "cs_5_0"; } break; } if (bBinary == false) { hr = CompileShaderFromFile((TCHAR*)pShaderFileData, pFName, pSLevel, &pBlob); if (FAILED(hr)) { return nullptr; } } else { pBlob = *ppBlobOut; if (pBlob == nullptr) { return nullptr; } } dwSize = (DWORD)pBlob->GetBufferSize(); lpData = pBlob->GetBufferPointer(); switch (Select) { case Vertex: { ID3D11VertexShader* pVertexShader = nullptr; hr = g_pD3dDevice->CreateVertexShader(lpData, dwSize, NULL, &pVertexShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pVertexShader; } break; case Pixel: { ID3D11PixelShader* pPixelShader = nullptr; hr = g_pD3dDevice->CreatePixelShader(lpData, dwSize, NULL, &pPixelShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pPixelShader; } break; case Geometry: { ID3D11GeometryShader* pGeometryShader = nullptr; hr = g_pD3dDevice->CreateGeometryShader(lpData, dwSize, NULL, &pGeometryShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pGeometryShader; } break; case Hull: { ID3D11HullShader* pHullShader = nullptr; hr = g_pD3dDevice->CreateHullShader(lpData, dwSize, NULL, &pHullShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pHullShader; } break; case Domain: { ID3D11DomainShader* pDomainShader = nullptr; hr = g_pD3dDevice->CreateDomainShader(lpData, dwSize, NULL, &pDomainShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pDomainShader; } break; case Computer: { ID3D11ComputeShader* pComputeShader = nullptr; hr = g_pD3dDevice->CreateComputeShader(lpData, dwSize, NULL, &pComputeShader); if (FAILED(hr)) { pBlob->Release(); return nullptr; } pShader = pComputeShader; } break; } if (ppBlobOut == nullptr) { pBlob->Release(); } else { *ppBlobOut = pBlob; } return pShader; } ID3D11InputLayout* CreateInputlayout(DWORD dwSize, LPCVOID lpData, D3D11_INPUT_ELEMENT_DESC* layout, UINT numElements) { HRESULT hr = S_OK; ID3D11InputLayout* pInutLayout = nullptr; hr = g_pD3dDevice->CreateInputLayout(layout, numElements, lpData, dwSize, &pInutLayout); if (FAILED(hr)) { H(hr); return nullptr; } return pInutLayout; } ID3D11Buffer* CreateVertexBuffer(void *vertices, UINT iNumVertex, UINT iVertexSize, bool bDynamic) { ID3D11Buffer* pBuffer = nullptr; HRESULT hr = S_OK; D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); if (bDynamic) { bd.Usage = D3D11_USAGE_DYNAMIC; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; } else { bd.Usage = D3D11_USAGE_DEFAULT; bd.CPUAccessFlags = 0; } bd.ByteWidth = iVertexSize * iNumVertex; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = vertices; if (vertices != NULL) { hr = g_pD3dDevice->CreateBuffer(&bd, &InitData, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } else { g_pD3dDevice->CreateBuffer(&bd, NULL, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } return pBuffer; } ID3D11Buffer* CreateIndexBuffer(void *indices, UINT iNumIndex, UINT iSize, bool bDynamic) { ID3D11Buffer* pBuffer = nullptr; HRESULT hr = S_OK; D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); if (bDynamic) { bd.Usage = D3D11_USAGE_DYNAMIC; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; } else { bd.Usage = D3D11_USAGE_DEFAULT; bd.CPUAccessFlags = 0; } bd.ByteWidth = iSize * iNumIndex; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = indices; if (indices != NULL) { hr = g_pD3dDevice->CreateBuffer(&bd, &InitData, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } else { hr = g_pD3dDevice->CreateBuffer(&bd, NULL, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } return pBuffer; } ID3D11Buffer* CreateConstantBuffer(void *data, UINT iNumIndex, UINT iSize, bool bDynamic) { ID3D11Buffer* pBuffer = nullptr; HRESULT hr = S_OK; D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); if (bDynamic) { bd.Usage = D3D11_USAGE_DYNAMIC; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; } else { bd.Usage = D3D11_USAGE_DEFAULT; bd.CPUAccessFlags = 0; } bd.ByteWidth = iSize * iNumIndex; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = data; if (data != NULL) { hr = g_pD3dDevice->CreateBuffer(&bd, &InitData, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } else { hr = g_pD3dDevice->CreateBuffer(&bd, NULL, &pBuffer); if (FAILED(hr)) { H(hr); return nullptr; } } return pBuffer; } ID3D11ShaderResourceView* CreateShaderResourceView(const TCHAR* strFilePath) { ID3D11ShaderResourceView* pSRV = nullptr; HRESULT hr = S_OK; if (strFilePath == NULL) { return nullptr; } hr = D3DX11CreateShaderResourceViewFromFile(g_pD3dDevice, strFilePath, NULL, NULL, &pSRV, NULL); if (FAILED(hr)) { H(hr); return nullptr; } return pSRV; } ID3D11DepthStencilView* CreateDepthStencilView(DWORD dwWidth, DWORD dwHeight) { ID3D11DepthStencilView* pDSV = nullptr; HRESULT hr; D3D11_TEXTURE2D_DESC DescDepth; DescDepth.Width = dwWidth; DescDepth.Height = dwHeight; DescDepth.MipLevels = 1; DescDepth.ArraySize = 1; DescDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; DescDepth.SampleDesc.Count = 1; DescDepth.SampleDesc.Quality = 0; DescDepth.Usage = D3D11_USAGE_DEFAULT; DescDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; DescDepth.CPUAccessFlags = 0; DescDepth.MiscFlags = 0; ComPtr<ID3D11Texture2D> pDSTexture = nullptr; hr = g_pD3dDevice->CreateTexture2D(&DescDepth, NULL, &pDSTexture); if (FAILED(hr)) { return nullptr; } D3D11_DEPTH_STENCIL_VIEW_DESC dsvd; ZeroMemory(&dsvd, sizeof(dsvd)); dsvd.Format = DescDepth.Format; dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsvd.Texture2D.MipSlice = 0; hr = g_pD3dDevice->CreateDepthStencilView(pDSTexture.Get(), &dsvd, &pDSV); if (FAILED(hr)) { return nullptr; } return pDSV; } //------------- 오브젝트 관련 전역 함수 세팅 끝 ------// Object_DX::Object_DX() { } //화면좌표계 -> 투영좌표게 void Object_DX::transStoP() { m_fPRegion.left = (m_uSRegion.left / ((float)g_rtClient.right)) * 2 - 1.0f; m_fPRegion.top = -((m_uSRegion.top / ((float)g_rtClient.bottom)) * 2 - 1.0f); m_fPRegion.right = (m_uSRegion.right / ((float)g_rtClient.right)) * 2 - 1.0f; m_fPRegion.bottom = -((m_uSRegion.bottom / ((float)g_rtClient.bottom)) * 2 - 1.0f); } //투영좌표계 -> 화면좌표계 void Object_DX::transPtoS() { m_uSRegion.left = (UINT)((m_fPRegion.left + 1.0f) / 2 * ((float)g_rtClient.right)); m_uSRegion.top = (UINT)((m_fPRegion.top - 1.0f) / -2 * ((float)g_rtClient.bottom)); m_uSRegion.right = (UINT)((m_fPRegion.right + 1.0f) / 2 * ((float)g_rtClient.right)); m_uSRegion.bottom = (UINT)((m_fPRegion.bottom - 1.0f) / -2 * ((float)g_rtClient.bottom)); } //중점 갱신 void Object_DX::UpdateCP() { m_ptCenter.x = (m_uSRegion.right + m_uSRegion.left) / 2; m_ptCenter.y = (m_uSRegion.bottom + m_uSRegion.top) / 2; m_v3Center.x = 0.0f; m_v3Center.y = 0.0f; m_v3Center.z = 0.0f; for (int iV = 0; iV < 4; iV++) { m_v3Center.x += m_pVertexList[iV].p.x; m_v3Center.y += m_pVertexList[iV].p.y; } m_v3Center.x /= 4; m_v3Center.y /= 4; } //정점 리스트 갱신 void Object_DX::UpdateVertexList() { m_pVertexList[0].p = D3DXVECTOR3(m_fPRegion.left, m_fPRegion.top, 0.0f); m_pVertexList[1].p = D3DXVECTOR3(m_fPRegion.left, m_fPRegion.bottom, 0.0f); m_pVertexList[2].p = D3DXVECTOR3(m_fPRegion.right, m_fPRegion.top, 0.0f); m_pVertexList[3].p = D3DXVECTOR3(m_fPRegion.right, m_fPRegion.bottom, 0.0f); //for (int pl = 0; pl < 4; pl++) { // m_pVertexList[pl].c = D3DXVECTOR4(1, 1, 1, 1); //} //중점 갱신 UpdateCP(); } //생성 위치 지정하기 void Object_DX::SetPosition(iXYWH _xywh) { //화면 좌표계 저장 m_uSRegion = _xywh; //투영 좌표계 변환 transStoP(); //정점 리스트 저장 UpdateVertexList(); } //이미지 자르기 void Object_DX::ImagePartialSelect(iXYWH imgXYWH, uWH imgSize) { //m_uImagePart = imgXYWH; //m_uImageSize = imgSize; //fLTRB fImageUV; ////이미지 화면 좌표를 uv좌표로 변환 //fImageUV.left = (float)m_uImagePart.left / m_uImageSize.width; //fImageUV.top = (float)m_uImagePart.top / m_uImageSize.Height; //fImageUV.right = (float)m_uImagePart.right / m_uImageSize.width; //fImageUV.bottom = (float)m_uImagePart.bottom / m_uImageSize.Height; //m_pVertexList[0].t = D3DXVECTOR2(fImageUV.left, fImageUV.top); //m_pVertexList[1].t = D3DXVECTOR2(fImageUV.left, fImageUV.bottom); //m_pVertexList[2].t = D3DXVECTOR2(fImageUV.right, fImageUV.top); //m_pVertexList[3].t = D3DXVECTOR2(fImageUV.right, fImageUV.bottom); } //오브젝트 생성하기 HRESULT Object_DX::Create(const TCHAR* pTexFile) { //이번 포스팅에서는 이부분 안 씀 HRESULT hr; // 정점 버퍼 생성 D3D11_BUFFER_DESC sDesc; ZeroMemory(&sDesc, sizeof(D3D11_BUFFER_DESC)); sDesc.Usage = D3D11_USAGE_DEFAULT; sDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; //헤더의 정점 구조체를 PNCT로 바꿀 예정 sDesc.ByteWidth = sizeof(PNCT_VERTEX) * 4; D3D11_SUBRESOURCE_DATA sInitData; ZeroMemory(&sInitData, sizeof(D3D11_SUBRESOURCE_DATA)); sInitData.pSysMem = m_pVertexList; if (FAILED(hr = g_pD3dDevice->CreateBuffer(&sDesc, &sInitData, &m_pVertexBuffer))) { return hr; } //정점 쉐이더 생성 ID3DBlob* pErrorBlob; ID3DBlob* pVSBlob; hr = D3DX11CompileFromFile(L"Svertex.txt", NULL, NULL, "VS", "vs_5_0", NULL, NULL, NULL, &pVSBlob, &pErrorBlob, NULL); if (FAILED(hr)) { OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); return false; } hr = g_pD3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, m_pVS.GetAddressOf()); if (FAILED(hr)) { return hr; } //기하 쉐이더 생성 ID3DBlob* pGSBlob; hr = D3DX11CompileFromFile(L"Svertex.txt", NULL, NULL, "GS", "gs_5_0", NULL, NULL, NULL, &pGSBlob, &pErrorBlob, NULL); if (FAILED(hr)) { OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); return false; } hr = g_pD3dDevice->CreateGeometryShader(pGSBlob->GetBufferPointer(), pGSBlob->GetBufferSize(), NULL, m_pGS.GetAddressOf()); if (FAILED(hr)) { SAFE_RELEASE(pGSBlob); return NULL; } //레이아웃 생성 if (pVSBlob == NULL) { return E_FAIL; } //헤더의 정점 구조체를 PNCT로 바꿀 예정 D3D11_INPUT_ELEMENT_DESC ied[] = { { "POS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NO", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; int iNumElement = sizeof(ied) / sizeof(D3D11_INPUT_ELEMENT_DESC); hr = g_pD3dDevice->CreateInputLayout(ied, iNumElement, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), m_pInputLayout.GetAddressOf()); if (FAILED(hr)) { return hr; } //픽셀 쉐이더 생성 ID3DBlob* pPSBlob; hr = D3DX11CompileFromFile(L"Svertex.txt", NULL, NULL, "PS", "ps_5_0", NULL, NULL, NULL, &pPSBlob, &pErrorBlob, NULL); if (FAILED(hr)) { OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); return false; } hr = g_pD3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, m_pPS.GetAddressOf()); if (FAILED(hr)) { SAFE_RELEASE(pPSBlob); return NULL; } SAFE_RELEASE(pErrorBlob); SAFE_RELEASE(pVSBlob); SAFE_RELEASE(pPSBlob); SAFE_RELEASE(pGSBlob); //블렌드 스테이트 생성 D3D11_BLEND_DESC BlendState; ZeroMemory(&BlendState, sizeof(D3D11_BLEND_DESC)); BlendState.AlphaToCoverageEnable = FALSE; BlendState.IndependentBlendEnable = FALSE; BlendState.RenderTarget[0].BlendEnable = TRUE; BlendState.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; BlendState.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; BlendState.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; BlendState.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; BlendState.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; BlendState.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; BlendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; if (FAILED(hr = g_pD3dDevice->CreateBlendState(&BlendState, m_pAlphaBlend.GetAddressOf()))) { return hr; } //samplerState 생성 m_dxFilter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; m_iTexAddressMode = D3D11_TEXTURE_ADDRESS_CLAMP; D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = m_dxFilter; samplerDesc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)m_iTexAddressMode; samplerDesc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)m_iTexAddressMode; samplerDesc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)m_iTexAddressMode; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 16; samplerDesc.ComparisonFunc = D3D11_COMPARISON_EQUAL; samplerDesc.BorderColor[0] = 0.0f; samplerDesc.BorderColor[1] = 0.0f; samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = 0; hr = g_pD3dDevice->CreateSamplerState(&samplerDesc, &m_pSamplerState); if (FAILED(hr)) { return hr; } //텍스쳐 로드 hr = D3DX11CreateShaderResourceViewFromFile(g_pD3dDevice, pTexFile, NULL, NULL, m_pTextureSRV.GetAddressOf(), NULL); if (FAILED(hr)) { return hr; } return hr; } void Object_DX::ImageFileChange(const TCHAR* pTexFile) { D3DX11CreateShaderResourceViewFromFile(g_pD3dDevice, pTexFile, NULL, NULL, m_pTextureSRV.GetAddressOf(), NULL); } //전체 이미지 오브젝트 생성 void Object_DX::CreateFullImgObj(iXYWH _xywh, const TCHAR* pTexFile) { SetPosition(_xywh); ImagePartialSelect({ 0,0,1,1 }, { 1,1 }); Create(pTexFile); } //부분 이미지 오브젝트 생성 void Object_DX::CreatePartImgObj(iXYWH _xywh, iXYWH imgXYWH, uWH imgSize, const TCHAR* pTexFile) { SetPosition(_xywh); ImagePartialSelect(imgXYWH, imgSize); Create(pTexFile); } //이미지 선택 영역 변경 void Object_DX::ImagePartialChange(iXYWH _uXYWH) { ImagePartialSelect(_uXYWH, m_uImageSize); } iLTRB Object_DX::getPos() { return m_uSRegion; } //x축 이동 void Object_DX::MoveX(float fDis) { for (int iV = 0; iV < 4; iV++) { m_pVertexList[iV].p.x += fDis * g_dSPF; } m_fPRegion.left += fDis * g_dSPF; m_fPRegion.right += fDis * g_dSPF; transPtoS(); UpdateCP(); } //y축 이동 void Object_DX::MoveY(float fDis) { for (int iV = 0; iV < 4; iV++) { m_pVertexList[iV].p.y += fDis * g_dSPF; } m_fPRegion.top += fDis * g_dSPF; m_fPRegion.bottom += fDis * g_dSPF; transPtoS(); UpdateCP(); } //회전 void Object_DX::spin(float fAngle) { float S = sinf(fAngle); float C = cosf(fAngle); for (int iV = 0; iV < 4; iV++) { D3DXVECTOR3 vertex = m_pVertexList[iV].p; m_pVertexList[iV].p.x -= m_v3Center.x; m_pVertexList[iV].p.y -= m_v3Center.y; vertex.x = m_pVertexList[iV].p.x * C + m_pVertexList[iV].p.y * S / 2; vertex.y = m_pVertexList[iV].p.x * -S * 2 + m_pVertexList[iV].p.y * C; vertex.x += m_v3Center.x; vertex.y += m_v3Center.y; m_pVertexList[iV].p = vertex; } } //크기 조절 void Object_DX::scale(float size) {//값 넣을 때 주의 for (int iV = 0; iV < 4; iV++) { m_pVertexList[iV].p.x -= m_v3Center.x; m_pVertexList[iV].p.y -= m_v3Center.y; m_pVertexList[iV].p.x *= size; m_pVertexList[iV].p.y *= size; m_pVertexList[iV].p.x += m_v3Center.x; m_pVertexList[iV].p.y += m_v3Center.y; } } void Object_DX::ColorChange(float r, float g, float b, float a) { //for (int pl = 0; pl < 4; pl++) { // m_pVertexList[pl].c = D3DXVECTOR4(r, g, b, a); //} } void Object_DX::Color() { //m_pVertexList[0].c = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f); //m_pVertexList[1].c = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f); //m_pVertexList[2].c = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f); //m_pVertexList[3].c = D3DXVECTOR4(1.0f, 0.0f, 1.0f, 1.0f); } bool Object_DX::Init() { return true; } bool Object_DX::Frame() { g_pD3dContext->UpdateSubresource(m_pVertexBuffer.Get(), 0, NULL, m_pVertexList, 0, 0); return true; } bool Object_DX::Render() { g_pD3dContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); g_pD3dContext->IASetInputLayout(m_pInputLayout.Get()); UINT pStrides = sizeof(P_VERTEX); UINT pOffsets = 0; g_pD3dContext->IASetVertexBuffers(0, 1, m_pVertexBuffer.GetAddressOf(), &pStrides, &pOffsets); g_pD3dContext->VSSetConstantBuffers(0, 1, m_pConstantBuffer.GetAddressOf()); g_pD3dContext->VSSetShader(m_pVS.Get(), NULL, NULL); g_pD3dContext->PSSetShader(m_pPS.Get(), NULL, NULL); g_pD3dContext->PSSetShaderResources(0, 1, m_pTextureSRV.GetAddressOf()); ID3D11SamplerState* SS[1]; SS[0] = m_pSamplerState; g_pD3dContext->PSSetSamplers(0, 1, SS); g_pD3dContext->GSSetShader(m_pGS.Get(), NULL, NULL); g_pD3dContext->OMSetBlendState(m_pAlphaBlend.Get(), 0, -1); g_pD3dContext->Draw(4, 0); return true; } bool Object_DX::Release() { return true; } Object_DX::~Object_DX() { }
smaple.h
#pragma once #include "obj.h" #include "timer.h" //쉐이더에 float 한개만 전달하고 싶어도 4개 단위로 전달이 된다. struct VSCB { D3DXVECTOR4 vColor; // c0 D3DXVECTOR4 fC5; //c1 }; class sample { timerC_DX m_Timer; Object_DX m_obj; VSCB m_cbData; bool m_isBinary; bool m_bDynamic; public: bool Init(); bool Frame(); bool Render(); bool Release(); public: sample(); ~sample(); }; const BYTE g_VS[] = { 68, 88, 66, 67, 26, 180, 218, 245, 115, 81, 191, 144, 96, 131, 96, 164, 223, 211, 37, 71, 1, 0, 0, 0, 160, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 36, 1, 0, 0, 88, 1, 0, 0, 172, 1, 0, 0, 36, 2, 0, 0, 82, 68, 69, 70, 232, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 0, 1, 0, 0, 180, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 99, 98, 48, 0, 60, 0, 0, 0, 2, 0, 0, 0, 88, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 84, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 99, 0, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 84, 105, 109, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 171, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 171, 171, 83, 72, 68, 82, 112, 0, 0, 0, 64, 0, 1, 0, 28, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const DWORD g_VSHex[] = { 0x43425844, 0xf5dab41a, 0x90bf5173, 0xa4608360, 0x4725d3df, 0x00000001, 0x000002a0, 0x00000005, 0x00000034, 0x00000124, 0x00000158, 0x000001ac, 0x00000224, 0x46454452, 0x000000e8, 0x00000001, 0x00000040, 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000b4, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00306263, 0x0000003c, 0x00000002, 0x00000058, 0x00000060, 0x00000000, 0x00000000, 0x00000088, 0x00000000, 0x00000010, 0x00000002, 0x0000008c, 0x00000000, 0x0000009c, 0x00000054, 0x00000004, 0x00000000, 0x000000a4, 0x00000000, 0xabab0063, 0x00030001, 0x00040001, 0x00000000, 0x00000000, 0x6d695466, 0xabab0065, 0x00030000, 0x00010001, 0x00000000, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000070, 0x00010040, 0x0000001c, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x06000036, 0x001020f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, };
sample.cpp
#include "sample.h" #include <time.h> sample::sample() { m_bDynamic = false; m_isBinary = true; } bool sample::Init() { #pragma region VertexBuffer P_VERTEX vertices[4]; vertices[0].p = { -0.5f, 0.5f, 0.5f }; vertices[1].p = { 0.5f, 0.5f, 0.5f }; vertices[2].p = { -0.5f, -0.5f, 0.5f }; vertices[3].p = { 0.5f, -0.5f, 0.5f }; int numVertices = sizeof(vertices) / sizeof(vertices[0]); m_obj.m_pVertexBuffer.Attach(CreateVertexBuffer(vertices, numVertices, sizeof(P_VERTEX))); #pragma endregion #pragma region IndexBuffer DWORD indices[] = { 0,1,2, 0,2,3, }; int iNumIndex = sizeof(indices) / sizeof(indices[0]); m_obj.m_pIndexBuffer.Attach(CreateIndexBuffer(indices, iNumIndex, sizeof(DWORD))); #pragma endregion #pragma region ConstantBuffer m_obj.m_pConstantBuffer.Attach(CreateConstantBuffer(&m_cbData, 1, sizeof(VSCB))); #pragma endregion #pragma region Shader if (m_isBinary) { DWORD dwSize = sizeof(g_VSHex); D3DCreateBlob(dwSize, m_obj.m_pVSBlob.GetAddressOf()); memcpy(m_obj.m_pVSBlob->GetBufferPointer(), g_VSHex, dwSize); m_obj.m_pVS.Attach((ID3D11VertexShader*)LoadSelectShaderFile(Vertex, nullptr, m_obj.m_pVSBlob.GetAddressOf(), 0, true)); } else { m_obj.m_pVS.Attach((ID3D11VertexShader*)LoadSelectShaderFile(Vertex, L"Svertex.txt", m_obj.m_pVSBlob.GetAddressOf())); } m_obj.m_pPS.Attach((ID3D11PixelShader*)LoadSelectShaderFile(Pixel, L"Svertex.txt")); // m_obj.m_pGS.Attach((ID3D11GeometryShader*)LoadSelectShaderFile(Geometry, L"Svertex.txt")); #pragma endregion #pragma region InputLayout //D3D11_INPUT_ELEMENT_DESC layout[] = //{ // { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // { "NOMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D11_INPUT_PER_VERTEX_DATA, 0 }, //}; D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = sizeof(layout) / sizeof(layout[0]); if (m_isBinary) { m_obj.m_pInputLayout.Attach(CreateInputlayout(sizeof(g_VS), g_VS, layout, numElements)); } else { m_obj.m_pInputLayout.Attach(CreateInputlayout(m_obj.m_pVSBlob.Get()->GetBufferSize(), m_obj.m_pVSBlob.Get()->GetBufferPointer(), layout, numElements)); } #pragma endregion //samplerState 생성 D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 16; samplerDesc.ComparisonFunc = D3D11_COMPARISON_EQUAL; samplerDesc.BorderColor[0] = 0.0f; samplerDesc.BorderColor[1] = 0.0f; samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = 0; g_pD3dDevice->CreateSamplerState(&samplerDesc, &m_obj.m_pSamplerState); m_Timer.Init(); return true; } bool sample::Frame() { m_Timer.Frame(); float fTime = m_Timer.getGameTime(); float fBoundedTime = cosf(fTime) * 0.5f + 0.5f; //상수 버퍼를 갱신한다. m_cbData.vColor = D3DXVECTOR4(cosf(fTime), sinf(fTime), 1.0f - cosf(fTime), 1.0f); m_cbData.fC5.x = fBoundedTime; if (m_bDynamic) { D3D11_MAPPED_SUBRESOURCE MappedResource; g_pD3dContext->Map(m_obj.m_pConstantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource); VSCB* pConstData = (VSCB*)MappedResource.pData; pConstData->vColor = m_cbData.vColor; pConstData->fC5.x = m_cbData.fC5.x; g_pD3dContext->Unmap(m_obj.m_pConstantBuffer.Get(), 0); } else { g_pD3dContext->UpdateSubresource(m_obj.m_pConstantBuffer.Get(), 0, NULL, &m_cbData, 0, 0); } return true; } bool sample::Render() { m_Timer.Render(); m_obj.Render(); return true; } bool sample::Release() { m_Timer.Release(); m_obj.Release(); return true; } sample::~sample() { }
Svertex.txt
cbuffer cb0 { //상수버퍼이며 쉐이더 내에서 변수처럼 사용할 수 있다. float4 Color : packoffset(c0); float fTime : packoffset(c1.x); }; struct VS_OUTPUT { float4 Position : SV_Position; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color }; //-------------------------------------------------------------------------------------- // Vertex Shader //-------------------------------------------------------------------------------------- VS_OUTPUT VS( float3 p : POSITION ) { VS_OUTPUT Output; float3 vPos = p * fTime; // 0 <= fTime <= 1.0f Output.Position = float4( vPos, 1.0f ); Output.Diffuse = Color; return Output; } float4 PS( VS_OUTPUT input ) : SV_Target { return input.Diffuse; }
반응형