DirectX/DirectX 2D

DX2D_05 정점 Update

컴맹학자 2022. 11. 19. 22:21
728x90

이전 04에선 rs를 cpu영역에서 변경 후 gpu에 값을 셋팅 했다면 이번엔 정점 정보를 수정 해서 다시 셋팅 하고자 함

방법은 2가지 형태가 있는데 gpu영역에 값을 넘겨 줘서 계산 하는 방식cpu 영역에서 값을 수정 해서 사용 하는 방식이 있다.

 

정점 정보가 IA ~ OM 과정에서 잠시 멈춰서 셋팅 하는 방법


1. 준비

Scene.cpp (수정)

※ 키보드로 이동 할 수 있도록 셋팅 (1e-4f ->  1 / -10의 4승)

더보기
void Update() 
{
	//if (GetAsyncKeyState('1') & 0x8001)
	if(Key->Toggle('1')) Wirte = !Wirte;

	if (Key->Press('A'))
	{
		for(int i =0 ; i <= 5 ; i++)
			vertices[i].Position.x -= 1e-4f; 
	}
	else if (Key->Press('D'))
	{
		for (int i = 0; i <= 5; i++)
			vertices[i].Position.x += 1e-4f; 
	}

	if (Key->Press('W'))
	{
		for (int i = 0; i <= 5; i++)
			vertices[i].Position.y += 1e-4f;
	}
	else if (Key->Press('S'))
	{
		for (int i = 0; i <= 5; i++)

			vertices[i].Position.y -= 1e-4f;
	}
}

 

2. GPU 영역에서 정점 정보 셋팅

1에서 update 코딩 치고 난 후 바로 실행 해보면 전혀 움직이지 않는데 당연 하게도 변경된 값을 넘겨주지 않았기 때문이다.

 

Scene.cpp -> InitScene() 

※ VertexBuffer를 만들때 사용 했던 사양서 중에 Usage 옵션을 기본적으로 DEFAULT로 해놓으면 GPU 영역에서 값을 변경 해서 사용 할 수 있도록 선언 해놓은거 

void InitScene()
{
	//Create VertexBuffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(Vertex) * 6;			
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;		
		
		//GUP
		desc.Usage = D3D11_USAGE_DEFAULT;				

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
		data.pSysMem = vertices; 

		HRESULT hr = Device->CreateBuffer(&desc, &data, &vertexBuffer);
		assert(SUCCEEDED(hr));
	}
}

Scene.cpp ->  void Update() 

※ DeviceContext안에 있는 UpdateSubresource() 함수를 통해서 값을 셋팅 한다.

void Update() 
{
	if(Key->Toggle('1')) Wirte = !Wirte;

	if (Key->Press('A'))	{...}
	else if (Key->Press('D'))	{...}
	if (Key->Press('W'))	{...}
	else if (Key->Press('S'))	{...}
	
	// 정점 정보를 다시 전달 (Subresource 고쳐 쓰는 경우) 
	// 직접 쉐이더에 값을 넣어줌(GPU방식)
	DeviceContext->UpdateSubresource(vertexBuffer, 0, nullptr, vertices, sizeof(Vertex) * 6, 0);

 

3. CPU 영역에서 정점 정보 셋팅

이번엔 cpu 영역내에서  셋팅 할 예정 

 

Scene.cpp -> InitScene() 

※Vertex Buffer 에서 Usage 사용 옵션 하고 추가로 CPU에 사용 할 수 있는 권한도 셋팅

	//Create VertexBuffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(Vertex) * 6;			
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;		
		
		//GUP
		//desc.Usage = D3D11_USAGE_DEFAULT;				
		
		//CPU
		desc.Usage = D3D11_USAGE_DYNAMIC;	
		desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
		data.pSysMem = vertices; 

		HRESULT hr = Device->CreateBuffer(&desc, &data, &vertexBuffer);
		assert(SUCCEEDED(hr));
	}

Scene.cpp ->  void Update() 

※ Map() ~ Unmap() 함수 내부에 있는 memcpy() 통해서 전달 하는 방식

void Update() 
{
	if(Key->Toggle('1')) Wirte = !Wirte;

	if (Key->Press('A')){...}
	else if (Key->Press('D')){...}

	if (Key->Press('W')){...}
	else if (Key->Press('S')){...}
	
	// 정점 정보를 다시 전달 (Subresource 고쳐 쓰는 경우) 
	// 직접 쉐이더에 값을 넣어줌(GPU방식)
	DeviceContext->UpdateSubresource(vertexBuffer, 0, nullptr, vertices, sizeof(Vertex) * 6, 0);
	
	// 잠시 Subresouce 값 멈추고 다시 셋팅 (CPU방식)
	D3D11_MAPPED_SUBRESOURCE subResouce;
	DeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResouce);
	{
		//메모리 카피(저장 받을 Subresource, 복사할 시작위치, 크기)
		memcpy(subResouce.pData, vertices, sizeof(Vertex) * 6);
	}
	DeviceContext->Unmap(vertexBuffer, 0);
}

 

실행

※ GPU / CPU 처리 방식에 별 차이점 안보이지만 계산을 계산을 많이 먹는 방식은 GPU 방식이기 때문에 map ~ unmap 방식으로 쓰는게 좋다

 

https://github.com/ascher8159/DX2D

DX2D_05

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

DX2D_07 Librarie 및 Utilitie  (0) 2022.11.24
DX2D_06 IndexBuffer  (2) 2022.11.22
DX_2 삼각형, DX_3 RS  (0) 2022.11.13
DX_1 배경 화면 & Line  (0) 2022.11.06
DX 렌더링 파이프라인 구조  (0) 2022.11.06