이번 시간에는 저번시간에 예약 했떤 대로
Index Buffer 인덱스 버퍼에 대해서 알아 보겠습니다.
우선 소스에 대한 것을 알기 전에 간단한 이론부터 알아 보도록 하죠.
인덱스 버퍼를 사용하는 이유입니다.
우선 우리는 정점을 정의했었습니다. 구조체에다가 정점을 일일이 넣었었죠.
간단한 사각형 하나를 그리기 위해서 우리는 정점 6개를 정의 했었어야 했습니다.
하지만 실제로 눈에 보이는 정점은 4개면 됩니다. 뭔가 불필요하지 않나요?
정점을 정의하고 정점 버퍼를 생성하는 것은 그 만큼의 메모리를 차지합니다.
이건 정말 억울한 메모리 낭비입니다. 단순 6개라면 모르겠지만
나중에 캐릭터라든가 집이라든가 란걸 그린다면? 몇백 몇천개의 정점이 필요할텐데
이때 중복되는 정점의 수만해도 적게는 몇십, 많게는 몇천이 있을 지도 모릅니다.
그 중복되는 메모리만 우리가 다른 곳에 활용한다면 더 좋은 게임을 만들 수 있습니다.
이렇게 인덱스 버퍼를 사용하면 중복되는 메모리를 낭비하지 않아도 좋습니다.
인덱스 버퍼를 사용한 단편적인 예를 보여드리겠습니다.
우선 사각형을 그리기 위해 정점 4개를 정의합니다.
0 : -1, 1, 0
1 : 1, 1 , 0
2 : -1, -1, 0
3 : 1, -1, 0
으로 말이죠.
왜 0번부터 시작하는 지는 당연히 아시겠죠?
이렇게 정점을 저장하면 비디오 메모리에는 0번 1번 2번 3번하고 저장이 됩니다.
즉 인덱스가 붙는 거죠.
그리고 우리가 삼각형을 그릴 때는 단순히 인덱스 번호만 불러 옵니다.
0 : 0 1 2
1 : 1 3 2
이렇게 말이죠.
이런 전에 했던 노가다 보다 훨씬 편하고 좋네요.
척 생각만 해도 너무나 좋습니다.
단순 사각형이라서 몸에 와닿지가 않나요?
그럼 육면체를 그려 보시기 바랍니다.
육면체 이다보니 사각형 수가 6개 입니다.
그리고 사각형 수가 6개 이면 삼각형 수는 12개 입니다.
삼각형 수가 12개 이면 우리가 넣어야 할 정점의 수는 36개 입니다.
이건 눈 돌아 갑니다. 괜히 한면이 안 그려지면 어디가 잘못된거야!!
라고 하면서 키보드를 쿵하고 칩니다. 그러면 키보드 불쌍해지죠...크흑..
하지만 인덱스 버퍼를 사용해서 육면체를 그려 봅시다.
필요한 정점의 수는 8개면 됩니다. 맞죠?
그리고 인덱스 리스트를 만듭니다.
인덱스 리스트란 위에서처럼 0 1 2, 1 3 2 와 같이 인덱스들을 리스트 해놓은 겁니다.
이 인덱스 리스트는 몇개가 생성될까요?
삼각형의 수 만큼 생성됩니다. 즉 12개만 정의해주면 되죠.
그러면 우리가 정의해야 하는 것은 총 몇개일까요?
정점 8개 + 인덱스 리스트 12개 = 20개.
위에서 정점을 정의한 36개 보다 턱없이 작습니다.
그리고 메모리에 차지하는 공간도 정점만 가지고 그릴 땐 36개의 정점 정보량이
인덱스를 사용해서 그릴땐 8개의 정점 공간과 12개의 인덱스 리스트 공간만 잇으면 됩니다.
메모리 양이 확 줄어 들죠. 너무 좋습니다.^^.
그럼 이제 실행 파일과 소스파일을 다운 받으시고 공부를 합시다.
역시 위에서부터 봅니다.
D3D 객체 중에 하나 추가된 것이 있습니다.
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; // 인덱스 버퍼 객체
이것입니다. 말 그대로 인덱스 버퍼 객체 입니다.
그리고 밑으로 내려가서.. 타이틀 이름과 클래스 이름도 바뀌었군요. ^^
구조체를 봅니다.
정점 정보를 저장했던 방법과 마찬가지로 인덱스 버퍼를 저장할 구조체를 정의합니다.
// 인덱스 정보
struct INDEX{
WORD idx[3];
};
자 그럼 이제 달라져야 할 곳이 한군데 더 있다는 건
직감으로 다들 아실거라 믿고 워프를 합시다.
워프 장소 : InitGeometry()
우선 변경해야 할 건 정점에 대한 정보겠죠.
위의 이론에서 설명 드린것처럼 우리가 필요한 정점은 4개 입니다.
그러니 정점 4개만 남겨놓고 지웠습니다. 휴~ 훨씬 적어 보이죠^^
그리고 인덱스 리스트를 만듭니다.
우리가 그릴 삼각형은 2개만 있으면 됩니다. 사각형을 그릴 거니까 말이죠.
그럼 인덱스 구조체에 리스트를 넣는 순서는?
일반 정점 정보 넣는 식으로 시계방향으로 넣습니다.
인덱스 번호는 어떻게 정의 되는 걸까요?
그건 Vertices 구조체에서 우리가 넣는 순서대로 0번부터 붙게 됩니다.
이해하기 쉽죠? 원래 배열은 0번이 처음이니까 말이죠.
구조체 배열의 순번을 넣어 준다고 생각하시면 됩니다.
그리고 다음에 인덱스 버퍼를 생성했습니다.
으아~ 따라붙는 매개변수가 꽤 됩니다.
이걸 일일이 설명드리는 건 한계라 생각하고 필요한 것만 설명하겠습니다.
첫번째 매개변수, 이건 우리가 넣어준 인덱스 리스트의 크기 입니다.
소스에서처럼 단순히 우리가 넣어준 구조체의 크기를 넣어주면 되겠죠.
다섯번재 매개변수, 이건 우리가 제일 위에서 정의했던 인덱스 버퍼 입니다.
즉 이 인덱스 버퍼에다가 저장하겠으니 이녀석을 인덱스 버퍼로 만들어라 이거죠.
정점 버퍼 생성할 때와 비슷한 부분입니다.
나머지 두번째, 세번째, 네번째는 SDK를 참고하세요.
자 생성했으니 뭘 해야 할까요?
인덱스 버퍼에 값을 넣어 줘야 합니다.
인덱스 버퍼도 정점 버퍼와 마찬가지로 Lock을 걸어 줍니다.
응? 근데 들어가는 매개변수들이 정점 버퍼와 비슷합니다...가 아니라 같죠.
그럼 설명할 부분이 많이 줄어들었네요^^
역시 Lock()을 거신후 Unlock() 하는 것 잊지 마시구요.
자 인덱스 버퍼에 값도 넣었겠다. 멋지게 그려 봅시다.
Render() 로 워프~!!
음 그리 달라져 보이는 건 없네요.
그럼 그냥 끝낼까요? (이게..이게....) 하하 죄송합니다...꾸벅
달라진 부분에 대해서 설명을 드리겠습니다.
우선 첫번째, SetIndices 이녀석입니다.
이건 우리가 사용한 인덱스 버퍼를 얘기합니다.
그리고 두번째, 기존에는 DrawPrimitive 를 사용해서 그렸습니다.
하지만 이제는 DrawIndexedPrimitive 를 사용해서 그립니다.
근데 매개변수가 꽤 있네요. 첫번째 매개변수는 동일하니까 알겠고..나머지는?
우리가 알아야 할 건 네번째와 마지막 입니다.
네번째 매개변수는 우리가 사용한 정점이 몇개인가를 적는 것입니다.
우린 사각형 하나 그렸으니 4로 정의를 합니다.
마지막 매개변수는 인덱스 리스트의 개수 입니다.
사각형을 그리기 위해서 우리는 리스트 두개를 만들었습니다.
그러니 2를 적어주면 원활히 실행이 되겠죠.
그럼 이제 실행을 해보세요. 제대로 되나 확인해 보시기 바랍니다. ^^
그리고 한번 육각형을 직접 정점 정보를 넣어주고 그려보시고
인덱스 버퍼를 이용해서 그려보시길 바랍니다. 일의 양이 다름을 알 수 있습니다.
머리 사용하는 건 같은데 일의 양이 적다면 너무 좋은 거죠.
이것으로 이번 강좌를 마침니다. 수고하셨습니다.^^
그럼 언제나 그렇듯 다음 강좌 예고 입니다.
아마 육각형을 시험삼아 그려보신분은 인상을 찌푸릴 겁니다.
이상하다...분명히 정점좌표 맞고, 리스트 순서 맞고 왜 이상하게 나올까...?
라고 말이죠. 흡족한 결과를 얻지 못했다는 것입니다. 이건 말이죠.
여러분의 소스를 믿으십시요. 제대로 된겁니다.
근데 제대로 안나온다면 무언가 아직 덜 배운게 있다는 거죠.
바로 노말 백터와 빛(LIGHT) 입니다. 아마 오늘중으로 올릴 듯 하네요.
노말 백터와 빛에 대해서 배우고 나신후 다시 한번 육각형을 그려 보시기 바랍니다.
그러면 원하는 결과가 있을 겁니다.^^
그러므로 다음 강좌는 육각형을 그리기!! 노말과 빛!!
하지만 노말과 빛 없이도 할 수 있습니다.
첫댓글 우와~ 강좌가 금방금방 올라오네요 +_+b 원츄~!! 음.. 인덱스버퍼를 사용하면 삼각형리스트를 삼각형스트립처럼 사용하는거에요~!? =_=a;;
아닙니다. 삼각형리스트...TRIANGLELIST 그대로 사용합니다.
^^ 저두 강좌가 빨리 올라와서 너무 좋네여~ ^^
기간이 너무 지나서 파일을 지운건가요?? 실행파일받기 및 소스파일받기가 안되네요.. 이제 공부를 시작해서요.