이 항목에서는 Direct2D 기하 도형 실현을 사용하여 특정 시나리오에서 앱의 기하 도형 렌더링 성능을 향상시키는 방법을 설명합니다.
여기에는 다음 섹션이 포함되어 있습니다.
기하 도형 실현이란?
Windows 8.1에서 도입된 기하 도형 실현은 Direct2D 앱을 쉽게 특정 경우에 기하 도형 렌더링 성능을 향상시킬 수 있도록 하는 새로운 유형의 그리기 기본 형식입니다. 기하 도형 실현은 ID2D1GeometryRealization 인터페이스로 표시됩니다.
기하 도형 실현을 사용하는 이유는 무엇인가요?
Direct2DID2D1Geometry 개체를 렌더링하는 경우 해당 기하 도형을 테셀레이션이라는 프로세스를 통해 그래픽 하드웨어가 이해하는 형태로 변환해야 합니다. 일반적으로 Direct2D는 기하 도형이 변경되지 않더라도 그려질 때마다 기하 도형을 전분화해야 합니다. 앱이 프레임마다 동일한 기하 도형을 렌더링하는 경우 반복되는 다시 분할은 낭비된 계산 노력을 나타냅니다. 기하 도형의 테셀레이션 또는 전체 래스터화를 캐시하고 반복적으로 다시 테셀레이션하는 대신 각 프레임에 캐시된 표현을 그리는 것이 더 계산적으로 효율적입니다.
개발자가 이 문제를 해결하는 일반적인 방법은 기하 도형의 전체 래스터화를 캐시하는 것입니다. 특히 새 비트맵을 만들고, 기하 도형을 해당 비트맵으로 래스터화한 다음, 필요에 따라 해당 비트맵을 장면에 그리는 것이 일반적입니다. (이 방법은 Direct2D 앱의 성능 향상에 대한 기하 도형 렌더링 섹션에서 설명합니다.) 이 방법은 계산 효율이 매우 높지만 몇 가지 단점이 있습니다.
- 캐시된 비트맵은 장면에 적용된 변환의 변경 내용에 민감합니다. 예를 들어 래스터화 크기를 조정하면 눈에 띄는 크기 조정 아티팩트가 발생할 수 있습니다. 고품질 크기 조정 알고리즘을 사용하여 이러한 아티팩트 완화는 계산 비용이 많이 들 수 있습니다.
- 캐시된 비트맵은 특히 고해상도로 래스터화된 경우 상당한 양의 메모리를 사용합니다.
기하 도형 실현은 위의 단점을 방지하는 기하 도형을 캐시하는 다른 방법을 제공합니다. 기하 도형 실현은 픽셀(전체 래스터화의 경우와 같이)이 아니라 수학적 평면의 포인트로 표시됩니다. 이러한 이유로 크기 조정 및 기타 조작에 대한 전체 래스터화보다 덜 민감하며 메모리를 훨씬 적게 사용합니다.
기하의 실현을 사용할 때
앱에서 모양이 자주 변경되지 않지만 변형 변경의 영향을 받을 수 있는 복잡한 기하 도형을 렌더링할 때 기하 도형 실현을 사용하는 것이 좋습니다.
예를 들어 정적 맵을 보여 주지만 사용자가 확대 및 축소할 수 있는 매핑 애플리케이션을 고려해 보세요. 이 앱은 기하 도형 실현을 사용하면 이점을 얻을 수 있습니다. 렌더링되는 기하 도형은 정적 상태로 유지되므로 테셀레이션 작업을 저장하기 위해 캐시하는 것이 유용합니다. 그러나 사용자가 확대/축소할 때 맵의 크기가 조정되므로 아티팩트 크기 조정으로 인해 전체 래스터화를 캐싱하는 것이 이상적이지 않습니다. 기하 도형 실현을 캐시하면 크기 조정 중에 높은 시각적 품질을 유지하면서 앱이 다시 분할 작업을 방지할 수 있습니다.
반면에, 애니메이션으로 지속적으로 변화하는 기하학적 형태를 보여주는 만화경 앱을 고려해 보세요. 이 앱은 기하학적 구현을 사용해도 특별히 이점이 없을 것입니다. 셰이프 자체는 프레임에서 프레임으로 변경되므로 테셀레이션을 캐시하는 것은 유용하지 않습니다. 이 앱의 가장 좋은 방법은 ID2D1Geometry 개체를 직접 그리는 것입니다.
기하학적 실현 만들기
ID2D1GeometryRealization 개체는 기존 ID2D1Geometry 개체에서 만들어야 합니다. 기하 도형 실현을 만들려면 CreateFilledGeometryRealization 메서드 또는 CreateStrokedGeometryRealization 메서드를 호출하여 실현할 ID2D1Geometry를 전달하십시오.
- CreateFilledGeometryRealization는 FillGeometry호출 시 그려질 도형의 내부를 실현합니다.
- CreateStrokedGeometryRealization은(는) 셰이프의 스트로크, 즉 DrawGeometry를 호출하여 그린 영역의 실체화를 만듭니다.
두 종류의 기하 도형 실현은 ID2D1GeometryRealization 인터페이스로 표시됩니다.
기하 도형 실현을 만들 때 Direct2D 제공된 기하 도형의 모든 곡선을 다각형 근사치로 평면화해야 합니다. 생성 방법에 평면화 허용 오차 매개 변수를 제공해야 합니다. 이 매개 변수는 기하 도형의 실제 곡선과 다각형 근사값 사이의 최대 거리(DIP)를 지정합니다. 제공하는 평면화 허용 오차가 낮을수록 결과 기하 도형 실현 개체의 충실도가 높습니다. 마찬가지로, 더 높은 평면화 허용 오차를 제공하면 더 낮은 충실도 기하 도형 실현이 생성됩니다. 충실도가 높은 기하 도형 실현은 낮은 충실도보다 그리는 데 비용이 더 많이 들지만, 표시되는 아티팩트가 도입되기 전에 더 확장할 수 있습니다. 평면화 허용 오차를 사용하는 방법에 대한 지침은 아래 기하 도형 크기 조정 실현을 참조하세요.
메모
기하 도형 실현 개체는 특정 그래픽 디바이스와 연결됩니다. 디바이스 종속 리소스입니다.
기하학적 도형 구현 그리기
기하 도형 실현은 비트맵과 같은 다른 Direct2D 기본 형식을 그리는 것과 유사합니다. 이렇게 하려면 DrawGeometryRealization 메서드를 호출하고 그릴 기하 도형 실현 개체와 사용할 브러시를 전달합니다. 다른 Direct2D 드로잉 메서드와 마찬가지로 BeginDraw 호출과 EndDraw호출 간에 DrawGeometryRealization 호출해야 합니다.
기하학적 구현 확대
다른 Direct2D 기본 형식과 마찬가지로 기하 도형 실현은 디바이스 컨텍스트에서 설정된 변환을 준수합니다. 변환 및 회전 변환은 기하 도형 실현의 시각적 품질에 영향을 주지 않지만 크기 조정 변환은 시각적 아티팩트가 생성됩니다.
특히 기하 도형 실현에 충분히 큰 배율을 적용하면 실제 곡선의 다각형 근사치를 확인할 수 있습니다. 여기에 있는 이미지는 너무 멀리 확장된 한 쌍의 타원형 기하 도형 실현(채우기 및 스트로크)을 보여줍니다. 곡선 평면화 아티팩트가 표시됩니다.
크게 확대한 타원형 기하 도형 실현(채우기 및 스트로크) 한 쌍의 
시각적 품질에 민감한 앱은 이러한 일이 발생하지 않도록 조치를 취해야 합니다. 크기 조정을 처리하는 방법은 앱의 요구 사항에 따라 달라집니다. 다음은 여러 가지 유형의 앱에 권장되는 몇 가지 접근 방식입니다.
크기 조절이 안 되는 앱에서 기하학적 표현 사용
앱이 기하 도형 실현에 대한 크기 조정을 수행하지 않는 경우 단일 평면화 허용 오차를 사용하여 한 번만 실현을 만드는 것이 안전합니다. (비 크기 조정 변환은 렌더링된 기하 도형 실현의 시각적 품질에 영향을 미치지 않습니다.) ComputeFlatteningTolerance 함수를 사용하여 DPI에 대한 적절한 평면화 허용 오차를 계산합니다.
float dpiX, dpiY;
deviceContext->GetDpi(&dpiX, &dpiY);
float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
D2D1::Matrix3x2F::Identity(), // apply no additional scaling transform
dpiX, // horizontal DPI
dpiY // vertical DPI
);
작은 범위로 조정하는 앱에서 기하학적 실현 사용
앱이 기하 도형 실현을 소량(예: 최대 2x 또는 3x)으로 확장할 수 있는 경우 기하 도형 실현을 기본값보다 비례적으로 낮은 평면화 허용 오차로 한 번 만드는 것이 적절할 수 있습니다. 이렇게 하면 크기 조정 아티팩트를 발생하기 전에 크게 확장할 수 있는 더 높은 충실도 실현이 생성됩니다. 절충은 더 높은 충실도 실현을 그리려면 더 많은 작업이 필요하다는 것입니다.
예를 들어 앱이 기하 도형 실현을 2배 이상 확장하지 않을 것임을 알고 있다고 가정합니다. 앱은 기본값의 절반인 평면화 허용 오차를 사용하여 기하 도형 실현을 만들고 필요에 따라 실현 크기를 최대 2배까지 조정할 수 있습니다. ComputeFlatteningTolerance 함수를 사용하여 2.0을 maxZoomFactor 매개 변수로 전달하여 적절한 평면화 허용 오차를 계산합니다.
float dpiX, dpiY;
deviceContext->GetDpi(&dpiX, &dpiY);
float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
D2D1::Matrix3x2F::Identity(), // apply no additional scaling transform
dpiX, // horizontal DPI
dpiY, // vertical DPI
2.0f // realization can be scaled by an additional 2x
);
크게 확장되는 앱에서 기하학적 구현 사용
앱이 기하 도형 실현을 대량으로 확장 또는 축소할 수 있는 경우(예: 10배 이상) 크기 조정을 적절하게 처리하는 것이 더 복잡합니다.
대부분의 이러한 앱에서 권장되는 방법은 시각적 충실도를 유지하고 아티팩트 크기를 조정하지 않기 위해 장면이 확장될 때 점점 더 낮은 평면화 허용 오차에서 기하 도형 실현을 다시 만드는 것입니다. 마찬가지로, 장면이 축소됨에 따라 앱은 보이지 않는 세부 정보를 낭비적으로 렌더링하지 않도록 점진적으로 더 높은 평면화 허용 오차에서 기하 도형 실현을 다시 만들어야 합니다. 이렇게 하면 테셀레이션 작업을 캐싱하는 목적이 무효화되므로 크기 조정이 변경 될 때마다 앱에서 기하 도형 실현을 다시 만들지 않아야 합니다. 대신, 앱은 기하 도형 실현을 덜 자주 다시 만들어야 합니다. 예를 들어 크기가 2배 증가하거나 감소할 때마다 다시 만들어야 합니다.
사용자 상호 작용에 대한 응답으로 앱에서 스케일이 변경될 때마다 앱은 기하 구현이 마지막으로 생성된 스케일과 새 스케일을 비교할 수 있습니다(예: m_lastScale 멤버에 저장됨). 두 값이 비슷하면(이 경우, 2배 이내) 추가 작업이 수행되지 않습니다. 두 값이 가깝지 않으면 기하학적 실현이 다시 만들어집니다. ComputeFlatteningTolerance 함수는 새 규모에 적합한 평면화 허용 오차를 계산하는 데 사용되며 m_lastScale 새 규모로 업데이트됩니다.
또한 앱은 ComputeFlatteningTolerance함수에 maxZoomFactor 매개 변수로 값 2를 전달하여 새 계산에서 일반적으로 사용되는 것보다 더 작은 허용 오차를 사용하여 항상 구현을 만듭니다. 이렇게 하면 확대 시 왜곡 현상 없이 새 기하학적 구현을 2배로 확대할 수 있습니다.
메모
여기에 설명된 접근 방식이 모든 앱에 적합하지 않을 수 있습니다. 예를 들어 앱에서 매우 큰 요소로 장면의 크기를 매우 빠르게 조정할 수 있도록 허용하는 경우(예를 들어 몇 프레임 범위에서 100%에서 1,000,000%로 이동할 수 있는 "확대/축소" 슬라이더가 포함된 경우) 이 방법은 모든 프레임에 대한 기하 도형 실현을 다시 만들어 과도한 작업이 발생할 수 있습니다. 다른 방법은 장면 크기의 조정이 완료된 후에만 기하학적 구성을 다시 생성하는 것입니다(예: 사용자가 손가락 모으기 제스처를 완료한 후).
관련 항목
Direct2D 앱 성능 향상
복잡한 정적 콘텐츠 렌더링하기 위한 일반 지침