꼭짓점 및 인덱스 버퍼에서 렌더링(Direct3D 9)

인덱싱된 그리기 메서드와 인덱싱되지 않은 그리기 메서드는 모두 Direct3D에서 지원됩니다. 인덱싱된 메서드는 모든 꼭짓점 구성 요소에 대해 단일 인덱스 집합을 사용합니다. 꼭짓점 데이터는 꼭짓점 버퍼에 저장되고 인덱스 데이터는 인덱스 버퍼에 저장됩니다. 다음은 꼭짓점 및 인덱스 버퍼를 사용하여 기본 형식을 그리는 몇 가지 일반적인 시나리오입니다.

다음 예제에서는 IDirect3DDevice9::D rawPrimitiveIDirect3DDevice9::D rawIndexedPrimitive의 사용을 비교합니다.

시나리오 1: 인덱싱 없이 두 개의 삼각형 그리기

다음 그림에 표시된 쿼드를 그릴 것이라고 가정해 보겠습니다.

두 개의 삼각형으로 구성된 사각형 그림

삼각형 목록 기본 형식을 사용하여 두 삼각형을 렌더링하는 경우 각 삼각형은 3개의 개별 꼭짓점으로 저장되므로 다음 그림과 비슷한 꼭짓점 버퍼가 생성됩니다.

두 삼각형에 대한 세 개의 꼭짓점을 정의하는 꼭짓점 버퍼 다이어그램

그리기 호출은 매우 간단합니다. 꼭짓점 버퍼 내의 위치 0부터 시작하여 두 개의 삼각형을 그립니다. 컬링을 사용하도록 설정하면 꼭짓점의 순서가 중요합니다. 이 예제에서는 기본 시계 반대 방향 컬링 상태를 가정하므로 표시되는 삼각형을 시계 방향 순서로 그려야 합니다. 삼각형 목록 기본 형식은 단순히 각 삼각형에 대한 버퍼에서 선형 순서로 세 개의 꼭짓점을 읽으므로 이 호출은 삼각형(0, 1, 2) 및 (3, 4, 5)를 그립니다.

DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
               0,                  // StartVertex
               2 );                // PrimitiveCount

시나리오 2: 인덱싱을 사용하여 두 개의 삼각형 그리기

여기서 알 수 있듯이 꼭짓점 버퍼에는 위치 0 및 4, 2 및 5의 중복 데이터가 포함됩니다. 두 삼각형이 두 개의 공통 꼭짓점을 공유하기 때문에 의미가 있습니다. 이 중복 데이터는 낭비되며 인덱스 버퍼를 사용하여 꼭짓점 버퍼를 압축할 수 있습니다. 더 작은 꼭짓점 버퍼는 그래픽 어댑터로 보내야 하는 꼭짓점 데이터의 양을 줄입니다. 더욱 중요한 것은 인덱스 버퍼를 사용하면 어댑터가 꼭짓점 캐시에 꼭짓점을 저장할 수 있습니다. 그리는 기본 형식에 최근에 사용한 꼭짓점이 포함되어 있으면 꼭짓점 버퍼에서 읽는 대신 캐시에서 해당 꼭짓점을 가져올 수 있으므로 성능이 크게 향상됩니다.

각 고유 꼭짓점을 꼭짓점 버퍼에 한 번만 저장해야 하므로 인덱스 버퍼가 꼭짓점 버퍼로 '인덱스'됩니다. 다음 다이어그램은 이전 그리기 시나리오에 대한 인덱싱된 접근 방식을 보여 줍니다.

이전 꼭짓점 버퍼에 대한 인덱스 버퍼 다이어그램

인덱스 버퍼는 꼭짓점 버퍼 내의 특정 꼭짓점을 참조하는 VB 인덱스 값을 저장합니다. 꼭짓점 버퍼는 꼭짓점 배열로 간주될 수 있으므로 VB 인덱스는 단순히 대상 꼭짓점의 꼭짓점 버퍼에 대한 인덱스입니다. 마찬가지로 IB 인덱스는 인덱스 버퍼의 인덱스입니다. 주의하지 않으면 매우 빠르게 혼동될 수 있으므로 사용 중인 어휘에 대해 명확히 확인해야 합니다. 즉, VB 인덱스 값이 꼭짓점 버퍼로 인덱싱되고, IB 인덱스 값이 인덱스 버퍼에 인덱스되고, 인덱스 버퍼 자체가 VB 인덱스 값을 저장합니다.

그리기 호출은 다음과 같습니다. 모든 인수의 의미는 다음 그리기 시나리오에 대해 길이에 따라 설명됩니다. 지금은 이 호출이 Direct3D에 인덱스 버퍼 내의 위치 0부터 시작하여 두 개의 삼각형이 포함된 삼각형 목록을 렌더링하도록 다시 지시합니다. 이 호출은 이전과 정확히 동일한 순서로 동일한 두 개의 삼각형을 그려서 적절한 시계 방향 방향을 보장합니다.

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    0,                  // StartIndex
                    2 );                // PrimitiveCount

시나리오 3: 인덱싱을 사용하여 삼각형 하나 그리기

이제 두 번째 삼각형만 그리려고 하지만 다음 다이어그램과 같이 전체 쿼드를 그릴 때 사용되는 것과 동일한 꼭짓점 버퍼와 인덱스 버퍼를 사용하려고 합니다.

두 번째 삼각형의 인덱스 버퍼 및 꼭짓점 버퍼 다이어그램

이 그리기 호출의 경우 사용되는 첫 번째 IB 인덱스는 3입니다. 이 값을 StartIndex라고 합니다. 사용되는 가장 낮은 VB 인덱스는 0입니다. 이 값을 MinIndex라고 합니다. 삼각형을 그리려면 꼭짓점이 3개만 필요하지만 이 세 꼭짓점은 꼭짓점 버퍼의 인접한 4개 위치에 분산됩니다. 그리기 호출에 필요한 꼭짓점 버퍼 메모리의 연속 블록 내 위치 수를 NumVertices라고 하며 이 호출에서는 4로 설정됩니다. MinIndex 및 NumVertices 값은 Direct3D가 소프트웨어 꼭짓점 처리 중에 메모리 액세스를 최적화하는 데 도움이 되는 힌트일 뿐이며, 단순히 전체 꼭짓점 버퍼를 성능 가격에 포함하도록 설정할 수 있습니다.

단일 삼각형 케이스에 대한 그리기 호출은 다음과 같습니다. BaseVertexIndex 인수의 의미는 다음에 설명됩니다.

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

시나리오 4: 오프셋 인덱싱을 사용하여 삼각형 하나 그리기

BaseVertexIndex는 인덱스 버퍼에 저장된 모든 VB 인덱스에 효과적으로 추가되는 값입니다. 예를 들어 이전 호출 중에 BaseVertexIndex에 대해 50 값을 전달한 경우 DrawIndexedPrimitive 호출 기간 동안 다음 다이어그램에서 인덱스 버퍼를 사용하는 것과 기능적으로 동일합니다.

basevertexindex에 대한 값이 50인 인덱스 버퍼의 다이어그램

이 값은 거의 0 이외의 값으로 설정되지 않지만 꼭짓점 버퍼에서 인덱스 버퍼를 분리하려는 경우 유용할 수 있습니다. 특정 메시에 대한 인덱스 버퍼를 채울 때 꼭짓점 버퍼 내의 메시 위치를 아직 알 수 없는 경우 꼭짓점 버퍼의 시작 부분에 메시 꼭짓점이 있는 척하기만 하면 됩니다. 그리기를 호출할 때가 되면 실제 시작 위치를 BaseVertexIndex로 전달하기만 하면됩니다.

이 기술은 단일 인덱스 버퍼를 사용하여 메시의 여러 인스턴스를 그릴 때도 사용할 수 있습니다. 예를 들어 꼭짓점 버퍼에 그리기 순서가 동일하지만 꼭짓점이 약간 다른 두 개의 메시(확산 색 또는 텍스처 좌표)가 포함된 경우 BaseVertexIndex에 서로 다른 값을 사용하여 두 메시를 모두 그릴 수 있습니다. 이 개념을 한 단계 더 나아가 하나의 인덱스 버퍼를 사용하여 각각 다른 꼭짓점 버퍼에 포함된 메시의 여러 인스턴스를 그릴 수 있습니다. 단순히 어떤 꼭짓점 버퍼가 활성 상태인지 순환하고 필요에 따라 BaseVertexIndex를 조정하기만 하면 됩니다. BaseVertexIndex 값도 MinIndex 인수에 자동으로 추가되므로 사용되는 방법을 확인할 때 의미가 있습니다.

이제 이전과 동일한 인덱스 버퍼를 사용하여 쿼드의 두 번째 삼각형만 그리려고 하는 척합니다. 그러나 쿼드가 VB 인덱스 50에 있는 다른 꼭짓점 버퍼가 사용되고 있습니다. 쿼드 꼭짓점의 상대 순서는 변경되지 않고 꼭짓점 버퍼 내의 시작 위치만 다릅니다. 인덱스 버퍼 및 꼭짓점 버퍼는 다음 다이어그램과 같습니다.

vb 인덱스가 50인 인덱스 버퍼 및 꼭짓점 버퍼의 다이어그램

적절한 그리기 호출은 다음과 같습니다. BaseVertexIndex는 이전 시나리오에서 변경된 유일한 값입니다.

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    50,                 // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

기본 형식 렌더링