- 현재 하이트 맵의 가장 간단한건 구현… 와이어프레임으로 랜더링하고 있다.
raw 파일에서 64*64 크기의 높이 정보를 읽어와서 버텍스들을 생성하고 인덱스버퍼를 만들어 랜더링한다. 랜더링 상태를 SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME) 으로 설정해서 와이어프레임이 꽉꽉차서 보인다.(과거 이 옵션을 몰라서 랜더링 옵션을 D3DPT_LINESTRIP 으로 하고 랜더링된 와이어프래임을 보고 “어째서 나의 와이어 프레임은 부실하게 나올까” 하고 고민한적이있다….)
음 하이트맵의 데이타를 생성하는 코드를 써보면
unsigned char TmpHeight; // 버텍스버퍼와 인덱스버퍼를 위한 중간 버퍼들 FVF_HEIGHTMAP* pVertexData = new FVF_HEIGHTMAP[m_dwVertices]; WORD* pIndexData = new WORD[m_dwPrimitives*3]; //파일에서 높이 정보를 읽어오고 버텍스정보를 삽입한다. FILE* pFile; UINT nIndex = 0; pFile = fopen(szFilename, "rb"); for(unsigned y = 0;y < (HEIMAP_Y + 1); y++) { for(unsigned x = 0;x < (HEIMAP_X + 1); x++) { TmpHeight = fgetc(pFile); // 버텍스 데이타 구성 pVertexData[x + y * (HEIMAP_X+1)].fX = (float)x; pVertexData[x + y * (HEIMAP_X+1)].fY = (float)TmpHeight / 15.0f - 40; pVertexData[x + y * (HEIMAP_X+1)].fZ = (float)y; pVertexData[x + y * (HEIMAP_X+1)].dwColor = 0xffffffff; if( (y < HEIMAP_Y) && (x < HEIMAP_X) ) { // 인덱스 데이타 구성 pIndexData[(x+y*(HEIMAP_X))*6 +0] = x + y * (HEIMAP_X+1); pIndexData[(x+y*(HEIMAP_X))*6 +1] = x+1 + y * (HEIMAP_X+1); pIndexData[(x+y*(HEIMAP_X))*6 +2] = x + (y+1) * (HEIMAP_X+1); pIndexData[(x+y*(HEIMAP_X))*6 +3] = x + y * (HEIMAP_X+1); pIndexData[(x+y*(HEIMAP_X))*6 +4] = x+1 + (y+1) * (HEIMAP_X+1); pIndexData[(x+y*(HEIMAP_X))*6 +5] = x + (y+1) * (HEIMAP_X+1); } } } fclose(pFile); // 버텍스버퍼를 구성한다. m_pVB->Create(m_pGraphics, m_dwVertices, sizeof(FVF_HEIGHTMAP), D3DFVF_HEIGHTMAP); m_pVB->Set(0, m_dwVertices, pVertexData); //인덱스데이타를 구성한다. m_pIB->Create(m_pGraphics, m_dwPrimitives*3); m_pIB->Set(0, m_dwPrimitives*3, pIndexData); // 버덱스데이타, 인덱스데이타 메모리를 해재한다. delete [] pVertexData; delete [] pIndexData;
이정도… 간단하다. 밑은 스크린샷 이제는 텍스쳐 매트릭스를 적용하여 한 중류의 텍스쳐로 덥어보자
2 Using Texture Matrix #
http://myevan.net/phpBB/viewtopic.php?t=1445 (빗자루님의 포럼) 에 텍스쳐 메트릭스에 관한 내용이 있다.
음 위의 내용을 이해하면 텍스쳐매트릭스를 사용하는데는 지장이 없을듯 하다. 문제는 다이렉트X SDK인데… 나만 그러는지 모르겠지만 D3DXMatrixDeterminant 를 사용했을때 런타임에러가 발생한다. 그래서 2003 Summer Update로 업데이트를 했는데 일단 위의 문제는 해결됐다. 다만 인테페이스가 바뀐게 좀 있어서 짜증이 난다. -_-;;; 쓰던 코드를 좀 손봐야 할듯하다.
- D3DXMatrixDeterminant 함수는 D3DXMatrixInverse 에 인자로 넣을 값을 얻기 위해서 사용한것이었는데 D3DXMatrixInverse 의 인자는 필요없으면 NULL로 해도 된다고 한다… 아 젠장..
위의 화면처럼 나오는데… 여러종류의 텍스쳐를 입히는것도 아주 쉬울듯하다. 그냥 텍스쳐별로 따로따로 인덱스버퍼를 구성하면 되니… 그런데 그렇게 할려면 맵의 파일 포멧이 좀 바껴야 할태고 그럴려면 이왕에 전용 에디터를 만드는쪽이 좆타… 라는 결론이 나와서 -_-;;; 좀 귀찮다. 일단 위의 하이트맵을 랜더링하는 코드를 보면
void CHeightMap::Rendering(HEIGHTMAP_DRAW_OPTION hdOption) { D3DXMATRIX matrixView; m_pGraphics->GetDeviceCOM()->GetTransform(D3DTS_VIEW, &matrixView); FLOAT fDeterminantMatView = D3DXMatrixDeterminant(&matrixView); D3DXMATRIX matViewInv; D3DXMatrixInverse(&matViewInv, &fDeterminantMatView, &matrixView); D3DXMATRIX matScale; ZeroMemory(&matScale, sizeof(D3DXMATRIX)); matScale._11=1.0f/1.0f; matScale._32=1.0f/1.0f; D3DXMATRIX matTex; D3DXMatrixMultiply(&matTex, &matViewInv, &matScale); // 텍스쳐 좌표 자동생성을 위한 세팅 m_pGraphics->GetDeviceCOM()->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); m_pGraphics->GetDeviceCOM()->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); m_pGraphics->GetDeviceCOM()->SetTransform(D3DTS_TEXTURE0, &matTex); // 랜더링 옵션이 WIRE이면 랜더링 상태를 설정 if(hdOption == RENDER_WIRE) m_pGraphics->GetDeviceCOM()->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); m_pIB->Render( D3DPT_TRIANGLELIST, 0, 0, m_pVB->GetNumVertices(), 0, m_dwPrimitives, m_pVB, m_pTextureDefault ); // 랜더링 옵션이 WIRE이면 랜더링 상태를 해제 if(hdOption == RENDER_WIRE) m_pGraphics->GetDeviceCOM()->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID); // 텍스쳐 좌표 자동생성을 위한 세팅 해제 m_pGraphics->GetDeviceCOM()->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); m_pGraphics->GetDeviceCOM()->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); }
이정도… 자세한 내용은 빗자루님의 글을 참고하는게 좋다. 간단히 설명하면 카메라의 위치와 버텍스의 위치값으로 UV값을 자동 생성해서 텍스쳐를 입히는 것이다.
자 그럼 다음은 맵에디터다