Screen Capture

Date:     Updated:

카테고리:

태그:

홍정모님의 그래픽스 새싹코스 강의를 듣고 정리한 내용입니다.


🐥 Screen Capture

captured1

Render Target에 그린 렌더링 결과를 저장하고 싶다면 어떻게 해야할까? 우선 렌더링 결과가 GPU 메모리에 존재하기 때문에 이를 CPU로 옮겨주는 과정이 필요하다. 이 과정이 생각보다 복잡한데 그 이유는 다음과 같다. 첫째, RenderTarget으로 사용되는 Texture는 Multi-Sampling을 위한 특수한 자료구조 Texture2D-MS로 이루어져 있다. 따라서 이를 일반적인 Texture2D로 바꿔야 한다. 둘쨰, GPU에서 Texutre를 만들고 메모리를 할당받으려면 용도를 명확히 지정해야 한다. 따라서 ‘CPU로 보내기 위해 임시로 저장하는 (Staging) Texture입니다’하고 별도의 texture로 바꿔야 한다.


m_context->ResolveSubresource(m_tempTexture.Get(), 0,
                                backBuffer.Get(), 0,
                                DXGI_FORMAT_R8G8B8A8_UNORM);

  • ResolveSubresource : GPU -> GPU 메모리 복사
  • back buffer를 temp texture로 옮겨주기


ComPtr<ID3D11Texture2D> stagingTexture;

D3D11_TEXTURE2D_DESC desc;
// ...
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ // CPU에서 읽을 수 있어요
desc.Usage = D3D11_USAGE_STAGING; // 임시로 저장하는 용도에요

D3D11_MAPPED_SUBRESOURCE ms;

std::Vector<uint8_t> pixels(desc.Width * desc.Height * 4);

context->Map(stagingTexture.Get(), NULL, D3D11_MAP_READ, NULL, &ms); // Map

uint8_t *pData = (uint8_t *)ms.pData; // memcpy
for (unsigned int h=0; h<desc.Height; h++) {
    memcpy(&pixels[h * desc.Width * 4], &pData[h * ms.RowPitch], desc.Width * sizeof(uint8_t) * 4);
}

context->Unmap(stagingTexture.Get(), NULL); // Unmap


  • Staging Texture 생성하고 (desc 주의)
  • map -> memcopy -> Unmap
  • for문으로 가로 줄 하나씩 복사
  • R8G8B8A8 가정
  • 이제 CPU에서 pixels로 한 줄씩 써주면 캡쳐 완료!



맨 위로 이동하기

Graphics 카테고리 내 다른 글 보러가기

댓글 남기기