결과물


코드

GrideDemo.cpp


Camera.cpp

 

Freedom.cpp ( class Freedom : public Camera )

 

'DirectX 11 > 코드 분석' 카테고리의 다른 글

Texture Sampler  (0) 2022.02.08
Texture  (0) 2022.02.08
Index Buffer / World Scale, World Translation  (0) 2022.02.08
World, View, Projection  (0) 2022.02.08
Triangle  (0) 2022.02.07

결과물

 


코드

IndexDemo.cpp

 


추가

DXGI_FORMAT

더보기

마지막에

GetDC()->IAsetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0); 인 부분이 있는데

여기서 DXGI_FORMAT이란

 

리소스를 어떻게 해석할것인가 인데

리소스 :  Direct3D 파이프라인에서 액세스할 수 있는 메모리 영역, buffer유형과 texture유형이 있다.

 

종류에 R32G32B32, R16,G16,B16,A16...이런식으로 있다고 색과 관련된건아니다.

그냥 데이터가 몇개인지 분류하는 형식이다.

 

예를들어

DXGI_FORMAT_R32 는 어떤 32bit짜리 데이터하나가 있다는것이고

DXGI_FORMAT_R32B32는 어떤 32bit짜리 데이터형 A와 어떤 32bit짜리 데이터형 B가 있다는것이다.

 

그러므로 IAsetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0); 코드에서

DXGI_FORMAT_R32_UINT가 넘어가는 이유는

indexBuffer가 4byte(32bit)UINT 으로 구성되어있다고 뜻하는 말이다.

 

https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-types#texture-resources

 

Resource Types (Direct3D 10) - Win32 apps

All resources used by the Direct3D pipeline derive from two basic resource types: buffers and textures. A buffer is a collection of raw data (elements); a texture is a collection of texels (texture elements).

docs.microsoft.com

 

 

'DirectX 11 > 코드 분석' 카테고리의 다른 글

Texture Sampler  (0) 2022.02.08
Texture  (0) 2022.02.08
Grid / Camera  (0) 2022.02.08
World, View, Projection  (0) 2022.02.08
Triangle  (0) 2022.02.07

결과물

 


코드

World.cpp

 


World.fx

전역변수 생성


추가

UpdateSubresource

더보기

CPU에서 VRam으로 값을 복사해 넘겨주는데 두가지 방법이 있다.

그중 하나가 UpdateSubresource이다.

속도가 늦은편이라 대체로 CPU에서 업데이트가 드문드문할때 추천한다고 한다.

드문드문 : 프레임당 한번이하

Default Buffer의 경우, UpdateSubResource를 사용해서만 업데이트 할 수 있다.

Default Buffer는 속성중 Resource Usage Type이 DEFAULT인걸 뜻한다.

 

공간변환

더보기

정점위치에 공간행렬을 곱하면 그 공간으로 변환이 된다.

공간행렬은 각 공간의 원점과 세 축을 알면 만들 수 있다.

그래서 Vertex Shader에서 mul함수를 사용하는것

mul : multiply 곱셈

 

World

더보기

정점의 로컬공간으로도 움직일수 있는데 왜 world공간이 필요한가? 한다면

한번에 모두 이동시키기 편하기 때문이다.

 

정점은 모든 정점을 다 일일히 이동시켜줘야한다. = 매우 반복적이고 느림

world공간으로 계산한다면 한번에 모두 이동시킬수 있다.

 

그래서 거의 대부분 그려질 클래스들은 모두 정점버퍼를 가지고있고

그 정점을 움직이기 위해 world매트릭스를 가지고 있다.

 

 

https://grandstayner.tistory.com/entry/DirectX-11-UpdateSubResource-Map-Unmap-CopyResource-CopySubresourceRegion%EC%9D%98-%ED%8C%81

 

DirectX11 - UpdateSubResource(), Map() ~ Unmap(), CopyResource(), CopySubresourceRegion()의 팁

DirectX 11에서는 Resource에 데이터를 넣는 함수는 4개가 존재한다. UpdateSubresource(), Map() ~ Unmap(), CopyResource(), CopySubresourceRegion() 이 함수들은 자주 사용되는 만큼 어느 정도는 알고 사용해..

grandstayner.tistory.com

https://gamedevforever.com/230

 

D3D11에서 Lock ??

제가 연재하는 날은 아니지만, 최근 플밍 관련 글도 자주 올라오지 않고, 겸사 겸사 정리하고 있던 내용도 있던 찰나에 불쑥 제가 한번 난입했습니다. ㅎㅎㅎ. 다들 DirectX11 공부를 하고 계신지

gamedevforever.com

'DirectX 11 > 코드 분석' 카테고리의 다른 글

Texture Sampler  (0) 2022.02.08
Texture  (0) 2022.02.08
Grid / Camera  (0) 2022.02.08
Index Buffer / World Scale, World Translation  (0) 2022.02.08
Triangle  (0) 2022.02.07

DEFAULT

GPU가 이 리소스를 빠르게 읽기 및 쓰기 권한이 가능하다.

오직 UpdateSubresource만을 사용하여 업데이트 할 수 있다.

렌더타겟에서 사용될때 좋은 후보가 될수있다 =>무슨말?

 

 

IMMUTABLE

GPU만이 이 리소스를 빠르게 읽을 수 있다.
일단 생성되면 업데이트할 수 없습니다.
생성 호출 중에 초기 데이터를 전달해야 합니다.
변하지 않는 리소스(정적 텍스처, Vb/Ib)에 좋은 후보가 될 수 있습니다.

Vb/Ib : VertexBuffer, IndexBuffer

모든것을 IMMUTABLE로 만들려 애쓰지 마라

 

 

DYNAMIC

빠른 CPU 쓰기 액세스가 필요한 리소스에 사용
(GPU 읽기 액세스 속도가 느려짐)
CPU 읽기 액세스 없음
밑의 두가지 플래그와 Map을 사용하여만 업데이트할 수 있습니다.

  • D3D10_MAP_WRITE_DISCARE
  • D3D10_MAP_WRITE_DNO_OVERWRITE

동적 텍스처, 동적 VertexBuffer는 좋은 후보입니다.

 

 

STAGING

GPU에서 데이터를 다시 읽을 수 있는 유일한 방법입니다.
MAP을 사용해야만 업데이트할 수 있습니다.
단 밑의 플래그와는 매핑할 수 없음

  • D3D11_MAP_WRITE_DISCARD
  • D3D11_MAP_WRITE_NO_OVERWRITE

gpu가 지연되지 않도록 버퍼를 두 배로 늘릴 수 있습니다.
GPU는 이것들을 직접 사용할 수 없다.

 

 


Vertex Buffer의 경우

 

버텍스 버퍼가 프레임당 한 번 미만의 CPU에 의해 터치됨
=> D3D11_USAGE_DEFAULT로 생성하여 UpdateSubresource를 사용하여 업데이트 해라


정점 버퍼는 동적 지오메트리에 사용되며 CPU에서 프레임당 여러 번 업데이트할 필요가 있는 경우

=> D3D11_USAGE_DYNAMIC으로 생성하여 MAP을 통해 업데이트 해라

 

 


사용하면서 내 경험으로 더 알아가면서 추가로 포스팅해야겠다.

 

https://www.slideshare.net/cagetu/windows-to-reality-getting-the-most-out-of-direct3-d-10-graphics-in-your-games

 

Windows to reality getting the most out of direct3 d 10 graphics in…

Windows to Reality: Getting the Most out of Direct3D 10 Graphics in Your Games Shanon Drone Software Development Engineer XNA Developer Connection Microsoft

www.slideshare.net

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=masca140&logNo=220719096462 

 

Direct3D 11의 자원들 (1)

자원을 이야기 하자면 자원 사용의 두 측면을 모두 살펴보는 것이 타당하다. 응용 프로그램의 관점에서 중...

blog.naver.com

 

'DirectX 11 > 개념 정리' 카테고리의 다른 글

동차 표기법 (Homogeneous)  (0) 2022.02.09
Vertex Shader, Pixel Shader, Rasterizer  (0) 2022.02.07
Device & Device Context / COM객체  (0) 2022.02.06

결과물

WVP 변환이 되지 않은 로컬공간의 삼각형


코드

예제에서는 fx셰이더를 사용한다.

 

TriangleList.cpp

 


Triangle.fx

Vertex Shader나 Pixel Shader를 생성하는건 hlsl과 비슷

fx에서는 technique과 pass가 있는데

편하게 골라 사용할 수 있다.

 

'DirectX 11 > 코드 분석' 카테고리의 다른 글

Texture Sampler  (0) 2022.02.08
Texture  (0) 2022.02.08
Grid / Camera  (0) 2022.02.08
Index Buffer / World Scale, World Translation  (0) 2022.02.08
World, View, Projection  (0) 2022.02.08

Vertex Shader

주 역할은 3D공간 상의 정점들의 위치를 화면좌표로 변환한다.

고로 정점하나당 Vertex Shader가 한번 실행된다.

 


Rasterizer

정점이 찍힌다면 이제 정점과 정점사이에 선을 그릴것이다.

그 선이 이어져서 삼각형을 만들수있다.

 

그렇다면 정점과 정점사이에는 몇개의 픽셀이 들어가있을까?

혹은 만들어진 삼각형안에 몇개의 픽셀이 어떻게 있을까?

 

이러한 정점 사이에 있는 픽셀들을 어디에 몇개나 그려야 하는지 알아내는 단계가 레스터라이저에서 이루어진다.

 


Pixel Shader

Vertex shader는 정점하나당 실행된다.

그렇다면 Pixel Shader는?

래스터라이저에서 계산된 픽셀 수 만큼 실행된다.

 

역할은 그 픽셀의 최종색상을 계산하는것

 


Shader

고로 셰이더란 화면에 존재하는 각 픽셀의 위치와 색상을 계산하는 함수이다.

 

셰이더에서 사용할 수 있는 입력 값으로는 전역변수와 정점데이터가 있다.

 

한 물체를 구성하는 모든 정점이 동일한 값을 사용한다면 전역변수가 될수있고

한 물체를 구성하는 모든 정점 : 예를들어 한 캐릭터를 그리기 위한 모든 정점

각 정점마다 다른 값을 사용하면 정점 하나하나의 데이터로 받아들여야한다.


https://kblog.popekim.com/2011/11/01-part-1.html

 

[포프의 쉐이더 입문강좌] 01. 쉐이더란 무엇이죠? Part 1

게임 프로그래머 김포프의 블로그

kblog.popekim.com

https://gasbebe.github.io/shader/

 

'DirectX 11 > 개념 정리' 카테고리의 다른 글

동차 표기법 (Homogeneous)  (0) 2022.02.09
D3D11_USAGE / Resource Usage Type  (0) 2022.02.08
Device & Device Context / COM객체  (0) 2022.02.06

Device & Device Context

 

이 두 인터페이스는 Dx의 주된 인터페이스로 물리적인 그래픽 장치 하드웨어에 대한 제어기다.

ID3D11Device, ID3D11DeviceContext 의 맨 앞이 모두 ' I ' 이므로 인터페이스인걸 확인 알 수 있다.

ID3D11Device / 모두 순수가상함수로 이루어져있다.

 

가장 주요한 인터페이스기에 Direct3D 초기화의 시작은 Device와 Device Context의 생성으로 시작 된다.

 

생성의 함수는

D3D11CreateDevice ( 혹은 D3D11CreateDeviceAndSwapChain사용 )

 

HRESULT D3D11CreateDevice(

     IDXGIAdapter *pAdapter,

     D3D_DRIVER_TYPE DriverType,

     HMODULE Software,

     UINT Flags,

     const D3D_FEATURE_LEVEL *pFeatureLevels,

     UINT FeatureLevels,

     UINT SDKVersion,

     ID3D11Device **ppDevice,

     D3D_FEATURE_LEVEL *pFeatureLevel,

     ID3D11DeviceContext **ppImmediateContext

);

 

주요 매개변수만 보자면

pAdapter : 디스플레이 어댑터를 지정한다

디스플레이 어댑터 : 그래픽 카드

ID3D11Device **ppDevice : 생성된 Device를 돌려줌

ID3D11DeviceContext **ppImmediateContext : 생성된 DeviceContext를 돌려줌

 

이러한 매개변수를 받는다는게

이 함수에서 그래픽 카드를 연결해준다는걸 추리해볼수있다.

 

 

ID3D11Device의 함수를 보면 거의 다 함수 앞에 Create가 붙어있었다.

셰이더를 만들고(Create)

텍스처의 배열을 만들고(Create)

버퍼를 만들고(Craete)

이런걸로 봤을때 Device의 역할은 그래픽을 그리는 자원들을 생성하고 준비하게끔 도와주는 역할이라 생각한다.

 

ID3D11DeviceContext의 함수는 대부분 Set과 Get이 많이 들어가 보였다.

버퍼를 세팅하고, 가져오고(Set, Get)

셰이더를 세팅하고(Set)

각 파이프라인 단계를 세팅하고(Set)

이런걸로 봤을때 Device로 생성된 자원들을 디스플레이 어댑터에 세팅하고 세팅되었던걸 가져오고 이러한 역할같다.

 

+DeviceContext는 주 쓰레드와 그외의 쓰레드일때 다른 문맥을 생성해야한다고 한다.

주 쓰레드면 위의 방식으로 생성, 즉시문맥이 생성되고( immediate context )

멀티 쓰레딩 환경에서 그 외의 쓰레드(일꾼쓰레드)이면 ID3D11Device::CreateDeferredContext으로

지연문맥을 생성한다 ( deferred context )

 

그래서 일꾼쓰레드가 ID3D11CommandList에 그리기 명령을 기록한다.

주쓰레드에서 그 기록들을 실행한다고 한다.

 


COM 객체 (Component Object Model)

 

COM객체또한 액터가 아닌 언어의 독립성과 호환성을 가능하게 하는 기술이라고 한다.

언어의 독립성 : 극단적 예시로 A라는 COM객체를 c++ 에서도 사용하고 java에서도 사용하고 python에서도 사용한다

 

갑자기 왜 나왔냐면 Device & Device Context가 COM객체이기 때문이다.

이유는 모든 COM객체는 IUnknown이라는 COM 인터페이스 기능을 상속받기 때문이다.

IUKnown을 상속받는 이유는 모든 COM객체가 같은 고유한 방식으로 메모리를 관리하기때문

Device Context는 ID3D11DeviceChild를 상속받는다.

일단 언리얼에서 컴포넌트를 다뤘다면 대강 그림이 그려진다.

컴포넌트의 이유가 어느 액터이던간에 땟다 붙엿다 하려고 컴포넌트를 생성했었는데

 

이러한 COM객체는 인터페이스형태로 우리에게 보여지며

New처럼 객체를 생성하지 못하고 특별한 함수나 다른 COM인터페이스의 메서드를 이용하여 얻어야한다.

 


맨위 사진의 맨 첫줄 MIDL_INTERFACE("db6f6ddb-ac77-4e88-8253-819df9bbf140") 는

uuid라는걸 뜻하는데 개념이 아직 너무 막연하고 아직 필요성은 없는거 같아 나중에 필요해질때 다시 찾아보자

 

'DirectX 11 > 개념 정리' 카테고리의 다른 글

동차 표기법 (Homogeneous)  (0) 2022.02.09
D3D11_USAGE / Resource Usage Type  (0) 2022.02.08
Vertex Shader, Pixel Shader, Rasterizer  (0) 2022.02.07

말그대로 사용자의 지정 축을 만들 수 있는 기능이다.

 

  • C++

FRotator UKismetMathLibrary::MakeRotationFromAxes(FVector Forward, FVector Right, FVector Up)

 

각 매개변수 Forward, Right, Up 벡터를 넣으면 하나의 축을 만들어 FRotator형으로 반환해준다.

 

  • Blueprint


나의 사용처

 

현재 벽에서 뛰어다닐 수 있는 기능을 구현중인데

WASD로 벽에서 자연스럽게 움직이려면

trace로 충돌한 벽의 hitResult에 Normal값을 Up vector (벽에 수직방향)

카메라가 바라보는 방향을 벽에 붙여 Forward vector으로 하나의 축을 만들어야했다.

 

그래서 위의 함수를 사용했다.

 

Forward와 Up은 위의 설명대로 넣었고 Right 같은경우에는 외적을 이용하면 바로 나온다.

 

더 응용하는 법은 밑 처럼 FVector UKismetMathLibrary::Get ??? Vector( FRotator) 을 이용하면 된다.

 

밑은 위의 함수로 만든 하나의 축을 arrow로 디버깅했다.

Yellow(forward ) / red(right) / up(blue)

 

+ Recent posts