DirectX 그리는 방법(점생성부터)


안녕하세요.
글이 좀 길어질거 같네요. 빨리 쓰도록 하겠습니다.

 


 


 


 


그림을 그리는 방법은 전에 얘기했듯이 트라이앵글스트립,트라이앵글리스트,트라이앵클팬,라인리스트,라인스트립,포인트 등이 있다.


 


그것은 나중에 설명하기로하고(이페이지 하단) 먼저 3차원이란 무엇인가 생각해보자.


 


3차원을 나타내려면(또는 2차원이래도), 점,선,면. 이런게 필요하다.


 


그런데 조금만 더 생각해보면 점만 있으면 될것도 같다.


 


어짜피 점을 이으면 선이되고 .또 면도 되니까.


 


결국 우주의 시작(?)은 점이다.


 


그렇기 때문에 우리는 그림을 그리기 전에 먼저 점을 만드는 것이다.


 


 


 


 


 


 


 


점을 만들자


 


virtual HRESULT STDMETHODCALLTYPE CreateVertexBuffer (THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) PURE


 


g_pD3DDevice -> CreateVertexBuffer(A, B, C, D, E, F);


 


A : 점의개수 * 한개의점의크기 : 이건 내부적으로 메모리를 할당하려고 필요한거 같다.(MS사에서 만들걸 누가알겠어? 그냥 그렇게 추측하고 MS 사가 하라는데로 하는게 장땡)


B : 죄송 지금 MSDN을 안깔아놨네요 ㅡ.,ㅡ 요즘 DX 로 작업을 안하고 OpenGL로 작업을 하다보니… 이건 그냥  0 넣으면 될거 같아요.


C : D3DFVF_CUSTOMVERTEX : 이건 점의 성격을 지정하는것이다.


 


점의 성격은  D3DFVF_XYZ 와 D3DFVF_XYZRHW 와 D3DFVF_DIFFUSE 와 D3DFVF_NORMAL , D3DFVF_TEX1 등이 있다.


(참고로 D3DFVF_CUSTOMVERTEX 는 #define 으로 선언된 조합을 말한다.)


 


3차원의 점을 만들때는 D3DFVF_XYZ 를


2차원의 점을 만들때는 D3DFVF_XYZRHW


점에 색을 넣고 싶으면 D3DFVF_DIFFUSE


점에 빛을반사하는성분(거울이나, 유리처럼?)을 넣고싶으면 D3DFVF_NORMAL (이건 좀 설명이 애매하네 생략 ㅋㅋ)


점에 그림정보(?) 를 넣고싶으면 D3DFVF_TEX1  을 포함하여 만들어야한다.


 


어떤사람은 아니… A 부분에서 크기만 알려주면됬지 멀또 이런거 알려줘야하나, 당연히 크기보구 지가 알아서 판단좀 하면 안되??


라고 생각하는 사람이 있다.(예전에 내가 그랬다. ㅋ)


 


하지만 x,y,z,rhw,color 과 x,y,z,tu,tv 의 경우 기능은 다르나 용량이 같을수 있다.(로 이해했다. ㅋ)


 


D : D3DPOOL_DEFAULT : 저도 연구는 안해봤는데. 이건 자원관리방식 인거 같아요;;;;-_-;


 


E : 점을 얻을 포인터(LPDIRECT3DVERTEXBUFFER9)


 


F : 공유핸들? 몰라 걍 NULL 하자 ㅡ,ㅡ;


 


=> 그러고보니 이거조차 제대로 연구도 안하고 그동안 썼었군;; 쩝쩝( 바빠죽겠는데 머 대충 되기만하면되지 ㅋㅋㅋㅋ 농담;;;;)


 


 


해서 점을 만들었습니다. 점을 만들때에 점의 총크기와 점의 성격부분이 젤루 중요하네요;


 


점은 프로그램 초기에 한번만 만들어야합니다.


 


-어떤분이 책 59쪽(또는 듀토리얼) 에있는 InitVB(); 함수를 매프레임마다 호출하면서 점을 바꿔서 구현했더군요;


 


그분이 저한테 오는 질문;;; 처음에는 잘 작동되는데 시간이 흐를수록 느려져요;; 왜그럴까요;;;… 소스를 보니 .. 그랬더군요.


 


점은 한번만 만듭니다. 계속 만들면 느려집니다. ^^; – 그렇다고 한개만 만들란 말은 아니죠 필요한 만큼만드세요(케릭터, 배경, 인터페이스.. 이런식으로 점이 필요하겠죠)


 


 


 


 


 


 


점을 수정하자


 


 


책 59쪽에는


 


CUSTOMVERTEX vertices[]  =


{


어쩌구, 저쩌구


};


 


를 한후에 CreateVertexBuffer() 을 했는데요…


 


CUSTOMVERTEX vertices[]  =


{


어쩌구, 저쩌구


};


 


이부분은 없어도 됩니다. 걍만들기만 하세요..


 


그리고 책에서 g_pVB->Lock(), g_pVB->Unlock() 부분은 함수를 따로 만드셔서 따로 구현합니다.


 


 


ex)


 


void initvertex()


{


 g_pD3DDevice->CreateVertexBuffer(어쩌구 저저구);


}


 


void setposition()


{//한국말로 vertices 로 받을테니 던져봐~~


CUSTOMVERTEX *vertices;


g_pVB->Lock(0, sizeof(CUSTOMVERTEX)*점의개수,(void**)&vertices, 0);


 


vertices[0].x = ?;


vertices[0].y = ?;


vertices[0].z = ?;


vertices[0].rhw = 1.0;


 


vertices[1].x = ?;


vertices[1].y = ?;


vertices[1].z = ?;


vertices[1].rhw = 1.0;


 


vertices[2].x = ?;


vertices[2].y = ?;


vertices[2].z = ?;


vertices[2].rhw = 1.0;


 


vertices[3].x = ?;


vertices[3].y = ?;


vertices[3].z = ?;


vertices[3].rhw = 1.0;


 


g_pVB->Unlock();


}


 


void setcolor()


{//한국말로 vertices 로 받을테니 던져봐~~


CUSTOMVERTEX *vertices;


g_pVB->Lock(0, sizeof(CUSTOMVERTEX)*점의개수,(void**)&vertices, 0);


 


vertices[0].color = ?;


vertices[1].color = ?;



 


g_pVB->Unlock();


}


 


 


이런식으로 포지션, 컬러, UV, 노말 등 다 각자 따로따로 변경할수 있는 함수를 작성합니다.


 


여기서 Lock 와 Unlock 에 대해서 잠시 설명.


 


그래픽카드에서 하드웨어 가속이 있죠.


 


점의 이동 변환 색의 변환 등… 하드웨어가 어느정도 알아서 연산하는경우도 있고,


 


DirectX 라이브러리 내부에서 무슨무슨 연산을 하겠쬬.


 


그런연산을 하는 도중에 점의 정보를 바꿔버리면, 꼬여버리게 됩니다.


 


그래서 생각한것이.


 


Lock( 야 잠만 내가 머좀 할랑게, 연산좀 하지말아봐)


 


머,, 머,, 작업한다.


 


Unlock( 야 나 할꺼 다 했으… 너가 연산 할람 해도되 ㅋㅋ)


 


 


이런식으로 진행되는거죠.


 


 


잡담


 


 


아~~~ 이런 트라이앵글 스트립 언제 하는겨 ㅠ.ㅠ


 


밥먹으러 가야한디. 이따 다시…. 추가 하겠어용…. 지워지면 안되니 일단 저장 ㅋㅋ


 


 


 


 


 


 


트라이앵글스트립, 트라이앵글리스트 등….


 


책 55쪽에 나와있습니다.


 


1. 점을만든다.


2. 점을 수정한다.(위치, 색 등)


3. 여기서 비긴씬(BeginScene())


 


4. g_pd3dDevice -> SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));


5. g_pd3dDevice -> SetFVF(D3DFVF_CUSTOMVERTEX);


6. g_pd3dDevice -> DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1);


 


7. 여기서 앤드씬(EndScene())


9. 여기서 Present() : 전면버퍼와 후면버퍼의 입장을 바꾼다.


 


 


4,5,6 부분이 그림 그리는 부분이 되겠습니다.


 


4번 : 어떠한 점을 이용하여 그림을 그릴지 알려준다. 여기서는 g_pVB 를 이용하여 그린다고 함. 점하나의 크기도 알려줌.


5번 : 점의 성격을 알려줍니다.(만들때도 알려주지만 사용할때도 알려주고 사용해야하내요..)


6번 : 그림을 그리는데 트라이앵클 리스트 방식으로 0번 점부터 1개 그립니다.


 


 


 


 



포인트 리스트 : 그냥 점을 그립니다. 점을 위와 같이 8개 만들었어도. DrawPrimitive 에서 몇번점부터 몇개 그린다…. 만큼만 그려집니다.


 


 



라인 리스트 : 선을 그립니다. 앞에점 부터 2개씩 세트로 그리게 됩니다…


0번점부터 2개를 그려라  : 0-1, 1-2 그린다.


3번점부터 2개를 그려라 : 3-4, 5-6 그린다. (이경우라면 위의 그림은 잘못된거죠 3-4 가 선이여야하니까, 위그림은 0번점부터 4개)


만약 위와같이 점이 총 8개인데 0번점부터 5개 그려라… 그럼 에러납니다 . ^^


 


 


 



라인 스트립 : 선을 그린다. 앞에점부터 이어서 그린다.


0번점부터 라인 4개를 그려라 : 0-1, 1-2, 2-3, 3-4


점이 8개인데 0번점부터 8개 그려라 : 에러 (점이 8개면 7개그릴수 있음)


 


 


 



트라이앵글 리스트 : 삼각형을 그린다. 앞에점부터 3개세트씩 그린다.


0번점부터 삼각형 2개를 그려라 : 012, 345


위와같이 점이 8개인경우에 0번점부터 삼각형 3개 그려라 : 에러(3개를 그릴수 없음)


 


 



트라이앵글 스트립 : 삼각형을 그린다. 처음3개의 점으로 삼각형을 그리고, 새로운점과 최근의두점으로 삼각형을 그린다.


0번점부터 삼각형 3개를 그린다. : 012, 123, 234


 


이게 좀 헷갈릴수 있다. 간단히 생각하자 앞에서 부터 처음3개의점을 연결하여 삼각형을 만들고, 그 다음부터는 점이 추가될때마다


최근 두점과 연결하여 삼각형을 만드는것.


 


사각형(인터페이스 같은경우) 을 그릴때 혹자는


트라이앵글 리스트로 : 012, 345 로 삼각형 2개를 그리고  점 1번과 점 3번의 위치가 같게, 점2번과 점4번의 위치가 같게 하여 그리는경우가 있다. 이경우는 트라이앵글 스트립으로 간단히 0번점부터 삼각형 2개 그려라… 해주면 된다. 012, 123


 


 



트라이앵글 팬 : 삼각형을 그린다. 처음3개의 점으로 삼각형을 그리고, 새로운점과-최근한점-처음점 으로 삼각형을 그린다.


 


0번점부터 삼각형 5개를 그려라 : 012, 320, 430, 540, 650


 


0번점을 가운데 두고 원을그리듯이 1,2,3,4,5, 번의 점이 있을때, 이 방식으로 그리면 팬피자? 의 모양이 되어서 트라이앵글 팬이다. ㅋ


 


후라이팬도 생각나고 ㅋㅋ


 


 


 


힘들다 좀 쉬어야겠다 ㅋㅋㅋㅋ


 


그럼 즐거운 프로그래밍 하세요;


 


 


 


 


 


참고로 삼각형 2개면 사각형을 할수 있으므로 사각형이상은 없습니다.


 


단, OpenGl 에서는 사각형이 있어요;;


답글 남기기

이메일 주소는 공개되지 않습니다.