본문 바로가기

DirectX/Direct2D,DirectWrite

Direct2D and Direct3D Interoperability Overview

https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-and-direct3d-interoperation-overview?redirectedfrom=MSDN

 

Direct2D and Direct3D Interoperability Overview - Win32 apps

Direct2D and Direct3D Interoperability Overview

docs.microsoft.com

 

 

기존의 2D 렌더링을 효율적인 방식으로 Direct3D 렌더링과 혼합하여 많은 효용성을 가질 수 있다.

이 글에서는 Direct2D 및 Direct3D를 사용하여 2D 및 3D 그래픽을 통합하는 방법에 대해 설명한다.




Interoperability Through DXGI

 

Direct3D 10부터 Direct3D 런타임은 리소스 관리에 DXGI를 사용한다.

DXGI runtime layers는 비디오 메모리를 공유하는 상호 프로세스를 제공한다.

Direct2D는 DXGI를 사용하여 Direct3D와 상호 운용된다.

 

Direct2D와 Direct3D를 함께 사용하는 두 가지 기본 방법

 

  1. IDXGISurface를 얻어 CreateDxgiSurfaceRenderTarget 메서드로 ID2D1RenderTarget를 생성하여 Direct2D 컨텐츠를 Direct3D surface에 쓸(Write) 수 있다.
    그렇게 되면 렌더 타겟을 사용하여 2차원 인터페이스 또는 배경을 3차원 그래픽에 추가하거나 Direct2D drawing을 3차원 객체 텍스처로 사용할 수 있다.
  2. CreateSharedBitmap을 사용하여 IDXGISurface로부터 ID2D1Bitmap을 생성하고 Direct3D 장면을 비트맵으로 쓰고(Write) Direct2D로 그릴 수 있다.




Writing to a Direct3D Surface with a DXGI Surface Render Target

 

Direct3D surface에 쓰기 위해 IDXGISurface를 얻어DXGI surface render target을 생성하기 위해 CreateDxgiSurfaceRenderTarget 메서드에 보낸다. 그렇게 하면 DXGI surface에 2D 컨텐츠를 DXGI surface render target을 사용하여 그릴 수 있다.

 

DXGI surface render target일종의 ID2D1RenderTarget이다.

다른 Direct2D 렌더 타겟처럼 리소스 생성그리기 명령을 실행할 수 있다.

 

DXGI surface render target과 DXGI surface는 같은 DXGI format을 사용해야 한다. render target을 만들 때 DXGI_FORMAT_UNKOWN 형식을 지정하면 자동으로 surface의 format을 사용한다.

 

DXGI surface render target은 DXGI surface 동기화를 수행하지 않는다.




Creating a DXGI Surface

 

Direct3D 10을 사용하면 DXGI surface을 얻는 여러 가지 방법이 있다.

Device에 대한 IDXGISwapChain을 만든 다음 스왑 체인의 GetBuffer 메서드를 사용하여 DXGI surface을 얻을 수 있다.

또는 Device를 사용하여 텍스처를 만든 다음 해당 텍스처를 DXGI surface로 사용할 수 있다.

 

DXGI surface을 만드는 방법과 관계없이 surface는 DXGI surface render target에서 지원하는 DXGI format 중 하나를 사용해야 한다.

 

DXGI surface와 연관있는 ID3D10Device1는 Direct2D와 같이 작동하기 위해서는 BGRA DXGI format을 지원해야한다. 이러한 지원을 보장하기 위해   D3D10CreateDevice1 메서드를 호출할 때 D3D10_CREATE_DEVICE_BGRA_SUPPORT 플래그를 사용한다. 




Writing Direct2D Content to a Swap Chain Buffer

 

Direct2D 컨텐츠를 Direct3D 화면에 표출하는 가장 간단한 방법은 

IDXGISwapChainGetBuffer 메서드를 사용하여 DXGI surface 얻고

이 surface로 CreateDxgiSurfaceRenderTarget 메서드를 사용하여 2D 컨텐츠를 그릴 ID2D1RenderTarget을 생성하는 것이다. 

 

이러한 접근 방법은 3차원에 컨텐츠를 그리는게 아니기에 원근감이나 깊이가 없다. 하지만 아래와 같은 작업에서 유용하다.

 

  • 3D화면에서 2D 배경화면을 생성할 때
  • 3D화면에 2D 인터페이스를 생성할 때
  • Direct2D 컨텐츠를 그릴 때 Direct3D를 멀티샘플링할 때



Example: Draw a 2D Background

 

다음 과정들은 어떻게 DXGI surface render target을 생성하는가 그리고 그라디언트 배경을 이를 사용해서 어떻게 그리는지 설명한다.

 

  1. ID3D10Device1를 위한 스왑 체인을 생성하기 위해 CreateSwapChain 메서드를 사용한다.
    이 스왑체인은 Direct2D에 의해 지원되는 DXGI format중 하나인 DXGI_FORMAT_B8G8R8A8_UNORM DXGI format을 사용한다.


  2. DXGI surface를 얻기위해 스왑체인의 GetBuffer 메서드를 사용한다.


  3. DXGI render target을 생성하기 위해 DXGI surface를 사용한다.


  4. gradient 배경을 그리기 위해 렌더 타겟을 사용한다.

 

Using Direct2D Content as a Texture

 

Direct2D 컨텐츠를 Direct3D와 같이 사용하기 위한 또다른 방법은 Direct2D를 2D 텍스처를 생성하는데 사용하고 이 텍스처를 3D 모델에 적용하는 것이다.

ID3D10Texture2D 를 만들고 텍스처에서 DXGI surface를 얻은 다음 surface를 사용하여 DXGI surface render target을 생성하면된다.

ID3D10Texture2D surface는 D3D10_BIND_RENDER_TARGET 바인드 플래그를 사용하고 

DXGI surface render target에의해 지원되는 DXGI format을 사용해야만한다.



Example: Use Direct2D Content as a Texture

 

다음 예제는 2D 텍스처(ID3D10Texture2D)를 그리는 DXGI surface render target를 어떻게 생성하는지 보여준다.

 

  1. 2D 텍스처를 생성하기위해 Direct3D device를 사용한다.
    이 텍스처는 D3D10_BIND_RENDER_TARGET과 D3D10_BIND_SHADER_RESOURCE 바인드 플래그를 사용한다.

    그리고 이 텍스처는 Direct2D가 지원하는 format중 하나인 DXGI_FORMAT_B8G8R8A8_UNORM DXGI format를 사용한다.


  2. 텍스처를 사용하여 DXGI surface를 얻는다.


  3. CreateDxgiSurfaceRenderTarget 메서드surface를 이용하여 Direct2D 렌더 타깃을 얻는다.

 

Direct2D 렌더 타깃을 가져와 Direct3D 텍스처와 연결 했으므로 렌더 타깃을 사용하여 해당 텍스처에 Direct2D 콘텐츠를 그리고 해당 텍스처를 Direct3D 프리미티브에 적용 할 수 있게된다.




Resizing a DXGI Surface Render Target

 

DXGI surface render target은 ID2D1RenderTarget::Resize 메서드를 제공하지 않는다.

그래서 DXGI surface render target의 크기를 다시 설정하려면 응용프로그램은 DXGI surface render target 릴리즈 시키고 재생성해야 한다.

 

이러한 작업은 퍼포먼스 문제를 일으킬 가능성이 있다.

렌더 타깃은 렌더 타깃의 DXGI surface와 연결된 ID3D10Device1에 대한 참조를 유지하는 마지막 활성 Direct2D 리소스 일 수 있다.

응용프로그램이 렌더 타깃을 해제하고 ID3D10Device1 참조가 파괴되면 새로운 참조를 다시 만들어야한다.

 

당신은 렌더 타깃에 의해 생성되는 Direct2D 리소스를 적어도 한 개를 남겨놓아서 렌더 타깃을 다시 생성하는 리소스를 많이 잡아먹는 작업을 피할 수 있다. 

 

다음은 이 접근 방식에서 작동하는 몇 가지 Direct2D 리소스들이다.

  • ID2D1Bitmap
  • ID2D1Layer
  • ID2D1Mesh

 

이 접근 방식을 수용하려면 크기 조정 메서드를 테스트하여 Direct3D 장치를 사용할 수 있는지 확인해야한다. 

사용 가능한 경우 DXGI surface render target을 릴리스하고 다시 생성하되 이전에 생성 한 모든 리소스를 유지하고 재사용합니다. 

이는 두 렌더 타깃이 동일한 Direct3D 장치에 연결되어있을 때 두 렌더링 대상에서 만든 리소스가 호환 되기 때문에 작동합니다.