랜더링 할때 정점 버퍼와 인덱스 버퍼를 이용해서 할때 DrawIndexedPrimitive() 함수를 호출하는데
넘겨줄 인자값이 재대로 이해가 되질 않아서
다른 블로그에서 계속 찾아 보던중 잘 정리가 되어있는 블로그를 발견해서 여기다가 쓴다..
출처 : http://blog.naver.com/lgmpfree/100055862741
※ 이 글에 앞서서 필히 확인해야 할것.
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice )
이와 같이.. 디바이스 생성할때, 위와 같이 SOFTWARE로 되어 있어야지 밑에 설명처럼 결과가 나오고 이것저것 실험 할수가 있다.
만약 HARDWARE로 설정할경우.. 하드웨어에서 임의대로 정점을 다 계산해버리고 결과가 좋게(?)만 나와 버린다..
-------------------------------------------------------------------------------------------------------------
DrawIndexedPrimitive 함수에 대하여..!! 정리.
struct CUSTOMVERTEX
{
float x, y, z; //좌표
float nx, ny, nz; //노말 값
float tu, tv; //uv 좌표계
};
//버텍스 버퍼
CUSTOMVERTEX pCustVerts[] =
{
// 정면
{ -2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.6666f }, // v0
{ -2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.3333f }, // v1
{ 2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.6666f }, // v2
{ 2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.3333f }, // v3
// 뒷면
{ 2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.6666f }, // v4
{ 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.3333f }, // v5
{ -2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.75f, 0.6666f }, // v6
{ -2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.75f, 0.3333f }, // v7
// 위
{ -2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.3333f }, // v8
{ -2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.0f }, // v9
{ 2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.3333f }, // v10
{ 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f }, // v11
// 아래
{ 2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f }, // v12
{ -2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 1.0f }, // v13
{ 2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.6666f }, // v14
{ -2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.6666f }, // v15
// 왼쪽
{ -2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.6666f }, // v16
{ -2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3333f }, // v17
{ -2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.6666f }, // v18
{ -2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.3333f }, // v19
// 오른쪽
{ 2.0f,-2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.6666f }, // v20
{ 2.0f, 2.0f,-2.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.3333f }, // v21
{ 2.0f,-2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.75f, 0.6666f }, // v22
{ 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.75f, 0.3333f } // v23
}
//인덱스 버퍼
INDEX pCustIndices[] =
{
{ 0, 1, 2 },
{ 2, 1, 3 },
{ 4, 5, 6 },
{ 6, 5, 7 },
{ 8, 9, 10 },
{ 10, 9, 11 },
{ 12, 13, 14 },
{ 14, 13, 15 },
{ 16, 17, 18 },
{ 18, 17, 19 },
{ 20, 21, 22 },
{ 22, 21, 23 }
}
//위와 같은 정점과 인덱스 정보가 있다는 가정하에..
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, // Primitive 타입
0, //BaseVertexIndex,
0, //MinIndex
24, //NumVertices
0, //StartIndex
12 //PrimitiveCount
);
BaseVertexIndex,: 버텍스 버퍼의 v0, v1, v2, v3, v4가 보일것이다..이것은 1번째 정점이 인덱스 0번 2번째 점이 인덱스 1번 이라고 기본적으로 정해지는것인데. 이 첫번째 인자를 4라고 할경우. 4번째 정점이 v0, 5번째 정점이 v1이 되는것이다. 이 렇게 될경우 인덱스 버퍼의 영향을끼친다.!! 이 부분이 많이 헷갈릴수 있는 부분이고 어려운 인자이다.. 이해가 안돼면 밑에 예제를 참고하세요.
MinIndex : 인덱스 버퍼에서 쓸 가장 적은 숫자를 쓴다 . 예를 들어 0,1,2,3 을 쓰지 않을경우(정면의 삼각형을 안그릴경우) 4를써준다.
그럼 4번 인덱스부터 사용하겠다는 것이다. 이 인자는 5번째 인자의 그릴 삼각형 갯수에 영향을 끼치지 않는다 여기서 정면 삼각형 2개 그리지 않기때문에 5번재 인자를 12에서 10으로 할경우 가장끝의 11, 12면이 그려지지 않고 물론 정면의 1,2면도 눈에는 안보인다 4번인덱스부터 그리기때문이다.
NumVertices : 그려질 정점의 갯수를쓴다. BaseVertexIndex + MinIndex 만큼 빼주면 된다. 예를 들어서 BaseVertexIndex 에 4를 쓰고 MinIndex 는 4를쓰면 24에서 8을빼서 16을써주면 된다. 이 값이 정확히 썼는데 이상한 출력이 나오면 PrimitiveCount이 인자 값을 잘못쓸경우 출력이 이상하니 이 값을 의심해보자. (* 이 값은 StartIndex 인자값의 영향을 받지 않는다)
StartIndex : 인덱스 버퍼의 시작 인덱스를 정한다. { 0, 1, 2 }, { 2, 1, 3 }, { 4, 5, 6 },.... (이하 생략) 이렇게 있을때 3이라고 쓰면 { 0, 1, 2 }, 다음에 있는 2부터 시작해서 그리고.. 6이라고 쓸경우 { 0, 1, 2 }, { 2, 1, 3 }, 다음 인덱스인 4부터 삼각형을 그리겠다는것이다. 7을쓸경우 1부터 그린다.
PrimitiveCount : 삼각형의 갯수를쓴다. MinIndex 의 영향을 받지 않으며, 그려질 삼각형의 갯수를 잘 계산해서 써야한다.
------------------------------------------------------------------------------------------------
이해를 돕기 위해 그림과 같이 설명 .
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
0,
24,
0,
12
);
이렇게 입력하면.. 다음과 같이 정상적인 정육면체 출력
그림 설명 : 빨간 큰 숫자 -> 1번째 삼각형 2번재 삼각형.. 12번째 삼각형까지 있음. (그려진 순서대로 1,2,....12번)
작은시퍼런 숫자 -> 인덱스 번호 0번 1번 2번 ...24번까지 있음. (위의 인덱스 버퍼 선언과 같은 위치)
--------------------------------------------------------------------------------------------------------------------
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, // Primitive 타입
0,
4,
20, //4개의 인덱스를쓰지 않기때문에 20개의 점만있어도 된다.
0,
12 //2개 삼각형이 없지만 인덱스 0,1,2,3만을안쓰겠다고 한거기때문에 여기는 변하면 안됀다 10개 할경우 마지막 2개면 11,12면이 그려지지 않는다
);
이렇게 변경(굵은글씨) 하면 다음과 같이 정면이 뚤려서 나온다.
뚤려 나오는 이유는 인덱스 버퍼의 0,1,2,3 을 안쓴다고 선언 하기때문이다 4부터 쓰기때문에 정면이 나오지 않는다
(참고 - 현재는 g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 상태 이다..)
--------------------------------------------------------------------------------------------------------------------
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, // Primitive 타입
4, //버텍스 버퍼의 4번재 점을 v0 으로 시작 한다는것이다.
0,
20, //버텍스 버퍼의 정점 4번재꺼부터 쓰기때문에 20개의 정점만을쓴다.
0,
10 // 정면 2개의 삼각형이 빠져서 10개면 된다.
);
결과는 위와 마찬가지로 정면이 뚤려 보인다. 하지만 중요한것은 여기선 뒤의(보이진 않지만) 3면의 인덱스 번호가 0,1,2라는것이다. 위의 결과는 3면이 4,5,6이다.
--------------------------------------------------------------------------------------------------------------------
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
4, //버텍스 버퍼의 4번재 점을 v0 으로 시작 한다는것이다.
0,
11, //5번째 인자 가 5개의 삼각형만 그리므로 11개면 된다. 이해가 안되면 잘생각해보기 바란다.
0,
5 // 3면부터 그리기때문에(1번재 인자가 4이므로) 3,4,5,6,7면 5개의 삼각형을 그리리겠다는 것. 밑에 그림처럼 나온다.
);
--------------------------------------------------------------------------------------------------------------------
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0, //위와 다르게 이것을 0으로 하면
0,
11, //5번째 인자 가 5개의 삼각형만 그리므로 11개면 된다.
0,
5 // 1번째 인자가 0이므로 1면부터 그린다.. 1,2,3,4,5 면의 5개의 삼각형을 그린다.
);
결과는 밑에 그림 처럼..단, 3차원이라..공간적 이해를 하시면서 보시길..
--------------------------------------------------------------------------------------------------------------------
g_pd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
0,
24, // 4번째 인자 값에 영향을 받지 않는다 . 여기서 정점수를 24이하로 할경우 이상한 결과를 볼것이다.
15, //15번째 인덱스 정점부터 쓴다.
7 //7개의 삼각형이 그려질것이므로 7이다. 6이라고쓰면 마지막 12면이 나오지 않는다.
};
이렇게 할경우 결과를 보자.