HeightMap Using Texture Matrix ( using one Texture )

1 Make HeightMap Vertex,Index Buffer #

2004년 7월 18일 쯤

  • 현재 하이트 맵의 가장 간단한건 구현… 와이어프레임으로 랜더링하고 있다.

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;

이정도… 간단하다. 밑은 스크린샷 이제는 텍스쳐 매트릭스를 적용하여 한 중류의 텍스쳐로 덥어보자

http://lagoons.net/docdata/Height_1.jpg

2 Using Texture Matrix #

http://myevan.net/phpBB/viewtopic.php?t=1445 (빗자루님의 포럼) 에 텍스쳐 메트릭스에 관한 내용이 있다.

음 위의 내용을 이해하면 텍스쳐매트릭스를 사용하는데는 지장이 없을듯 하다. 문제는 다이렉트X SDK인데… 나만 그러는지 모르겠지만 D3DXMatrixDeterminant 를 사용했을때 런타임에러가 발생한다. 그래서 2003 Summer Update로 업데이트를 했는데 일단 위의 문제는 해결됐다. 다만 인테페이스가 바뀐게 좀 있어서 짜증이 난다. -_-;;; 쓰던 코드를 좀 손봐야 할듯하다.

2004년 7월 22일

http://lagoons.net/docdata/Height_2.jpg

위의 화면처럼 나오는데… 여러종류의 텍스쳐를 입히는것도 아주 쉬울듯하다. 그냥 텍스쳐별로 따로따로 인덱스버퍼를 구성하면 되니… 그런데 그렇게 할려면 맵의 파일 포멧이 좀 바껴야 할태고 그럴려면 이왕에 전용 에디터를 만드는쪽이 좆타… 라는 결론이 나와서 -_-;;; 좀 귀찮다. 일단 위의 하이트맵을 랜더링하는 코드를 보면

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값을 자동 생성해서 텍스쳐를 입히는 것이다.

자 그럼 다음은 맵에디터다 -_-

2.1 Texture Matrix Reference #

  • http://myevan.net/
    에서 texture matrix 로 검색을 한뒤 링크지식/여치님의 하드웨어가속 타일링 을 찾아보면 있다.
  • 댓글 남기기

    이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다