XAML과 DirectX 결합

Windows 8 앱 개발자 블로그

Windows 8 엔지니어링 팀에서 제공하는 Windows 8용 Metro 스타일 앱 개발의 이해

XAML과 DirectX 결합

  • Comments 0

우리는 Windows 8 개발 초기부터 다양한 컨트롤과 같은 UI, XAML에서 제공하는 대화형 작업, DirectX의 고성능 하위 수준 렌더링과 같은 그래픽을 결합하는 방법을 생각해 왔습니다.

여러분이 개발자 센터 포럼과 다른 채널을 통해 Developer Preview에 대해 보내주신 의견 덕분에 우리는 개발자가 정말로 만들고 싶어 한 시나리오에 초점을 맞출 수 있었습니다. 그리고 몇 가지 공통점을 발견할 수 있었습니다. XAML 앱에 DirectX 그래픽을 추가하거나 DirectX 앱에 Metro 스타일 UI를 쉽게 추가할 수 있으면 좋겠다는 의견이 많았습니다.

반가운 소식은 Consumer Preview의 릴리스와 함께 이제 더 이상 XAML 앱과 DirectX 앱을 구분할 필요가 없어졌다는 것입니다. 이제 여러분은 익숙한 XAML 모델을 사용하여 단일 앱 내에서 XAML과 DirectX의 장점을 모두 활용할 수 있게 되었습니다. 즉, XAML로 풍부한 UI 플랫폼 경험을 제공하고 DirectX로 고성능 렌더링 솔루션을 구현할 수 있습니다.

이 두 가지 기술을 결합할 수 있으므로 이 둘의 장점을 최대한 활용할 수 있습니다. 이는 다양한 가능성을 의미합니다. 여러분이 보내주셨던 주요 시나리오 몇 가지는 다음과 같습니다.

  • UI와 그래픽이 결합된 이미지 처리, 독창성, 앱 디자인
  • 수많은 DirectX 그래픽과 일부 UI가 결합된 대규모 지도와 문서 뷰어
  • 전체 화면, 고성능 DirectX 그래픽과 최소한으로 오버레이된 UI를 지원하는 게임과 시뮬레이션

XAML과 DirectX를 결합하면 개발자의 생산성이 높아지고, 더 풍부하고 빠른 경험을 제공하는 앱을 개발할 수 있게 됩니다.

Windows 8의 Metro 스타일 UI

XAML은 HTML/JavaScript와 마찬가지로 Windows 8에서 지원되는 모든 유형의 앱을 위한 UI 도구 키트로서 대화형 작업, Metro 스타일 컨트롤 및 애니메이션, 그리고 접근성 지원, 데이터 바인딩, 미디어, HTML 호스팅과 같은 풍부한 기능 구성을 제공합니다. 또한 Visual Studio와 Expression Blend에서 원하는 프로그래밍 언어를 사용하여 디자인 타임 지원 기능을 이용할 수 있습니다.

XAML과 HTML/JavaScript의 이러한 모든 영역 중에서 우리가 역량을 계속 집중하고 있는 부분 중 하나는 성능입니다. 우리는 개발자가 빠르고 유연한 Metro 스타일 앱을 간단하게 만들 수 있도록 Windows 8에서 성능에 심혈을 기울였습니다. 특히 그래픽 영역에서 렌더링 및 결합 성능을 지속적으로 개선했고, 가능하면 GPU 하드웨어를 사용하기 위해 노력했으며, CPU에서 앱이 어떤 작업을 실행하든 관계없이 일반적 형태의 애니메이션이 부드럽게 표시되도록 UI 스레드와 독립적으로 실행될 수 있게 만들었습니다. 또한 UI 프레임워크가 모든 작업을 빠르고 유연하게 실행하고 전원을 적게 소비하도록 최선을 다했습니다. UI 프레임워크를 사용 중이라면 강력한 DirectX를 이미 사용하고 있는 것입니다. 대부분의 경우 UI 프레임워크만으로도 뛰어난 그래픽 성능을 충분히 구현할 수 있습니다.

Windows 8의 DirectX

그러나 원시 직접 실행 모드 렌더링을 수행하고 DirectX에서 제공하는 그래픽 장치에 직접 액세스해야 하는 경우가 있습니다. Windows 8부터는 주요 Windows SDK에 DirectX SDK 구성 요소가 제공되며, 통합 3D API, 향상된 2D 그래픽 및 Direct2D를 사용한 텍스트 효과, 풍부한 이미지 처리 파이프라인, 향상된 인쇄 지원 등이 DirectX에 포함됩니다.

Windows 8은 개발자 플랫폼부터 OS, 하드웨어 디자인까지 모두 DirectX에 최적화되어 있고 DirectX 위주로 만들어졌습니다. 따라서 개발자는 Windows 8에서 DirectX를 사용하여 최상의 렌더링 성능을 구현할 수 있습니다. 하지만 DirectX 솔루션 자체가 너무 복잡해서 만들거나 유지 관리하기가 상당히 까다로울 수 있고, 타사 래퍼를 사용하지 않는 경우 C++로 구현해야 한다는 단점이 있습니다.

이러한 문제는 DirectX와 XAML의 상호 작용으로 해결할 수 있습니다. C#, Visual Basic 또는 C++를 사용하여 XAML UI를 작성하고 C++ DirectX 구성 요소를 삽입하면 됩니다. HTML/JavaScript와 DirectX의 상호 작용에 대해서도 궁금하실 것입니다. 앞서 말한 것처럼 우리는 UI 플랫폼에 강력한 DirectX를 탑재하기 위해 심혈을 기울였으며 UI와 기본 DirectX 그래픽을 결합하기 위해 Windows 8용 XAML에 초점을 맞추었습니다.

설계 목표

우리는 위와 같은 내용을 염두에 두고 DirectX와 XAML의 결합을 구현할 때 충족하고자 하는 몇 가지 주요 목표를 수립했습니다.

1. 성능

  • 대기 시간이 짧은 입력 및 대화형 작업 지원
  • XAML과 DirectX 콘텐츠의 증분식 다시 그리기 허용
  • XAML 사용으로 인한 오버헤드 최소화

우리는 주로 “XAML 부담”을 피하는 데 중점을 두었습니다. 앱이 대부분 DirectX로 구성된 경우 Metro 스타일 UI가 필요하다면 XAML이 가장 손쉬운 방법입니다. XAML을 사용하는 것은 개발자에게만 중요한 것이 아닙니다. 앱을 사용하는 고객에게 뛰어난 성능과 긴 배터리 수명을 지원하기 위해서이기도 합니다.

2. 유연성

  • XAML과 DirectX 11의 모든 기능 구현

그 결과, Blend와 Visual Studio에서 XAML 인터페이스를 설계하고 개발하여 원하는 DirectX 콘텐츠와 결합할 수 있게 되었습니다. 우리는 개발자가 XAML과 DirectX를 결합할 수 있도록 XAML 또는 DirectX의 기능을 제한하지 않기 위해 노력했습니다.

3. 통합

  • XAML과 DirectX의 원활한 통합 보장

익숙한 XAML 개념을 사용하여 DirectX 그래픽과 XAML UI를 동일한 앱에 결합할 수 있습니다.

우리는 앞 부분에서 설명한 시나리오를 분석한 후 크게 3개 범주로 분류된다는 사실을 발견했습니다.

  1. DirectX의 작은 아일랜드를 주요 XAML UI에 결합
  2. 확장 가능한 대규모 DirectX 서피스를 XAML UI와 결합
  3. 주요 DirectX 앱상에 Metro 스타일 XAML UI 오버레이

마지막으로, 우리는 위의 3개 범주에 공통적으로 적용할 수 있는 접근 방식을 발견하지 못했습니다. 따라서 이러한 주요 시나리오 유형에 각각 적용되는 3개의 XAML 유형을 추가했습니다. 우리는 이 방식으로 개발자가 앱의 요구 사항에 가장 적합한 옵션을 매우 유연하게 선택할 수 있을 것이라 생각합니다. 이러한 옵션은 배타적이지 않으므로 동일한 앱의 여러 구성 요소에 3가지 방식을 모두 사용할 수도 있습니다.

시나리오 #1 – SurfaceImageSource: XAML UI에 DirectX 아일랜드 결합

DirectX과 XAML을 결합하는 첫 번째 옵션으로, 새로운 SurfaceImageSource XAML 유형을 사용하여 Metro 스타일 XAML 앱에 DirectX 콘텐츠 영역을 추가하는 방법이 있습니다. DirectX의 모든 기능을 사용할 수 있도록 이러한 XAML 유형이 제공하는 공유 DirectX 서피스에 콘텐츠를 그린 후 이러한 서피스를 XAML 앱 인터페이스의 나머지 부분에 구성합니다.

이 옵션은 특히 DirectX를 사용하여 더 큰 XAML UI에 속하는 특정 구성 요소를 그리려는 경우에 유용합니다. 예를 들어 사진에 복잡한 이미지 효과를 적용하거나 고성능 3D 데이터 시각화를 만들 때 SurfaceImageSource를 사용할 수 있습니다.

XAML ImageSource를 사용한 적이 있다면 금세 익숙해질 것입니다. SurfaceImageSourceImageBrush의 원본으로 설정한 다음 ImageBrush를 사용하여 원하는 XAML 요소를 채울 수 있습니다(브러시 재사용 가능). 예를 들어 SurfaceImageSource를 사용하여 XAML 직사각형을 채울 수 있습니다.

SurfaceImageSource^ surfaceImageSource =  
ref new SurfaceImageSource(rectangle1->Width, rectangle1->Height, true);
ImageBrush^ brush = ref new ImageBrush();
brush->ImageSource = surfaceImageSource;
rectangle1->Fill = brush;

그런 다음 DirectX를 사용하여 직사각형의 콘텐츠를 그리고 필요할 때마다 업데이트할 수 있습니다. 가장 좋은 점은 이 서피스가 XAML 결합 모델과 원활하게 통합된다는 점입니다. 직사각형에 적용된 속성은 DirectX를 사용하여 그린 콘텐츠에도 적용됩니다. 렌더링 기술을 결합할 때 자주 발생하는 공역 문제 없이 간편하게 요소를 중첩하고, 렌더링 변환, 투영, z-인덱스 또는 불투명도를 모두 XAML에 적용할 수 있습니다.

DirectX 서피스와 XAML 콘텐츠가 결합된 XAML 앱을 보여주는 다이어그램. DirectX 서피스가 회전되어 있고 서피스 위에 다른 XAML 콘텐츠가 오버레이되어 있습니다.

XAML 콘텐츠와 함께 구성된 직사각형 DirectX 서피스

WPF의 D3DImage 유형과 비슷한 개념이라고 생각하시면 됩니다. 그러나 우리는 D3DImage에 대한 여러분의 의견을 듣고 SurfaceImageSource를 보다 강력하고 편리하게 만들기 위해 노력했습니다. 구체적으로 설명하면, SurfaceImageSource는 Direct2D를 포함한 DirectX 11을 지원하므로 D3DImage의 많은 제한 사항이 사라졌습니다. 예를 들어, 원격 데스크톱 연결을 통해 SurfaceImageSource를 사용할 수 있게 되었습니다. 또한 성능이 개선되었고, 서피스를 자동으로 관리하므로 더 이상 잠금/잠금 해제가 필요 없고 버퍼를 수동으로 만들고 관리하지 않아도 됩니다. SurfaceImageSource는 Direct3D 장치의 최대 텍스처 크기보다 큰 서피스도 지원할 수 있습니다.

SurfaceImageSource를 만들 때 처음으로 알 수 있는 것은 언뜻 보기에 새 메서드를 노출하지 않는 것처럼 보인다는 것입니다. 실제로 구현은 배경 기본 인터페이스를 통해 노출됩니다. C++로만 제공되는 DirectX API를 직접 참조해야 하기 때문입니다. 따라서 DirectX API를 C++ XAML 앱에서 직접 호출하거나 별도의 C++ WinRT 구성 요소에서 호출할 때는 C++를 사용해야 하며 그 후에 C# 또는 Visual Basic 앱에 삽입할 수 있습니다. 필요한 헤더 파일을 삽입한 후

#include "windows.ui.xaml.media.dxinterop.h"

시작하는 데 필요한 3개 메서드에 대한 액세스 권한을 부여하는 ISurfaceImageSourceNative 인터페이스를 쿼리할 수 있습니다.

interface ISurfaceImageSourceNative: IUnknown
{
SetDevice(IDXGIDevice *pDevice);
BeginDraw(
RECT updateRect,
IDXGISurface** pSurface,
POINT* offset
);

EndDraw();
};

BeginDraw()는 업데이트할 영역을 제한하는 데 사용되는 updateRect 매개 변수를 사용합니다. 따라서 서피스에 작은 증분 업데이트만 적용할 수 있으므로 성능이 개선됩니다. 이 메서드는 또한 서피스를 반환하고, 그리기를 시작해야 하는 오프셋 지점을 반환합니다. 전체 서피스를 업데이트하는 경우에도 이 오프셋을 확인해야 합니다. 프레임워크가 최적의 성능을 위해 내부적으로 유지 관리하는 더 큰 서피스에 포함된 서피스일 수 있기 때문입니다. 여기에서 DXGI 장치를 만들고 설정한 다음 DirectX를 사용하여 그리기를 시작할 수 있습니다. 자세한 내용은 개발자 센터의 DirectX와 XAML 상호 작용 항목에 알기 쉽게 간략히 설명되어 있습니다.

시나리오 #2 – VirtualSurfaceImageSource: 대규모 DirectX 콘텐츠 + XAML UI

VirtualSurfaceImageSource는 큰 서피스를 더욱 효율적으로 지원하도록 SurfaceImageSource를 확장합니다. 화면에 표시될 때만 서피스 영역을 그리는 '가상화' 개념에 기초하고 있습니다.

이 유형은 화면보다 크고, 특히 이동하거나 확대/축소할 수 있는 복잡한 콘텐츠를 표시할 때 사용하기 위해 만들어졌습니다. 이 유형은 일반 모니터의 최대 해상도보다 몇 배 더 클 수도 있는 콘텐츠가 포함된 문서 뷰어부터 의료 영상 앱까지 다양한 시나리오에 적용됩니다. 지도 컨트롤도 좋은 예입니다. VirtualSurfaceImageSource를 사용하면 DirectX를 사용하여 대규모의 벡터 기반 지도를 구현하고 시스템에서 언제든지 화면상의 영역을 추적하도록 허용할 수 있습니다. 또한 지도 위에 압정과 같은 XAML 요소를 오버레이하고 압정의 위치를 DirectX 콘텐츠와 간편하게 동기화할 수 있습니다.

VirtualSurfaceImageSource는 바둑판식 배열과 콜백 모델을 사용하여 이러한 가상화를 구현합니다. 전체 크기의 VirtualSurfaceImageSource를 만들면 내부에서 DirectX 콘텐츠가 일련의 직사각형 영역으로 분할됩니다. 프레임워크는 특정 지점에 표시된 직사각형을 자동으로 추적하고 부드럽게 이동하기 위해 화면에 표시되지 않는 다른 직사각형을 추적할 수도 있습니다. 필요할 경우 새로 표시된 영역에 콘텐츠를 제공하기 위해 앱에서 구현하는 콜백을 호출합니다. 터치하거나 마우스를 사용하여 부드럽게 이동할 수 있도록 ScrollViewerVirtualSurfaceImageSource 콘텐츠를 삽입할 경우에 특히 유용합니다.

현재 화면에 영역이 프레임으로 표시되는 대규모 DirectX 서피스. 화면 바깥쪽의 빈 영역은 화면에 아직 표시되지 않아 아직 그려지지 않은 서피스 부분을 나타냅니다.

직사각형 타일로 분할된 대규모 서피스

이러한 접근 방식은 직접 좌표를 추적하는 것보다 구현하기 어렵습니다. 하지만 앱의 성능을 한층 끌어올릴 수 있습니다. 시스템에서 콘텐츠를 내부 캐시에 저장하므로 특정 영역의 콘텐츠를 그리면 콘텐츠가 메모리에 보관되고, 화면에 표시되지 않았다가 다시 표시되더라도 GPU에서 자동으로 콘텐츠를 재사용하므로 다시 그릴 필요가 없습니다. 이미 그린 영역을 업데이트하려면 SurfaceImageSource와 마찬가지로 BeginDraw()를 호출하기만 하면 됩니다. 시스템에서는 성능을 더욱 최적화하기 위해 특정 시점 이후로 화면에 표시되지 않은 기존 영역에 사용된 메모리를 자동으로 재활용하여 메모리 사용을 제한하고, 매우 큰 서피스가 포함된 광범위한 폼 팩터와 하드웨어 프로필에서 앱이 잘 작동하도록 합니다. 이러한 성능 이점은 특히 태블릿과 같은 휴대용 장치에서 확연하게 드러납니다.

SurfaceImageSource를 사용할 때와 마찬가지로 배경 기본 인터페이스(이 경우 IVirtualSurfaceImageSourceNative)를 쿼리하여 필요한 메서드에 액세스할 수 있습니다. 자세한 내용은 개발자 센터의 DirectX 및 XAML 상호 작용 문서 또는 Direct2D 잡지 앱 샘플을 참조하십시오.

시나리오 #3 0 SwapChainBackgroundPanel: DirectX에 XAML 오버레이

XAML과 DirectX 콘텐츠를 결합하는 세 번째이자 마지막 옵션은 SwapChainBackgroundPanel입니다. 주로 DirectX에 초점을 맞춘 전체 화면 앱을 개발하기 위한 XAML 요소입니다. SurfaceImageSourceVirtualSurfaceImageSource와 달리 SwapChainBackgroundPanelImageSource가 아니라 XAML 요소로서 XAML 격자 레이아웃 패널에서 상속되며, 다른 모든 XAML 콘텐츠가 오버레이된 전체 화면 DirectX 스왑 체인을 만들고 완벽하게 제어하는 데 사용됩니다.

DirectX 콘텐츠가 항상 XAML 오버레이 뒤에 있는 SwapChainBackgroundPanel의 결합 모델 그림

SwapChainBackgroundPanel은 오버레이된 XAML 콘텐츠 뒤에 있습니다.

이 옵션은 대부분의 그래픽이 DirectX로 구현되는 게임과 같은 앱에 가장 적합합니다. 이 옵션을 사용하면 뛰어난 성능을 얻을 수 있고, DirectX 앱 자체와 가까운 업데이트 모델을 구현할 수 있습니다. XAML을 함께 사용하면 간편하게 알림 표시 인터페이스를 만들어 게임 모델에 데이터 바인딩하고, 대화형 컨트롤을 추가하고, AppBar(앱 바)와 같은 Metro 스타일 요소를 삽입할 수 있습니다.

이를 구현하려면 SwapChainBackgroundPanel에 몇 가지 제한 사항이 적용됩니다. SwapChainBackgroundPanel이 앱의 루트 XAML 요소여야 하고, OpacityRenderTransform과 같이 상속된 몇 가지 XAML 속성이 SwapChainBackgroundPanel에 적용되지 않아야 합니다. 그러나 물론 스왑 체인 콘텐츠에 동등한 DirectX 작업을 적용하여 이러한 효과를 구현할 수는 있습니다. 이렇게 하면 SurfaceImageSource를 사용하여 구현한 XAML 프레임워크 결합 모델과의 긴밀한 통합과 스왑 체인을 직접 관리할 때 대기 시간이 가장 짧은 상호 작용 작업과 표시 타이밍에 대한 추가 제어 간에 균형을 이룰 수 있습니다.

이 경우 배경 기본 인터페이스에는 단일 메서드만 있습니다.

interface ISwapChainBackgroundPanelNative: IUnknown
{
SetSwapChain(IDXGISwapChain *pSwapChain);
};

SetSwapChain()을 호출하여 패널과 스왑 체인을 연결하면 콘텐츠가 즉시 표시됩니다. 이때 SwapChainBackgroundPanel은 누를 수 있는 상태가 되며, 여러분은 일반 XAML 입력 이벤트를 사용하여 입력을 처리할 수 있습니다. 패널에 추가한 자식 XAML 요소는 스왑 체인의 위에 표시됩니다.

SwapChainBackgroundPanel 사용 방법에 대한 자세한 내용은 개발자 센터의 상호 작용 항목에서 확인할 수 있습니다. SwapChainBackgroundPanel을 사용하여 작성된 샘플 DirectX 슈팅 게임의 소스를 보면 XAML 인터페이스를 지원하는 Direct3D 게임의 전반적인 구현 방법을 확인할 수 있습니다.

DirectX 및 XAML 1인칭 슈팅 게임의 스크린샷. DirectX 서피스에는 메뉴와 AppBar 컨트롤을 포함하는 XAML UI가 오버레이된 벽과 과녁이 있습니다.

DirectX와 XAML을 사용하여 작성된 게임

결론

XAML의 풍부한 UI 지원 및 디자인 타임 생산성과 DirectX의 고성능 그래픽을 결합할 경우 눈앞에 펼쳐질 새로운 가능성을 생각하니 마음이 설렙니다. 여러분이 고객을 위한 멋진 앱을 만들 때 이러한 새 옵션을 사용하여 Metro 스타일 앱을 편리하게 작성해 보시기를 바랍니다.

- Windows 프로그램 관리자
Jesse Bishop

  • Loading...
Leave a Comment
  • Please add 2 and 7 and type the answer here:
  • Post