오늘은 API에 DirectX 적용하는 법에 대한 수업을 들었다.
버텍스와 노멀 벡터
버텍스 개수가 24개인 이유 ( DirectX11 Tutorial6 )
- 조명 처리를 위해 하나의 점(버텍스)당 하나의 법선 벡터(Normal Vector)를 가져야 함
- 하나의 점이 여러 방향을 가질 수 없으므로, 같은 위치에 여러 개의 버텍스를 배치하여 각기 다른 방향을 설정함
버텍스 셰이더의 역할
- 빛이 반사되는 방향을 계산하여 조명 효과를 적용함
UV 좌표
개념
- 3D 모델에 텍스처를 매핑하기 위한 2D 좌표계를 의미
- 최소 좌표는 (0,0), 최대 좌표는 (1,1)로 정규화됨
- 0보다 작거나 1보다 크면 텍스처가 반복됨 (타일링 효과)
활용
- 개체에 이미지를 씌울 때, 해당 이미지의 크기로 나눈 비율을 UV 좌표(0~1)에 대입하여 매핑
- 폴리곤의 각 점에 대응하는 텍스처 좌표를 지정하여 정확한 이미지 매핑을 수행함
- 종이접기와 비슷한 개념
DDS(Texture 압축 포맷)
2의 제곱 크기 제한
- 게임에서 사용되는 모든 텍스처는 2의 n승(예: 256x256, 512x512, 1024x1024 등)의 크기를 유지해야 함
- 이유: DirectX에서 연산 속도 최적화를 위해 float 기반 연산을 사용하며,비정규 크기의 텍스처는 자동으로 더 큰 크기로 확장됨 → 메모리 낭비 및 성능 저하 발생
API 클래스화 + DirectX을 적용
api.h
#pragma once
#include <windows.h>
class C_API
{
private:
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 updataMsg();
};
api.cpp
#include "api.h"
#include "resource.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)
{
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_APIDIRECTX));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = L"Main";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassExW(&wcex);
m_hWnd = CreateWindowW(L"Main", nullptr, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, m_hInstance, nullptr);
if (!m_hWnd)
return FALSE;
ShowWindow(m_hWnd, SW_SHOWDEFAULT);
UpdateWindow(m_hWnd);
return true;
}
void C_API::updataMsg()
{
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
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>
class C_DX
{
private:
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = NULL;
ID3D11DeviceContext* g_pImmediateContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11Texture2D* g_pDepthStencil = NULL;
ID3D11DepthStencilView* g_pDepthStencilView = NULL;
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;
ID3D11InputLayout* g_pVertexLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;
ID3D11Buffer* g_pIndexBuffer = NULL;
ID3D11Buffer* g_pCBNeverChanges = NULL;
ID3D11Buffer* g_pCBChangeOnResize = NULL;
ID3D11Buffer* g_pCBChangesEveryFrame = NULL;
ID3D11ShaderResourceView* g_pTextureRV = NULL;
ID3D11SamplerState* g_pSamplerLinear = NULL;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
XMFLOAT4 g_vMeshColor;
public:
C_DX() = default;
void init();
};
dx.cpp
#include "dx.h"
void C_DX::init()
{
g_driverType = D3D_DRIVER_TYPE_NULL;
g_featureLevel = D3D_FEATURE_LEVEL_11_0;
g_vMeshColor = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
}
main.cpp
#include "framework.h"
#include "ApiDirectX.h"
#include "api.h"
#define MAX_LOADSTRING 100
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
C_API::createApi();
C_API::getApi()->init(hInstance);
C_API::getApi()->updataMsg();
C_API::releaseApi();
}
'C++' 카테고리의 다른 글
[강의] 2월 11일 수업정리 (0) | 2025.02.11 |
---|---|
[강의] 2월 10일 수업정리 (0) | 2025.02.10 |
[강의] 2월 5일 수업정리 (0) | 2025.02.05 |
[강의] 2월 4일 수업정리 (0) | 2025.02.04 |
[강의] 2월 3일 수업정리 (0) | 2025.02.03 |