프로그래밍 공부
작성일
2023. 10. 5. 16:58
작성자
WDmil
728x90

렌더타겟뷰, 백버퍼 생성해서 화면띄우기,

버텍스 픽셀 쉐이더 생성후. 화면에 정점버퍼 띄우기

 

DXD3D 기본 화면 초기화

Dx3D에서 기본적인 화면을 띄우기 위해서 먼저 윈도우 기본 핸들을 스왑체인에 연결해주어야 하는데,

 

윈도우 핸들을 그때그때마다 새로 지정해줄 수 없고,

 

어차피 핸들은 한개만 사용하기 때문에 윈도우 기본핸들을 전역변수로 빼주어도 무방하다.


그 후에, InitDevice에서 WindowsHandle을 스왑체인에 연결시켜준다.

직관적인 이름의 DirectX Graphics Infrastructure Swap Chain Description인,
DXGI_SWAP_CHAIN_DESC 형의 swapChainDesc를 생성하고, 내부의 항목에 하나하나 값을 채워준다,

BufferDesc.Width 스왑체인의 버퍼 너비
BufferDesc.Height 스왑체인의 버퍼 높이
BufferDesc.RefreshRate.Numerator 화면의 리프레시 속도의 분자값. 통칭 프레임 이라고함.
BufferDesc.RefreshRate.Denominator 화면의 리프레시 속도의 분모값. 통칭 프레임 이라고 함.
BufferDesc.Format 픽셀형식. 위 항목에서는 각 RGBA가 8바이트. 32비트 형식임을 명시한다.
SampleDesc.Count 멀티셈플링(표본화)에 사용되는 샘플 숫자를 이야기한다. 여기서는 한개이다.
BufferUsage 버퍼가 어떻게 사용될지를 설명한다. 여기서는 렌더타겟으로 사용된다.
BufferCount 스왑체인에 사용될 버퍼수 를 이야기한다. 보통 표시화면, 백버퍼 로 1개의 버퍼이다.
OutputWindow 출력윈도우 의 핸들을 설정한다. 핸들을 지정해주면된다.
Windowed 스왑체인이 윈도우모드면 true 전체화면이면 false를 넣는다. 여기는 윈도우 모드이다.

위에서 기입해준 디바이스 값들을 SwapChain생성부에 넣으면서 다른 기입값들을 전부 넣어준다.


전체적인 백버퍼 정보를 Texture2D로 생성한 backBuffer에 지정하여 기입해준다.

여기서, IID interfaceID를 받아오는 이유는, 현재 기입된 backBuffer가, VoidPointer로 받아오기 때문에, 어떠한 형태인지 알 수 없어서. uuidof로 현재 포인터가 어떤 형식인지를 같이 리턴시켜준다.

 

위 swapChain의 버퍼구성에 Texutr2D인것을 기입해주고

renderTargetView로 device에 Buffer을 넘겨주었다면, backBuffer는 더이상 의미가 없기때문에 Release()해주고,

그 이후, 그래픽카드에 OM의 RenderTarget를 renderTargetView로 지정하여 화면에 띄워준다.


그 후, 렌더에서 deviceContext의 Color를 지정한 Color로 초기화 시켜준다.


D3DX 버텍스, 픽셀 생성.  화면에 렌더링

먼저, 버텍스와 픽셀을 생성하기 전에 그래픽 파이프라인을 먼저 확인해야한다.

그래픽 파이프 라인은 전에 작성했다 싶이 순서대로 진행되는 구조로 이루어져 있는데 이 순서는 다음과 같다.

IA(Input Assembler) 입력 조립기. 데이터(정점)을 받아들이는 과정이다.
예를들어, 사각형을 그리려면 네 개의 점이 필요하다.
이 점들은 각 위치 색상 노멀 등의 정보를 가지게 된다.
VS(Vertex Shader) 정점 셰이더는 IA에서 받은 정보들에 효과를 기입하게 된다.
예를들어 점의 위치를 이동하거나 점을 변형시키는 작업을 수행한다.
여기서  WVP변환이 이루어진다.

1. World Transform : 3D 모델의 정점데이터를 월드 좌표계로 변환한다.
2. View Transform : 월드 좌표계의 정점을 카메라 뷰 좌표계로 변환한다.
3. Projection Transform : 뷰 좌표계의 정점을 클립 공간으로 변환하고, 이를통해 최종적으로 NDC(Normalized Device Coordinates) 좌표계로 반환한다.

중간에 무언가 많은 셰이더 무언가 많은 재처리과정을 통한 화면처
RS(Rasterizer) 래스터라이저 는 픽셀화 하는 과정이다.
안보이는 과정을 잘라내고, 보이는부분만을 처리하게 된다.
(뒤에 가려진 픽셀 또는 일정범위내의 정점에 포함되지 않는 픽셀 등)
주로 뷰포트로 변환하는 과정을 이야기한다.
PS(Pixel Shader) 픽셀 셰이더는 정점 연산을 거쳐 생성된 폴리곤의 픽셀에 대해서 연산한다.
정점 셰이더에서 넘어온 정보와 래스터라이즈와 보간기를 통해 넘어곤 픽셀 정보를 기반으로 색 재처리를 한다.
OM(Output Merger) 출력병합 단계에서는 픽셀 셰이더 이후 넘어온 값들을 넣어도 좋은것인지 검증한 후,
화면에 띄우는 방법을 정하고 띄우는것이다.

위 그래픽 파이프라인대로 코드를 설정해주면 우리는 간단하게 정점데이터를 화면에 띄워줄 수 있다.

 

모든 정점데이터는 위와같은 그래픽 파이프라인을 거쳐서 출력되게 된다.

 

1. 뷰포트 설정

어느걸 먼저 설정해도 순서상 큰 상관은 없다.

먼저 화면을 띄울 뷰포트를 설정해준다.

VIEWPORT에 대한 인터페이스를 설정해준다.

뷰포트에서 가장 상위 왼쪽 상단 모서리의 X와 Y위치를 TopLeftX, TopLeftY 에서 지정해준다.

Width, Height에서 뷰포트의 너비와 높이를 지정해준다.

MinDepth와 MaxDepth로 뷰포트의 최소깊이와 최대깊이를 설정한다. 해당 값은 2D에서는 있으나 사용하지 않는다.

그 후 설정한 뷰포트를 deviceContext{GPU}에 넘겨주어 처리하게 한다.

 


2. Flags 세우기

쉐이더를 로드하기 위해 허가권한과 방식을 지정해준다.

 

위 허가권한은 HLSL에 대한 컴파일 방법을 지정해주는 역할을 한다.

다른 HLSL의 컴파일방법에 대한 지정 Flags는 마이크로소프트에서 설명한다.


3. Shader 생성하기

아주 간단한 형태의 HLSL을 생성하여 관리하면 된다.

이때, 기본 생성자는 float4의 VS가 아니라 main으로 되어있기 때문에, 전역관리자에서 main이 아니라 VS로 진입을 수정해야한다.

진입점 이름이 VS로 수정되어있는것 을 확인할 수 있다.

위 코드에서 VS는 float4의 pos를 받아와서 바로 PS로 리턴하는것 이 아닌, 데이터를 시스템에 전달 한 뒤,

해당 pos값을 다시 시스템에서 데이터로 전달받아 PS에서 아용한다 라는 의미이다.


4. Blob 생성하기

컴파일 된 HLSL에 데이터를 전달하기 위해 Blob을 생성하여 데이터를 넘겨주어야 한다.

Blob은 버텍스 버퍼나 인덱스 버퍼를 생성, 셰이더를 컴파일 할 때 바이트 코드를 HLSL 에 전달하는 Buffer 역할을 한다고 볼 수 있다.

blob을 생성하여, blob에 들어가야할 데이터 정점정보와 hlsl이 무엇인지 등의 데이터를 기입한다.

blob에 대한 BufferPointer와 blob의 Buffersize를 사용하여, vertexShader를 생성해준다.

그리하여, cpu에 현재 사용되는 VertexShader를 알려주고 위치를 기억시킬 수 있다.


5. ELEMENT_DESC를 기입한다.

현재 들어가게되는 정점데이터의 형태 데이터를 Buffer에 묶어서 전달하기 위해 배열로 값을 저장한다.

layoutSize에 현재 기입한 Desc의 배열사이즈를 넣어준뒤,

CPU의 IA에 Desc의 정보데이터를 넣어준다.

즉, 여기까지 왔으면, CPU는 현 정점데이터가 어느부분의 HLSL에 기입될지, 어떤 형태로 들어갈지, 어떤 유형으로 기입될것 인지를 알고있다.


6. vertexBuffer생성

버텍스의 위치좌표를 Buffer로 만들어서 기입해준다. Buffer에서 데이터를 기입해주고 bufferDesc의 인터페이스에 필요정보를 각각 기입한다.

Usage 허가권한을 이야기한다.
해당되는 데이터버퍼가 CPU나 GPU가 접근할 수 있는지
없는지 등을 알려준다.
DEFAULT는 모두 가능하다. 라는 뜻
ByteWidth 현 길이에 대한 사이즈를 넣어준다.
BindFlags 현재 이 버퍼가 어떤 버퍼인지 알려주는 flags를 이야기한다.

 


7. 출력명령 실행

이제 해당된 모든 데이터를 출력한다고 명령을 주면 된다.

 

출력결과

728x90