direct3d를 하면서 기초를 너무 소홀히 한거 같다. 가장기본인 device생성 부터 버벅대다니.

pd3dDevice =  CreateDevice(....,DWORD dwBehaviorflags,...);
여기에 들어가는 옵션으로 3가지가 있다.
첫째, D3DCREATE_MIXED_VERTEXPROCESSING  - 실시간으로 정점연산을 하드웨어와 소프트웨어 방식을 변경이 가능하다. 변경은 pd3dDevice->SetSoftwareVertexProcessing(TRUE); 해줌으로 소프트웨어 방식 사용, FLASE를 넣어주면 하드웨어 방식을 사용.
둘째, D3DCREATE_HARDWARE_VERTEXPROCESSING - 정점연산을 하드웨어 방식에만 의존.
셋째, D3DCREATE_SOFTWARE_VERTEXPROCESSING - 정점연산을 소프트웨어 방식에만 의존.

이런것 조차 간과 하고 있었다니ㅡ_ㅡ;

Posted by hazeyun
,
사용자 삽입 이미지

D3DXCreateRenderToSurface 함수에 대한 설명은 msdn이나 Directx 문서에 잘 나와있으니 생략하고 일단 D3DXCreateRenderToSurface함수를 이용해서 텍스쳐에 그려주려면 일단
LPD3DXRENDERTOSURFACE   g_pRenderToSurface;
LPDIRECT3DTEXTURE9           g_pTexture;
LPDIRECT3DSURFACE9          g_pSurface;

와 같은 3개의 개체가 필요하다. 위의 개체 말고도 여러가지 부수적인 것들도 필요하지만 설명을 위한 필수 항목만 언급하겠다.


위의 3개체 가 선언 되었다면 D3DXCreateRenderToSurface 함수를 이용해 RenderToSurface개체를 얻고 D3DXCreateTexture함수로 그려질수 있는 텍스쳐개체를 얻어온다. 그리고 GetSurfaceLevel함수를 사용해서 서페이스에 그려지는걸 텍스쳐에 그대로 옮기도록 설정한다.
D3DXCreateRenderToSurface(g_pd3dDevice, 256, 256, D3DFMT_A8R8G8G8, TRUE, D3DFMT_D24S8, &g_pdRenderToSurface);
D3DXCreateTextureg_pd3dDevice, 256, 256, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture);
g_pTexture->GetSurfaceLevel(0, &g_pSurface);

초기화가 됐으면 이제 surface에 그려주면 된다.
g_pRenderToSurface->BeginScene(g_pSurface, NULL);
g_pd3dDevice->clear(...)
//여기에 surface(texture)에 그려질 부분을 렌더링
해주면 된다
g_pRenderToSurface->EndScene(0);

이제 texture에 그려진 장면을 정점을 잡아서 uv좌표에 맞춰서 랜더링 해주면 된다. 여기서 가장 중요한건 RenderToSurface를 만들거나 Texture를 만들때 format이랑 width, height를 꼭 맞춰 주어야 한다. 심지어 텍스쳐를 입힐 사각형의 크기도 width, height를 맞춰 주어야 한다.
Posted by hazeyun
,

3인칭 시점의 게임은 카메라가 캐릭터의 일정거리 뒤쪽에 위치하게 됩니다.
거기에 지형을 통메쉬로 만들어 상하좌우가 막혀있는 공간이다 보니 캐릭이 벽에 가까이 다가서게 되면
카메라가 지형밖으로 나가 버리게 되고 캐릭은 지형에 가려서 보이지 않게 됩니다.
처음 생각한 방법이 간단하게 지형 메쉬를 렌더 할 때 D3DRS_CULLMODE를  D3DCULL_NONE으로 해서
카메라가 지형 밖에 위치하게 되면 벽면을 그려주지 않게 하는 방법입니다.  
하지만 이방법은 너무 허접해 보여서 탈락.
그래서 일반적인 방법을 이리저리 찾아봤는데 projection의 nearplane을 지형과 어찌 저찌 해야
한다는 방법이었는데 찬찬히 읽어보다가 갑자기 생각난 것으로 일단 땜방했습니다.
.
.
본론으로가서 이용한 방법은 D3DXIntersect함수를 사용해서 체크하는 방법입니다.
D3DXIntersect함수가 부하가 많이 걸린다는 말을 어디서 본것 같은데 어디까지나 임시 방편이기
때문에 그부분은 스킵.
일단 이론은 카메라에서 캐릭방향으로 ray를 쏴서(카메라가 캐릭을 바라보고있기 때문)
쏘아진 ray에 지형 메쉬의 충돌이 있는가 확인해서 카메라가 밀려난 만큼 보정을 해주는 방법입니다.

구현의 요점은
//카메라의 시점벡터...matView는 viewtransformMatirx...
D3DXVECTOR3 dir(matView._13, matView._23, matView._33); 

//시점벡터를 정규화 해줌....
D3DXVec3Normalize(&dir, &dir);  

//정규화 해준 dir과 지형메쉬인 포인터인 g_pCollMesh, 카메라의 좌표인 vEyept를 넣어줘서
//intersect함수를 통해서 지형메쉬와의 충돌을 체크해줌....
//여기서 카메라의 좌표는 최종 월드변환후의 좌표...
D3DXIntersect(g_pCollMesh, &vEyept, &dir, &bHit, &dNearIndex, &u, &v, &dist, &pBuffer, &dCount);  

반환해주는 bHit를 통해서 메쉬와의 충돌유무를 확인 할 수 있습니다.
충돌 되었다는것은 결국 카메라가 바라보는 시점에 메쉬가 위치한다는 것입니다.
하지만 여기서 생각해 봐야 될께 바닥면과의 충돌일 수도 있기 때문입니다.

그래서 마지막으로
//캐릭터 좌표벡터에서 카메라 좌표벡터를 빼서 거리를 구함....
float fRadius = D3DXVec3Length(&(vCharPos - vEyept));  

여기서 구한 캐릭과 카메라의 거리사이에 충돌지점이 있는지 확인 해야 됩니다.
그부분이 intersect함수에서 반환해주는 dist를 통해서  확인 가능합니다.
if(dist < fRadius)
{
    //지형과 ray의 충돌지점이 카메라와 캐릭사이에 있을경우 진입.....
}
하지만 이방법의 경우 땜빵 방법이라 더 알아 봐야겠습니다.
어디까지나 임시방편;;ㅋ

Posted by hazeyun
,