C/C++에 추가포함 디렉터리에 Include 폴더, 라이브러리에 추가 라이브러리 디렉터리에 Lib 폴더를 추가해준다
Client
Client 프로젝트에 속성에 현재 C/C++ 속성이 없는데 이는 프로젝트에 C/C++ 파일이 하나도 없기 때문이므로 미리컴파일된 헤더 클래스를 하나 만들어주면 뜨는것을 볼 수 있다
C/C++ 속성에 추가포함 디렉터리에 라이브러리 안에 Include 폴더와 Engine 프로젝트 폴더를 추가하여 Client에서 사용할 수 있게 해준다
이번엔 링커에 추가 라이브러리 디렉터리에 Lib 파일을 추가해준다
이번엔 미리 컴파일된 헤더속성을 변경해준다(Rider에서는 이상하게 cpp에 use가 create로 바뀌지 않아 visual studio로 열어 바꿔줘야함)
빌드 이벤트
Engine 프로젝트에 있는 .h가 모두 라이브러리의 Include->Engine에 저장되게 하고싶으니 Engine 프로젝트 속성에 빌드 이벤트에서 이를 할 수 있다
xcopy는 복사를 하겠다는 뜻이고, /Y는 오버라이트(이미 있는 파일에 덮어쓰기)를 하겠다는 뜻이고, Engine에 있는 *.h 는 모든 h를 뒤에 있는 경로로 복사해주겠다는 것이다
이렇게 되면 Client에 추가포함 디렉터리에 Engine을 연결해도 되지만 라이브러리에 Include->Engine을 연결해줘도 된다
Engine 만들기
Engine은 저번 프로젝트에서 만든것을 대부분 복붙해서 사용할 것이다
먼저 저번 프로젝트에서 만들었던 것처럼 필터를 만들어준다
pch.h ... #define WIN32_LEAN_AND_MEAN // 거의 사용되지 않는 내용을 Windows 헤더에서 제외합니다. ...
framework.h헤더는 사실상 위의 코드때문에 존재하므로 pch.h로 옮기고 삭제해줘도 된다
먼저 Define.h는 아직까지는 별거 없지만 싱글톤을 사용할때 사용하는 메크로이다
EnginePCH.h는 엔진과 관련된 필수 헤더들이 모여있는 헤더로 저번 프로젝트에서는 pch.h에 있던 것들로 이름을 바꾼것으로 바뀐점은 FX11d3dx11effect.h가 추가됐는데 이것이 라이브러리에서 추가한 그 헤더이다
Type.h는 Type과 관련된 애들이 모여있는 헤더로 저번 프로젝트에 있는 그 .h이다
이 3개를 먼저 가져와준다
Utils
저번 프로젝트때 다 봤던 파일들이고 Untils라는 파일이 새로 추가됐는데 이는 지금 당장은 중요하지 않지만 온갖 잡동사니들을 필요하겠다 생각이 들면 작업을 할 파일이다
pch.h
pch.h에 모든 내용은 EngeinPch.h에 있으므로 다 지우고 EnginePch.h만 include해주면 된다
이렇게 빼서 나눈 이유는 Client에서도 EnginePch.h 파일을 긁어 사용할 예정이기 때문이다
Manager
위에 추가된 파일들의 .h에는 모두 싱글톤을 사용할 것이므로 DECLARE_SINGLE()메크로가 추가되어있다
TimeMGR, InputMGR
지난번 사용하던 파일과 동일
ResourceMGR
저번 프로젝트에서 마지막에 만들었던 리소스를 관리하는 메니저로 여러 리소스들의 타입들을 편리하게 관리할 수 있는 MGR이다
Graphics
이 클래스는 Device, DeviceContext를 통해 GPU에 일을 시키는 등을 하면서 온갖 리소스들을 만들고 파이프라인에 연결시켜주는 용도로 사용할 클래스이다
또한 SwapChain을 이용해 더블 버퍼링을 이용해 화면에 그려주는 것까지 하는 클래스이다
#define 메크로
이들을 싱글톤으로 만들어 이제는 Device나 DeviceContext등을 넘겨주고 받아서 일을 처리하는게 아닌 직접 불러서 사용할 수있게 하였는데 이들을 메크로로 이름을 지정해 부를 수 있게 만들어 줬다
EnginePch.h
#define CHECK(p) assert(SUCCEEDED(p))
#define GAME GET_SINGLE(Game)
#define GRAPHICS GET_SINGLE(Graphics)
#define DEVICE GRAPHICS->GetDevice()
#define DC GRAPHICS->GetDeviceContext()
#define INPUT GET_SINGLE(InputManager)
#define TIME GET_SINGLE(TimeManager)
#define DT TIME->GetDeltaTime()
#define RESOURCES GET_SINGLE(ResourceManager)`
Game
이 클래스는 우리가 저번에 만들었던 프로젝트의 Main 함수가 있는 창을 보면 윈도우 창 정보를 등록하고, 윈도우 창을 생성한 뒤 메인루프를 돌면서 PeekMessage, Update등을 하는 것을 클래스 형태로 빼놓은 것이다
즉 메인 윈도우를 런치하는 부분을 엔진에 Game이라는 클래스로 만든것이다
여기서 실행 단위라는 개념이 등장하는데 실제로 클라이언트를 하나 만들고 다른 실습을 할때 그 클라를 지우지 않고 실행 단위라는 개념을 도입해 편리하게 꽂는 기능을 도입했다
이는 나중에 실습때 자세히 설명할 예정이며 00.Engine폴더에 추가했다
Graphics
ConstantBuffer
상수 버퍼는 GPU에 데이터를 넘겨주는 버퍼로 Device->CreateBuffer()를 통해 만들어준 뒤 상수 버퍼에 값을 복사해 주는 역할을 하는 클래스이다 3D11_MAPPED_SUBRESOURCE subResource; ZeroMemory(&subResource, sizeof(subResource)); 이 구조체는 GPU 메모리에 메핑된 데이터에 접근하기 위한 정보를 가진 데이터로, 구조체의 메모리를 0으로 초기화 한것이다::memcpy(subResource.pData, &data, sizeof(data)); 를 통해 CPU의 데이터를 GPU로 복사해준다
DC->Unmap(_constantBuffer.Get(), 0); Unmap 함수를 통해 GPU 메모리와 CPU 메모리의 매핑을 해제하여 GPU에서 해당 상수버퍼를 사용할 수 있게 된다
DC->Map(_constantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource); DeviceContext의 Map은 GPU 메모리의 특정 영역을 CPU에 매핑하거여 데이터를 읽거나 쓸 수 있는 함수이다 상수 버퍼를 가져온 뒤, 버퍼 부분을 선택하는데 0은 전체 버퍼를 대상으로 한다는 의미를 가지며, D3D!!_MAP_WRITE_DISCARD는 버퍼에 데이터를 쓸 때 기존 데이터를 무시하고 새로 쓴다는 것을 나타낸 것이며, 특수 플래그를 사용할지 정한 뒤,위에서 만든 구조체의 주소를 넘겨 Map 함수에서 반환되는 매핑된 데이터에 대한 정보를 저장한다
Geometry
어떤 기하학적 모형을 나타내기 위해 단위를 클래스로 만든 것이다
이 클래스는 IndexBuffer, VertexBuffer를 배열로 가지고 있으며, 특정 모형을 그려줄 때 Index, VertexBuffer들을 배열에 저장하고 내보내는 역할로 이를 통해 점을 찍고 그 점을 연결해 모형을 나타낼 수 있다
VertexBuffer, IndexBuffer
이 클래스는 IndexBuffer와 VertexBuffer를 만들어주는 클래스이다
VertexBuffer는 Geometry에서 도형을 표현한 것을 GPU에 복사해주는 역할을 한다
IndexBuffer는 VertexBuffer와 비슷하지만 Index와 관련된 것들을 GPU로 복사하는 역할을 한다
VertexData
정점들어 어떤식으로 표현되는지를 나타내는 방법을 구조체로 가지고 있다
이 정보들은 Shader와 밀접한 관계가 있으며 이 데이터들을 Buffer들을 통해 GPU로 복사되는 값들이다
Shader
Graphics에 Shader라는 폴더를 만들어 줄 것이다
이제는 지금까지 만들었던 Shader와 다른 방식으로 진행할 것이다
이전에 만들었던 쉐이더는 쉐이더 리소스를 로드한 다음 Vertex Shader나 Pixel Shader라는 클래스로 만들어 관리하고, 렌더링파이프라인 단계에서 실행되는 코드들이였고, 거기에 인자를 넣기 위해 Material이라는 개념을 통해 조립을 했었다
하지만 이 방법은 Vertex 데이터에 InputLayout을 묘사한 후 연동시키고, 세부적인 상수버퍼를 통해 인자를 넘겨서 작업을 했는데 이는 Shader가 많아지면 짝을 맞춰주는 것이 엄청 힘들것이다
그래서 우리는 이를 직접 관리하는 것이 아닌 effect11를 사용해서 할 것이다
effect11을 사용하기 전 이와 랩핑된 파일들을 사진처럼 가져와 줄것이다
이들은 우리가 나중에 사용하면서 자세히 공부할 것이다이를 사용하기 위해 미리 컴파일된 헤더에 FX11에 Effects11을 사용하겠다 추가해주고, 이놈은 Shader를 로드함과 동시에 머터리얼 코드, 우리가 지난번에 만들었던 Shader에 인자를 꽂아넣는 작업까지 하나로 묶여있는 놈이다
그 안들 들어가보면 Engine내의 Gmae 클래스로 Run 함수에서는 우리가 설정한 값을 가지고 윈도우 창의 정보를 등록하고, 윈도우 창을 생성 해줄 것이다
그 후 Update 함수를 호출하는데 이는 MANAGER들의 Update 함수를 호출하고, Graphics의 RenderBegin과 우리가 설정한 app의 Update, Render 그리고 Grahpics의 RenderEnd를 호출하여 창에 그림까지 그려주게 되는 것이다
이 과정이 저번 프로젝트에서 화면을 띄어 그림을 그려주는 과정이랑 동일한 과정이 될 것이다
Shader 입히기
이제 TriangleDemo에 삼각형을 찍어볼 것이다
그러기 위해 Shader를 추가해 작업을 해줄것이므로 HLSL을 꼭지점으로 추가해준다
이때 솔루션 파일이 있는 위치에 Shader 폴더로 저장을 해줄것은데 이는 리소스 파일이므로 소스코드들과 분리되어 관리하도록 하기 위함이다