정점과 마찬가지로, 색인도 GPU가 접근할 수 있는 특별한 자원에 넣어야 한다. 이를 '색인 버퍼'라 부른다. 색인 버퍼는 정점 버퍼와 매우 비슷하다. 예제 코드를 통해 몇 가지 차이점에만 주목하자.
UINT indices[] = {
0, 1, 2,
0, 2, 3,
4, 6, 5,
4, 7, 6,
4, 5, 1,
4, 1, 0,
3, 2, 6,
3, 6, 7,
1, 5, 6,
1, 6, 2,
4, 0, 3,
4, 3, 7
};
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * 36; // 바이트 크기가 달라졌다.
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; // 인덱스 버퍼용으로 묶었다.
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices; // 인덱스 배열을 가리킨다.
ID3D11Buffer* mIB;
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));
md3dImmediateContext->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);
입력 조립기 단계에 묶을 때, ID3D11DeviceContext::IASetIndexBuffer 메서드를 사용하였다. 여기서 제1 매개변수는 묶을 버퍼, 제2 매개변수는 색인의 형식이다. UINT를 사용했으므로 그에 맞는 형식을 썼다. 이 UINT는 D3D11_BUFFER_DESC::ByteWidth에도 쓰이는 걸 알고 있어야 한다. 제3 매개변수는 바이트 단위의 오프셋 값으로, 입력 조립기가 색인 버퍼에서 색인 자료를 읽기 시작할 위치를 뜻한다. 색인 앞부분을 건너 뛸 필요가 있을 때 이 값을 적절히 사용하면 된다.
마지막으로 색인 버퍼를 이용해서 기본도형을 그릴 때는 Draw 메서드 대신 DrawIndexed 메서드를 사용해야 한다.
void ID3D11DeviceContext::DrawIndexed(
UINT IndexCount,
UINT StartIndexLocation,
INT BaseVertexLocation);
이 메서드를 이해하기 위해 예를 들겠다. 구, 상자, 원기둥을 그릴려고 한다. 이는 각각의 정점 버퍼, 색인 버퍼들이 있었으나 정점 버퍼는 정점 버퍼끼리, 색인 버퍼는 색인 버퍼끼리 합치고 싶다고 하자. (이러면 정점 버퍼, 색인 버퍼를 변경할 때 생기는 추가 부담을 약간 덜 할 수 있다. 하지만 그렇게 큰 문제는 아니다.) 버퍼들을 합치면, 색인들이 잘못된 정점을 가리키게 된다. 따라서 새로운 정점 버퍼에 맞게 색인들을 다시 계산할 필요가 있다.

(사진 출처 : DirectX 11을 이용한 3D 게임 프로그래밍)
위의 그림과 같이 구, 상자, 원기둥 순으로 버퍼들을 합쳤다고 하자. 이때 원래 코드와 고친 후 코드를 비교해보겠다.
// 수정 전.
DrawIndexed(mNumBoxIndices, 0, 0);
// 수정 후.
DrawIndexed(mNumBoxIndices, firstBoxIndex, firstBoxVertexPos);
왜 이렇게 해야 하는가? 만약 수정 전 코드로 한다면, vertex와 index 버퍼를 모두 0에서부터 시작했기 때문에, 구의 버퍼와 색인을 이용하게 되는 것이다. 구의 버퍼와 색인을 이용하는데 색인 개수는 상자의 것을 사용해서 완전 엉터리 작업물이 나오게 된다. 그래서 적절한 오프셋이 필요한 것이다. 이 경우에는 세 번의 호출로 세 작업물을 그릴 수 있다.
md3dImmediateContext->DrawIndexed(numSphereIndices, 0, 0);
md3dImmediateContext—>DrawIndexed(numBoxIndices, firstBoxIndex, firstBoxVertexPos);
md3dImmediateContext->DrawIndexed(numCylIndices, firstCylIndex, firstCylVertexPos);