관리 메뉴

有希

21.11.10 공부 본문

프로그래밍/DirectX 11

21.11.10 공부

有希. 2021. 11. 10. 20:24

화면에 노란색을 띄우는 것은 성공했다.

Direct X의 튜토리얼을 보고 따라하는게 아니고 아래 사이트를 따라하며 공부하고 있다.

https://copynull.tistory.com/240?category=649932 

 

[DirectX11] Tutorial 3 - DirectX 11 초기화

Tutorial 3 - DirectX 11 초기화 원문 : http://www.rastertek.com/dx11s2tut03.html 이 튜토리얼은 DirectX 11에 대한 첫 번째 소개가 될 것입니다. 여기에서는 Direct3D를 초기화하고 종료하는 방법과 창에 렌..

copynull.tistory.com

초기화 부분을 직접해주느냐의 차이인거 같은데, 여기서는 class 구조를 나눠서 좀 더 체계적으로 설명해주는것 같다.

GraphicsClass에서 Render함수로 화면을 그릴 색을 넣어주는데, openCV처럼 0~255 단위가 아니라 0~1로 normalize해줘서 넣어줘야 했다.

저 색은 rgba값으로 (247, 202, 24, 1) 인데 DirectX에서는 대충 변환해서 (0.968f, 0.79f, 0.09f, 1.0f)로 값을 넣어줬다.


txt파일에 그래픽 카드의 이름과 용량 적기

이미 예제 코드에 GetVideoCardInfo 라는 이름으로 넣어준 인자에 그래픽 카드의 정보를 담아주는 기능을 구현했다.

void D3DClass::GetVideoCardInfo(char* cardName, int& memory)
{
	strcpy_s(cardName, 128, m_videoCardDescription);
	memory = m_videoCardMemory;
}

이제 이를 호출해서 txt파일에 써 주기만 하면 된다.

GraphicsClass에서 초기화 할 때 D3DClass 객체를 생성해서 초기화해주고 있으므로 초기화 이후 함수를  호출해서 저장해준다.

bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
	// Direct3D 객체 생성
	m_Direct3D = (D3DClass*)_aligned_malloc(sizeof(D3DClass), 16);
	if (!m_Direct3D)
	{
		return false;
	}

	// Direct3D 객체 초기화
	if (!m_Direct3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLE, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR))
	{
		MessageBox(hwnd, L"Could not initialize Direct3D.", L"Error", MB_OK);
		return false;
	}
	char cardName[128];
	int memory;
	m_Direct3D->GetVideoCardInfo(cardName, memory);

	std::string filePath = "GraphicCards.txt";

	//write File
	std::ofstream writeFile(filePath.data());
	if (writeFile.is_open())
	{
		writeFile << cardName;
		writeFile << '\n';
		writeFile << std::to_string(memory);
		writeFile << '\n';
		writeFile << '\0';
		writeFile.close();
	}

	return true;
}

그럼 소스코드 폴더에 GraphicCrads.txt 파일이 생기고 다음과 같은 내용이 적힌다


용어정리

버텍스 버퍼

구를 그린다고 하면 삼각형 수백개로 구를 그린다.

출처: http://www.rastertek.com/dx11s2tut04.html

삼각형에는 3개의 점이 있으며 각 점을 꼭짓점(Vertex)라고 한다. 구형 모델을 렌더링하려면 구를 구성하는 모든 Vertex를 Vertex 버퍼라고 부르는 특수 데이터 배열에 넣어야 한다. 구 모델의 모든 Vertex가 Vertex Buffer에 있으면 Vertex Buffer를 GPU에 전송하여 모델을 렌더링 할 수 있다.

인덱스 버퍼

Vertex버퍼에 있는 각 Vertex의 위치를 기록하는 버퍼. GPU는 Index Buffer를 사용하여 Vertex Buffer의 Vertex를 빠르게 찾는다. Index Buffer를 사용하면 비디오 메모리의 더 빠른 위치에 Vertex Data를 Caching할 가능성을 높일 수 있다고 한다. -> Caching 가능성 높이면 좋은거니까 사용해라!

버텍스 쉐이더

Vertex Shader는 주로 Vertex Buffer의 Vertex들을 3D공간으로 변환시켜주는 프로그램이다. 이외에도 각 정점의 법선을 계산하는 연산도 가능하다. 정점 셰이더 프로그램은 GPU에서 계산이 필요하다고 판단될 때 호출된다.

예를 들어, 5000개의 폴리곤(우리는 주로 삼각형을 쓴다. CG아티스트는 사각형도 쓰고 원도 쓴다고 한다.)을 가진 모델을 화면에 표시한다면 매 프레임마다 15000번의 Vertex Shader 프로그램이 실행된다. -> 5000개의 삼각형 -> 15000개의 꼭짓점이므로 매 꼭짓점마다 VertexShader를 사용해 그려야 한다.

만약 60fps 프로그램이라면 15000 * 60 = 900,000번의 Vertex Shader 를 호출한다. Vertex Shader를 최대한 효율적으로 작성해야 한다.

픽셀 셰이더

그리고자 하는 도형에 색상을 입힐 때를 위한 작은 프로그램. 화면에 보이지 않는 모든 픽셀들에 대해서 GPU에서 연산한다. 색상을 입히고(Coloring), 텍스처를 입히고(texturing), 광원 효과를 주고(Lighting) 등 채색 효과를 주는 녀석이다. 픽셀 셰이더 또한 GPU에서 매우 많이 호출되기 때문에 최대한 효율적으로 작성해야 한다.

HLSL

HLSL은 DirectX 11에서 사용하는 Vertex Shader & Pixel Shader 프로그램을 작성할 때 사용하는 일종의 언어이다. 미리 정의된 타입이 있다는 것을 빼면 C언어와 거의 동일하다.(아마 하드웨어를 직접적으로 다루기 때문에 C언어 사용한듯)

HLSL 프로그램 파일은 전역 변수, 타입 정의, 정점 셰이더, 픽셀 셰이더, 그리고 기하 셰이더로 구성되어 있다.


 

'프로그래밍 > DirectX 11' 카테고리의 다른 글

21.11.17 공부  (0) 2021.11.17
21.11.11 공부  (0) 2021.11.11