C++
[강의] 2월 10일 수업정리
k-codestudy
2025. 2. 10. 17:12
오늘 api환경에 directX를 옮기는 작업을 하였다.
실행 파일과 리소스 경로 설정 정리
C++ 프로젝트에서 실행 파일(EXE)이 데이터를 찾을 때 EXE가 포함된 디렉터리를 기준으로 탐색한다
즉, 실행 파일과 리소스 파일(예: 이미지, 사운드, 설정 파일 등)이 같은 폴더에 있어야 정상적으로 로드된다
실행 방식에 따른 리소스 경로 차이
- Ctrl + F5 (독립 실행)
- 실행 중인 EXE 파일이 있는 디렉터리에서 데이터를 찾는다
- 그러나 리소스 파일은 Visual Studio 내부의 경로를 참조할 수도 있어 불일치 문제가 발생할 수 있음.
- EXE 파일을 직접 실행 (더블 클릭)
- 실행 파일과 동일한 폴더에 있는 리소스를 정상적으로 로드함
- 따라서 최종적으로 배포할 때는 EXE와 리소스를 같은 디렉터리에 두어야 함
리소스 경로를 설정하는 방법
1. 출력 디렉터리 설정
- 속성 → 일반 → 출력 디렉터리 → bin 폴더로 변경
- 실행 파일이 생성되는 위치를 bin 폴더로 설정하여, 다른 파일과 통일된 경로를 유지
2. 디버그 모드에서 실행 파일 이름 변경
- 속성 → 일반 → 대상 이름 → game_D.exe (디버그 모드에서 실행할 EXE 이름)
- 디버그와 릴리스 버전의 EXE 파일을 명확히 구분할 수 있음
3. 작업 디렉터리 설정
- 속성 → 디버깅 → 작업 디렉터리
- 출력 디렉터리와 동일한 경로로 설정 (복사 & 붙여넣기)
- 이렇게 하면 Visual Studio에서 실행할 때도 리소스 경로가 실제 실행 파일과 일치하여 경로 불일치 문제를 방지
요약
- EXE 파일은 동일한 디렉터리에 있는 데이터 파일을 로드함
- Visual Studio에서 실행할 때 리소스 경로가 어긋나는 문제를 방지하려면 출력 디렉터리와 작업 디렉터리를 동일하게 설정
- 디버그/릴리스 실행 파일을 구분하기 위해 EXE 이름을 변경 (예: game_D.exe)
- 배포 시에는 EXE와 리소스를 같은 폴더에 둬야 정상 동작
- 이렇게 설정하면 어떤 방식으로 실행해도 리소스 경로가 일치하여 실행 시 리소스를 찾지 못하는 오류를 방지할 수 있다
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"
class C_DX
{
private:
static C_DX* m_pDx;
public:
static void createDx();
static C_DX* getDx();
static void releaseDx();
private:
struct CBNeverChanges
{
XMMATRIX mView;
};
struct CBChangeOnResize
{
XMMATRIX mProjection;
};
struct CBChangesEveryFrame
{
XMMATRIX mWorld;
XMFLOAT4 vMeshColor;
};
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;
ID3D11VertexShader* g_pVertexShader;
ID3D11PixelShader* g_pPixelShader;
ID3D11InputLayout* g_pVertexLayout;
ID3D11Buffer* g_pCBNeverChanges;
ID3D11Buffer* g_pCBChangeOnResize;
ID3D11Buffer* g_pCBChangesEveryFrame;
ID3D11SamplerState* g_pSamplerLinear;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
XMFLOAT4 g_vMeshColor;
C_MESH m_cMesh;
private:
C_DX() = default;
HRESULT InitDevice();
HRESULT CompileShaderFromFile(LPCWSTR szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut);
public:
HRESULT createBuffer(D3D11_USAGE usage, UINT byteWidth, UINT bindFlags, const void* initData, ID3D11Buffer** ppBuffer);
void init(HWND hWnd);
void CleanupDevice();
void Render();
ID3D11Device* getDevice();
ID3D11DeviceContext* getContext();
};
dx.cpp
#include "dx.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::CompileShaderFromFile(LPCWSTR 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;
}
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;
}
if (FAILED(hr))
return hr;
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;
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;
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);
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);
ID3DBlob* pVSBlob = NULL;
hr = CompileShaderFromFile(L"data\\Tutorial07.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 = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);
if (FAILED(hr))
{
pVSBlob->Release();
return hr;
}
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);
hr = g_pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout);
pVSBlob->Release();
if (FAILED(hr))
return hr;
g_pImmediateContext->IASetInputLayout(g_pVertexLayout);
ID3DBlob* pPSBlob = NULL;
hr = CompileShaderFromFile(L"data\\Tutorial07.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;
}
// Create the pixel shader
hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);
pPSBlob->Release();
if (FAILED(hr))
return hr;
if (FAILED(createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBNeverChanges), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBNeverChanges)))
return hr;
if (FAILED(createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBChangeOnResize), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBChangeOnResize)))
return hr;
if (FAILED(createBuffer(D3D11_USAGE_DEFAULT, sizeof(CBChangesEveryFrame), D3D11_BIND_CONSTANT_BUFFER, nullptr, &g_pCBChangesEveryFrame)))
return hr;
if (FAILED(hr))
return hr;
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 = g_pd3dDevice->CreateSamplerState(&sampDesc, &g_pSamplerLinear);
if (FAILED(hr))
return hr;
g_World = XMMatrixIdentity();
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);
CBNeverChanges cbNeverChanges;
cbNeverChanges.mView = XMMatrixTranspose(g_View);
g_pImmediateContext->UpdateSubresource(g_pCBNeverChanges, 0, NULL, &cbNeverChanges, 0, 0);
g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f);
CBChangeOnResize cbChangesOnResize;
cbChangesOnResize.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(g_pCBChangeOnResize, 0, NULL, &cbChangesOnResize, 0, 0);
m_cMesh.load(L"cube.data");
m_cMesh.setMesh();
return S_OK;
}
HRESULT C_DX::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);
}
ID3D11Device* C_DX::getDevice()
{
return g_pd3dDevice;
}
ID3D11DeviceContext* C_DX::getContext()
{
return g_pImmediateContext;
}
void C_DX::CleanupDevice()
{
m_cMesh.release();
if (g_pImmediateContext) g_pImmediateContext->ClearState();
if (g_pSamplerLinear) g_pSamplerLinear->Release();
if (g_pCBNeverChanges) g_pCBNeverChanges->Release();
if (g_pCBChangeOnResize) g_pCBChangeOnResize->Release();
if (g_pCBChangesEveryFrame) g_pCBChangesEveryFrame->Release();
if (g_pVertexLayout) g_pVertexLayout->Release();
if (g_pVertexShader) g_pVertexShader->Release();
if (g_pPixelShader) g_pPixelShader->Release();
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()
{
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;
}
g_World = XMMatrixRotationY(t);
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;
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
CBChangesEveryFrame cb;
cb.mWorld = XMMatrixTranspose(g_World);
cb.vMeshColor = g_vMeshColor;
g_pImmediateContext->UpdateSubresource(g_pCBChangesEveryFrame, 0, NULL, &cb, 0, 0);
g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pCBNeverChanges);
g_pImmediateContext->VSSetConstantBuffers(1, 1, &g_pCBChangeOnResize);
g_pImmediateContext->VSSetConstantBuffers(2, 1, &g_pCBChangesEveryFrame);
g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);
g_pImmediateContext->PSSetConstantBuffers(2, 1, &g_pCBChangesEveryFrame);
g_pImmediateContext->PSSetSamplers(0, 1, &g_pSamplerLinear);
m_cMesh.render();
g_pSwapChain->Present(0, 0);
}
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 "dx.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_DX::getDx()->getDevice(), L"data\\seafloor.dds", NULL, NULL, &g_pTextureRV, NULL)))
return S_FALSE;
if (FAILED(C_DX::getDx()->createBuffer(D3D11_USAGE_DEFAULT, sizeof(SimpleVertex) * 24, D3D11_BIND_VERTEX_BUFFER, vertices, &g_pVertexBuffer)))
return S_FALSE;
if (FAILED(C_DX::getDx()->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_DX::getDx()->getContext()->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
// Set index buffer
C_DX::getDx()->getContext()->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
// Set primitive topology
C_DX::getDx()->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_DX::getDx()->getContext()->PSSetShaderResources(0, 1, &g_pTextureRV);
C_DX::getDx()->getContext()->DrawIndexed(36, 0, 0);
}
main.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();
}