DirectX/DirectX 2D

DX 셋팅

컴맹학자 2022. 11. 5. 23:57
728x90

1. DirectX 설치 

구글 검색 : directx software development kit

홈페이지 : https://www.microsoft.com/en-us/download/details.aspx?id=6812

 

다운로드


 

설치 진행 (설치 과정은 그냥 동의만 하면되니 별다른 과정 안올림)

※ 설치 과정에서 먼가 오류가 나올수도 있는데 해당 라이브러리 덮어쓰기 관련 일 수 있으니 동의 하고 다운


 

설치 경로는 왠만하면 기본경로 지정


2. 사용할 IDE, 프로젝트 생성

Visual Studio 2019


 

새로운 프로젝트 생성


 

개발 기본 환경 (빈 프로젝트)


 

경로 & 이름설정


3. 헤더 파일 생성 & 경로 셋팅

임시로 dx 사용 환경을 정의 해줄 헤더 작성 예정.

 

솔루션 정리 & Device.h 생성 


 

경로 정의 셋팅 (View -> Other Windows -> Property Manager -> Win32.user 더블 클릭)

※ .user가 없는 경우 마우스 우클릭하고 수동으로 .user 생성


 

DirectX SDK 경로를 환경 변수 셋팅

※ DH, DL이름으로 경로를 매크로 형식으로 저장


 

프로젝트 속성 (Solution Explorer -> DX_2D 솔루션 우클릭 -> Properties 클릭)

VC++ Directories에서 만든 매크로 경로 셋팅


4. 헤더 파일 작성 및 프로젝트 설정 변경

헤더파일

더보기
#pragma once
//Window
#include <Windows.h>
#include <assert.h> //검사용
//STL
#include <vector>
#include <string>
using namespace std;
//DX Lib
#include <d3d11.h>
#include <D3DX11.h>
#include <D3DX10.h>
#include <D3DX10math.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
//Global Variable
//--윈도우
const UINT Width = 1024;
const UINT Height = 768;
extern HWND Hwnd;
extern wstring Title;
//--DX ComInterfase
extern IDXGISwapChain* SwapChain; // 2개의 화면을 교체하는 변수
extern ID3D11Device* Device; // dx자원을 셋팅용
extern ID3D11DeviceContext* DeviceContext; // dx에서 사용하는 HDC(렌더링)
extern ID3D11RenderTargetView* RTV; // 실제 화면을 보여주는 용
//https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nn-d3d11-id3d11pixelshader
extern ID3D11VertexShader* VertexShader; // vs 단계에서 정점을 제어
extern ID3D11PixelShader* PixelShader; // ps 단계에서 픽셸을 제어
extern ID3D10Blob* VsBlob; // 쉐이더 처리값 받는용 Vs용
extern ID3D10Blob* PsBlob; // 쉐이더 처리값 받는용 Ps용
//Global Function
void InitWindow(HINSTANCE hInstance, int nCmdShow); // 윈도우 클래스 관련 셋팅
void InitDirct3D(HINSTANCE hInstance); // dx변수 관련 셋팅
void Destroy(); // 할당 받은 변수들 반환
WPARAM Running(); // Win32API 작업
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); // Win32API 이벤트
//Global Scene Function
//void InitScene();
//void DestroyScene();
//void Update();
//void Render();
//TypeDef
typedef D3DXVECTOR3 Vector3;
typedef D3DXVECTOR2 Vector2;
typedef D3DXMATRIX Matrix;
typedef D3DXCOLOR Color;
typedef D3DXQUATERNION Quaternion;
//Macro
#define SAFE_DELETE(p) { if(p) {delete (p); (p) = NULL;}}
#define SAFE_DELETE_ARRAY(p) { if(p) {delete[] (p); (p) = NULL;}}
#define SAFE_RELEASE(p) { if(p) {(p)->Release(); (p) = NULL;}}

 

프로젝트 설정 (콘솔 -> 사용 않함 변경)

※ int main이 아닌 Win32API 사용하는 main 함수를 사용 하기 위해서 변경


5. Device.cpp

Dx를 실행 하는 main 함수 클래스

 

1. WinMain 함수 

> Win32API 에서 사용되는 Main 함수이며 프로그램 빌드되면 제일 처음으로 불러오는 함수

> 각각의 함수들을 호출하고 마지막에 종료가 되면 반환되는 시작과 끝

더보기
#include "Device.h"
//1
int APIENTRY WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
InitWindow(hInstance, nShowCmd); //2
InitDirct3D(hInstance); //3
Running(); //4
Destroy(); //5
//윈도우 반환
DestroyWindow(Hwnd);
UnregisterClass(Title.c_str(), hInstance);
return 0;
}

 

2. Global Variable, extern 변수 초기화

> WinMain 바로 밑에다 공통으로 사용하는 모든 변수들 초기화

더보기
HWND Hwnd = nullptr;
wstring Title = L"DX_2D";
IDXGISwapChain* SwapChain = nullptr;
ID3D11Device* Device = nullptr;
ID3D11DeviceContext* DeviceContext = nullptr;
ID3D11RenderTargetView* RTV = nullptr;
ID3D11VertexShader* VertexShader = nullptr;
ID3D11PixelShader* PixelShader = nullptr;
ID3D10Blob* VsBlob = nullptr;
ID3D10Blob* PsBlob = nullptr;

 

3. 윈도우 클래스 정의

> 윈도우 관련 클래스들 초기화

더보기
void InitWindow(HINSTANCE hInstance, int nCmdShow)
{
// 윈도우 클래스 셋팅
{
WNDCLASSEX wcx;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = WndProc;
wcx.cbClsExtra = NULL;
wcx.cbWndExtra = NULL;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)WHITE_BRUSH;
wcx.lpszMenuName = NULL;
wcx.lpszClassName = Title.c_str();
wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WORD check = RegisterClassEx(&wcx);
assert(check != NULL);
}
//윈도우 클래스 생성 & 윈도우 출력
{
Hwnd = CreateWindowEx
(
NULL,
Title.c_str(),
Title.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
Width,
Height,
NULL,
NULL,
hInstance,
NULL
);
assert(Hwnd != NULL);
//실제 모니터값 가져와서 위치 셋팅
RECT rect = { 0, 0, (LONG)Width, (LONG)Height };
UINT centerX = (GetSystemMetrics(SM_CXSCREEN) - (UINT)Width) / 2;
UINT centerY = (GetSystemMetrics(SM_CYSCREEN) - (UINT)Height) / 2;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
MoveWindow
(
Hwnd, centerX, centerY,
rect.right - rect.left, rect.bottom - rect.top,
TRUE
);
ShowWindow(Hwnd, nCmdShow);
UpdateWindow(Hwnd);
}
}

 

4. Dx에서 사용할 변수들 셋팅

※ 크게 보면 Buffer, RTV, ViewPort 값을 셋팅 하고 Device, DeviceContext, SwapChin 만드는 과정 

더보기
void InitDirct3D(HINSTANCE hInstance)
{
//Buffer 설명서
DXGI_MODE_DESC desc;
ZeroMemory(&desc, sizeof(DXGI_MODE_DESC));
desc.Width = Width;
desc.Height = Height;
desc.RefreshRate.Numerator = 60;
desc.RefreshRate.Denominator = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//SwapChain 설명서
DXGI_SWAP_CHAIN_DESC swapDesc;
ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapDesc.BufferDesc = desc;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.BufferCount = 1;
swapDesc.SampleDesc.Count = 1;
swapDesc.SampleDesc.Quality = 0;
swapDesc.OutputWindow = Hwnd;
swapDesc.Windowed = TRUE;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//사용할 버젼
vector<D3D_FEATURE_LEVEL> feature_level =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
};
//Create Device & SwapChain
HRESULT hr = D3D11CreateDeviceAndSwapChain
(
NULL,
D3D_DRIVER_TYPE_HARDWARE, // 사용할 환경
NULL,
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
feature_level.data(),
feature_level.size(),
D3D11_SDK_VERSION,
&swapDesc,
&SwapChain,
&Device,
NULL,
&DeviceContext
);
assert(SUCCEEDED(hr));
//Get BackBuffer
ID3D11Texture2D* BackBuffer;
//GPU가 사용 하는 방식
hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
assert(SUCCEEDED(hr));
// RTV 생성하고 화면에 나타내는 백버퍼(Resource)자원 셋팅
hr = Device->CreateRenderTargetView(BackBuffer, NULL, &RTV);
assert(SUCCEEDED(hr));
BackBuffer->Release(); //반환(삭제)
//OM Set
DeviceContext->OMSetRenderTargets(1, &RTV, NULL);
//Create Viewport
{
D3D11_VIEWPORT viewPort;
ZeroMemory(&viewPort, sizeof(D3D11_VIEWPORT));
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
viewPort.Width = (float)Width;
viewPort.Height = (float)Height;
DeviceContext->RSSetViewports(1, &viewPort);
}
}

 

5. Rendering 관련 

※ Update, Render 및 msg 관련 무한 반복 처리 하기 위한 함수 ( 주석처리 된 함수들은 아직 사용 미사용 )

더보기
WPARAM Running()
{
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
//InitScene();
while (true)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
//여기 들어오면 종료
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//Update();
//Render();
}
}
//DestroyScene();
return msg.wParam;
}

 

6. 해제

※ 현재는 사용하지 않음

void Destroy()
{
}

 

7. 메시지 처리

※ Win32API 관련 Call Back 함수

더보기
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY: PostQuitMessage(0); break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

 

6. 실행

※ 현재 모니터 중앙에 800 * 600 짜리 화면이 출력

 

 

1. Win32API 관련만 셋팅

2. 현재 값만 셋팅하고 dx 관련 출력은 아직 안함

'DirectX > DirectX 2D' 카테고리의 다른 글

DX_2 삼각형, DX_3 RS  (0) 2022.11.13
DX_1 배경 화면 & Line  (0) 2022.11.06
DX 렌더링 파이프라인 구조  (0) 2022.11.06
Win32API C++ 작성  (0) 2022.10.30
2D 시작하기 전에 필요한 최소의 지식들  (0) 2022.10.30