C++

[강의] 2월 7일 수업정리

k-codestudy 2025. 2. 7. 17:50

오늘은 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