이전 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 |