directX 클래스화 2일차
api.h
#pragma once
#include <Windows.h>
#include "resource.h"
#include "graphic.h"
class C_API
{
private:
C_GRAPHIC m_cGraphic;
static C_API* m_pApi;
HINSTANCE m_hInstance;
HWND m_hWnd;
private:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK apiProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
C_API() = default;
public:
static void createApi();
static C_API* getApi();
static void releaseApi();
bool init(HINSTANCE hInstance);
void updateMsg();
};
api.cpp
#include "api.h"
C_API* C_API::m_pApi = nullptr;
void C_API::createApi()
{
if (!m_pApi)
m_pApi = new C_API{};
}
C_API* C_API::getApi()
{
return m_pApi;
}
void C_API::releaseApi()
{
if (m_pApi)
{
m_pApi->m_cGraphic.release();
delete m_pApi;
m_pApi = nullptr;
}
}
bool C_API::init(HINSTANCE hInstance)
{
m_hInstance = hInstance;
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = m_hInstance;
wcex.hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_API));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = L"name";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassExW(&wcex);
m_hWnd = CreateWindowW(L"name", nullptr, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, m_hInstance, nullptr);
if (!m_hWnd)
return FALSE;
ShowWindow(m_hWnd, SW_SHOWDEFAULT);
m_cGraphic.init();
C_DX::getDx()->init(m_hWnd);
return true;
}
void C_API::updateMsg()
{
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
C_DX::getDx()->Render();
}
}
}
LRESULT CALLBACK C_API::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return m_pApi->apiProc(hWnd, message, wParam, lParam);
}
LRESULT C_API::apiProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
dx.h
#pragma once
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include "mesh.h"
#include "vs.h"
#include "ps.h"
class C_DX
{
private:
static C_DX* m_pDx;
public:
static void createDx();
static C_DX* getDx();
static void releaseDx();
private:
HWND g_hWnd;
D3D_DRIVER_TYPE g_driverType ;
D3D_FEATURE_LEVEL g_featureLevel;
ID3D11Device* g_pd3dDevice ;
ID3D11DeviceContext* g_pImmediateContext;
IDXGISwapChain* g_pSwapChain;
ID3D11RenderTargetView* g_pRenderTargetView;
ID3D11Texture2D* g_pDepthStencil;
ID3D11DepthStencilView* g_pDepthStencilView;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
XMFLOAT4 g_vMeshColor;
C_MESH m_cMesh;
C_VS m_cVs;
C_PS m_cPs;
private:
C_DX() = default;
HRESULT InitDevice();
public:
void init(HWND hWnd);
void CleanupDevice();
void Render();
};
dx.cpp
#include "dx.h"
#include "dxUtil.h"
C_DX* C_DX::m_pDx = nullptr;
void C_DX::createDx()
{
if (!m_pDx)
m_pDx = new C_DX{};
}
C_DX* C_DX::getDx()
{
return m_pDx;
}
void C_DX::releaseDx()
{
if (m_pDx)
{
delete m_pDx;
m_pDx = nullptr;
}
}
void C_DX::init(HWND hWnd)
{
g_hWnd = hWnd;
g_driverType = D3D_DRIVER_TYPE_NULL;
g_featureLevel = D3D_FEATURE_LEVEL_11_0;
g_World = XMMatrixIdentity();
g_View = XMMatrixIdentity();;
g_Projection = XMMatrixIdentity();;
g_vMeshColor = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
InitDevice();
}
HRESULT C_DX::InitDevice()
{
HRESULT hr = S_OK;
RECT rc;
GetClientRect(g_hWnd, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
C_DXUTIL::init(g_pd3dDevice, g_pImmediateContext);
if (FAILED(hr))
return hr;
// Create a render target view
ID3D11Texture2D* pBackBuffer = NULL;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))
return hr;
hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
return hr;
// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = width;
descDepth.Height = height;
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;
hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencil);
if (FAILED(hr))
return hr;
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory(&descDSV, sizeof(descDSV));
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencil, &descDSV, &g_pDepthStencilView);
if (FAILED(hr))
return hr;
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports(1, &vp);
if (FAILED(hr))
return hr;
// Initialize the world matrices
g_World = XMMatrixIdentity();
m_cMesh.load(L"cube.data");
m_cMesh.setMesh();
m_cVs.init();
m_cVs.setVs();
m_cPs.init();
m_cPs.setPs();
// Initialize the view matrix
XMVECTOR Eye = XMVectorSet(0.0f, 3.0f, -6.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
g_View = XMMatrixLookAtLH(Eye, At, Up);
C_VS::CBNeverChanges cbNeverChanges;
cbNeverChanges.mView = XMMatrixTranspose(g_View);
g_pImmediateContext->UpdateSubresource(m_cVs.getCBNeverChange(), 0, NULL, &cbNeverChanges, 0, 0);
// Initialize the projection matrix
g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f);
C_VS::CBChangeOnResize cbChangesOnResize;
cbChangesOnResize.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(m_cVs.getCBChangeOnResize(), 0, NULL, &cbChangesOnResize, 0, 0);
return S_OK;
}
void C_DX::CleanupDevice()
{
m_cMesh.release();
m_cVs.release();
m_cPs.release();
if (g_pImmediateContext) g_pImmediateContext->ClearState();
if (g_pDepthStencil) g_pDepthStencil->Release();
if (g_pDepthStencilView) g_pDepthStencilView->Release();
if (g_pRenderTargetView) g_pRenderTargetView->Release();
if (g_pSwapChain) g_pSwapChain->Release();
if (g_pImmediateContext) g_pImmediateContext->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
}
void C_DX::Render()
{
// Update our time
static float t = 0.0f;
if (g_driverType == D3D_DRIVER_TYPE_REFERENCE)
{
t += (float)XM_PI * 0.0125f;
}
else
{
static DWORD dwTimeStart = 0;
DWORD dwTimeCur = GetTickCount();
if (dwTimeStart == 0)
dwTimeStart = dwTimeCur;
t = (dwTimeCur - dwTimeStart) / 1000.0f;
}
// Rotate cube around the origin
g_World = XMMatrixRotationY(t);
// Modify the color
g_vMeshColor.x = (sinf(t * 1.0f) + 1.0f) * 0.5f;
g_vMeshColor.y = (cosf(t * 3.0f) + 1.0f) * 0.5f;
g_vMeshColor.z = (sinf(t * 5.0f) + 1.0f) * 0.5f;
//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
//
// Clear the depth buffer to 1.0 (max depth)
//
g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
//
// Update variables that change once per frame
//
C_VS::CBChangesEveryFrame cb;
cb.mWorld = XMMatrixTranspose(g_World);
cb.vMeshColor = g_vMeshColor;
g_pImmediateContext->UpdateSubresource(m_cVs.getCBChangesEveryFrame(), 0, NULL, &cb, 0, 0);
m_cMesh.render();
//
// Present our back buffer to our front buffer
//
g_pSwapChain->Present(0, 0);
}
dxUtil.h
#pragma once
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
class C_DXUTIL
{
private:
static ID3D11Device* g_pd3dDevice;
static ID3D11DeviceContext* g_pImmediateContext;
public:
static ID3D11Device* getDevice();
static ID3D11DeviceContext* getContext();
static void init(ID3D11Device* pd3dDevice ,ID3D11DeviceContext* pImmediateContext);
static HRESULT createBuffer(D3D11_USAGE usage, UINT byteWidth, UINT bindFlags, const void* initData, ID3D11Buffer** ppBuffer);
static HRESULT CompileShaderFromFile(LPCWSTR szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut);
};
dxUtil.cpp
#include"dx.h"
#include "dxUtil.h"
ID3D11Device* C_DXUTIL::g_pd3dDevice = nullptr;
ID3D11DeviceContext* C_DXUTIL::g_pImmediateContext = nullptr;
ID3D11Device* C_DXUTIL::getDevice()
{
return g_pd3dDevice;
}
ID3D11DeviceContext* C_DXUTIL::getContext()
{
return g_pImmediateContext;
}
void C_DXUTIL::init(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext)
{
g_pd3dDevice = pd3dDevice;
g_pImmediateContext = pImmediateContext;
}
HRESULT C_DXUTIL::createBuffer(D3D11_USAGE usage, UINT byteWidth, UINT bindFlags, const void* initData, ID3D11Buffer** ppBuffer)
{
D3D11_BUFFER_DESC bd{ byteWidth , usage , bindFlags , 0,0,0 };
D3D11_SUBRESOURCE_DATA subResource{ initData ,0,0 };
D3D11_SUBRESOURCE_DATA* pInit{};
if (initData)
pInit = &subResource;
return g_pd3dDevice->CreateBuffer(&bd, pInit, ppBuffer);
}
HRESULT C_DXUTIL::CompileShaderFromFile(LPCWSTR szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
HRESULT hr = S_OK;
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
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;
}
graphic.h
#pragma once
#include "dx.h"
class C_GRAPHIC
{
private:
public:
void init();
void release();
};
graphic.cpp
#include "graphic.h"
void C_GRAPHIC::init()
{
C_DX::createDx();
}
void C_GRAPHIC::release()
{
C_DX::getDx()->CleanupDevice();
C_DX::releaseDx();
}
mesh.h
#pragma once
#include <d3d11.h>
#include <d3dx11.h>
#include <xnamath.h>
class C_MESH
{
private:
struct SimpleVertex
{
XMFLOAT3 Pos;
XMFLOAT2 Tex;
};
private:
ID3D11Buffer* g_pVertexBuffer;
ID3D11Buffer* g_pIndexBuffer;
ID3D11ShaderResourceView* g_pTextureRV;
public:
HRESULT load(LPCWSTR strFileName);
void setMesh();
void release();
void render();
};
mesh.cpp
#include "dxUtil.h"
#include "mesh.h"
HRESULT C_MESH::load(LPCWSTR strFileName)
{
SimpleVertex vertices[] =
{
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
};
WORD indices[] =
{
3,1,0,
2,1,3,
6,4,5,
7,4,6,
11,9,8,
10,9,11,
14,12,13,
15,12,14,
19,17,16,
18,17,19,
22,20,21,
23,20,22
};
if (FAILED(D3DX11CreateShaderResourceViewFromFile( C_DXUTIL::getDevice(), L"data\\seafloor.dds", NULL, NULL, &g_pTextureRV, NULL)))
return S_FALSE;
if (FAILED(C_DXUTIL::createBuffer(D3D11_USAGE_DEFAULT, sizeof(SimpleVertex) * 24, D3D11_BIND_VERTEX_BUFFER, vertices, &g_pVertexBuffer)))
return S_FALSE;
if (FAILED(C_DXUTIL::createBuffer(D3D11_USAGE_DEFAULT, sizeof(WORD) * 36, D3D11_BIND_INDEX_BUFFER, indices, &g_pIndexBuffer)))
return S_FALSE;
return S_OK;
}
void C_MESH::setMesh()
{
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
C_DXUTIL::getContext()->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
// Set index buffer
C_DXUTIL::getContext()->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
// Set primitive topology
C_DXUTIL::getContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void C_MESH::release()
{
if (g_pTextureRV) g_pTextureRV->Release();
if (g_pVertexBuffer) g_pVertexBuffer->Release();
if (g_pIndexBuffer) g_pIndexBuffer->Release();
}
void C_MESH::render()
{
C_DXUTIL::getContext()->PSSetShaderResources(0, 1, &g_pTextureRV);
C_DXUTIL::getContext()->DrawIndexed(36, 0, 0);
}
ps.h
#pragma once
#include <d3d11.h>
#include <d3dx11.h>
#include <xnamath.h>
#include "dxUtil.h"
class C_PS
{
private:
ID3D11PixelShader* g_pPixelShader;
ID3D11SamplerState* g_pSamplerLinear;
public:
C_PS() = default;
HRESULT init();
void setPs();
void release();
};
ps.cpp
#include "ps.h"
HRESULT C_PS::init()
{
HRESULT hr = S_FALSE;
// Create the sample state
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
hr = C_DXUTIL::getDevice()->CreateSamplerState(&sampDesc, &g_pSamplerLinear);
if (FAILED(hr))
return hr;
ID3DBlob* pPSBlob = NULL;
hr = C_DXUTIL::CompileShaderFromFile(L"data\\ps.fx", "PS", "ps_4_0", &pPSBlob);
if (FAILED(hr))
{
MessageBox(NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
return hr;
}
hr = C_DXUTIL::getDevice()->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);
pPSBlob->Release();
if (FAILED(hr))
return hr;
return S_OK;
}
void C_PS::setPs()
{
C_DXUTIL::getContext()->PSSetShader(g_pPixelShader, NULL, 0);
C_DXUTIL::getContext()->PSSetSamplers(0, 1, &g_pSamplerLinear);
}
void C_PS::release()
{
if (g_pPixelShader) g_pPixelShader->Release();
if (g_pSamplerLinear) g_pSamplerLinear->Release();
}
vs.h
#pragma once
#include <d3d11.h>
#include <d3dx11.h>
#include <xnamath.h>
#include "dxUtil.h"
class C_VS
{
public:
struct CBNeverChanges
{
XMMATRIX mView;
};
struct CBChangeOnResize
{
XMMATRIX mProjection;
};
struct CBChangesEveryFrame
{
XMMATRIX mWorld;
XMFLOAT4 vMeshColor;
};
private:
ID3D11VertexShader* g_pVertexShader;
ID3D11InputLayout* g_pVertexLayout;
ID3D11Buffer* g_pCBNeverChanges;
ID3D11Buffer* g_pCBChangeOnResize;
ID3D11Buffer* g_pCBChangesEveryFrame;
public:
C_VS() = default;
HRESULT init();
void setVs();
void release();
ID3D11Buffer* getCBNeverChange();
ID3D11Buffer* getCBChangeOnResize();
ID3D11Buffer* getCBChangesEveryFrame();
};
vs.cpp
#include "vs.h"
#include "dxUtil.h"
HRESULT C_VS::init()
{
HRESULT hr = S_FALSE;
// Create the vertex shader
ID3DBlob* pVSBlob = NULL;
hr = C_DXUTIL::CompileShaderFromFile(L"data\\vs.fx", "VS", "vs_4_0", &pVSBlob);
if (FAILED(hr))
{
MessageBox(NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
return hr;
}
hr = C_DXUTIL::getDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);
if (FAILED(hr))
{
pVSBlob->Release();
return hr;
}
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE(layout);
// Create the input layout
hr = C_DXUTIL::getDevice()->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout);
pVSBlob->Release();
if (FAILED(hr))
return hr;
if (FAILED(C_DXUTIL::createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBNeverChanges), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBNeverChanges)))
return S_FALSE;
if (FAILED(C_DXUTIL::createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBChangeOnResize), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBChangeOnResize)))
return S_FALSE;
if (FAILED(C_DXUTIL::createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBChangesEveryFrame), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBChangesEveryFrame)))
return S_FALSE;
return S_OK;
}
void C_VS::setVs()
{
C_DXUTIL::getContext()->IASetInputLayout(g_pVertexLayout);
C_DXUTIL::getContext()->VSSetShader(g_pVertexShader, NULL, 0);
C_DXUTIL::getContext()->VSSetConstantBuffers(0, 1, &g_pCBNeverChanges);
C_DXUTIL::getContext()->VSSetConstantBuffers(1, 1, &g_pCBChangeOnResize);
C_DXUTIL::getContext()->VSSetConstantBuffers(2, 1, &g_pCBChangesEveryFrame);
}
void C_VS::release()
{
if (g_pVertexLayout) g_pVertexLayout->Release();
if (g_pVertexShader) g_pVertexShader->Release();
if (g_pCBNeverChanges) g_pCBNeverChanges->Release();
if (g_pCBChangeOnResize) g_pCBChangeOnResize->Release();
if (g_pCBChangesEveryFrame) g_pCBChangesEveryFrame->Release();
}
ID3D11Buffer* C_VS::getCBNeverChange()
{
return g_pCBNeverChanges;
}
ID3D11Buffer* C_VS::getCBChangeOnResize()
{
return g_pCBChangeOnResize;
}
ID3D11Buffer* C_VS::getCBChangesEveryFrame()
{
return g_pCBChangesEveryFrame;
}
main.cpp
// api.cpp : 애플리케이션에 대한 진입점을 정의합니다.
//
#include "framework.h"
#include "api.h"
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
C_API::createApi();
C_API::getApi()->init(hInstance);
C_API::getApi()->updateMsg();
C_API::releaseApi();
}
'C++' 카테고리의 다른 글
[C++] 4월 21일 코딩 테스트 수업 (0) | 2025.04.23 |
---|---|
[C++] 그래프, DFS, BFS 탐색 (0) | 2025.03.17 |
[강의] 2월 10일 수업정리 (0) | 2025.02.10 |
[강의] 2월 7일 수업정리 (0) | 2025.02.07 |
[강의] 2월 5일 수업정리 (0) | 2025.02.05 |