Terrain.cpp
资源名称:Direct3D.rar [点击查看]
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:6k
源码类别:
DirextX编程
开发平台:
Visual C++
- #include "zfxd3dUtility.h"
- #include "terrain.h"
- #include ".terrain.h"
- #define MINELEV 0.0f
- CZFXTerrain::CZFXTerrain(void)
- {
- m_iWidth=0;
- m_iHeight=0;
- m_pVB=NULL;
- m_pIB=NULL;
- m_pTexture = NULL;
- }
- CZFXTerrain::~CZFXTerrain(void)
- {
- SAFE_RELEASE(m_pVB);
- SAFE_RELEASE(m_pIB);
- SAFE_RELEASE(m_pTexture);
- }
- bool CZFXTerrain::RenderTerrain( LPDIRECT3DDEVICE9 pd3dDevice, D3DFILLMODE Flag)
- {
- if( NULL == m_pVB )
- {
- MessageBox( NULL, "地形未创建或未成功创建", "渲染地形失败", MB_OK );
- return false;
- }
- // set material
- D3DMATERIAL9 material;
- ZeroMemory( &material, sizeof(D3DMATERIAL9) );
- material.Ambient.r = material.Ambient.g = material.Ambient.b = material.Ambient.a = 1.0f;
- material.Diffuse.r = material.Diffuse.g = material.Diffuse.b = material.Diffuse.a = 1.0f;
- material.Specular.r = material.Specular.g = material.Specular.b = material.Specular.a = 1.0f;
- pd3dDevice->SetMaterial( &material );
- // set lighting
- D3DLIGHT9 light;
- ZeroMemory( &light, sizeof(light) );
- light.Type = D3DLIGHT_DIRECTIONAL;
- light.Diffuse.r = 0.5f;
- light.Diffuse.g = 0.5f;
- light.Diffuse.b = 0.5f;
- light.Diffuse.a = 0.5f;
- light.Direction.x = -3.0f; light.Direction.y = -3.0f; light.Direction.z = 0.0f;
- pd3dDevice->SetLight( 0, &light );
- pd3dDevice->LightEnable( 0, TRUE );
- pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xff444444 );
- // set render state
- pd3dDevice->SetRenderState(D3DRS_FILLMODE, Flag);
- // set texture
- pd3dDevice->SetTexture(0, m_pTexture);
- // Rendering
- pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
- pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) );
- pd3dDevice->SetIndices(m_pIB);
- pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
- 0, // BaseVertexIndex
- 0, // MinIndex
- m_iWidth*m_iHeight, // NumVertices
- 0, // StartIndex
- 2*(m_iWidth - 1) * (m_iHeight -1) ); // PrimitiveCount
- return true;
- }
- void CZFXTerrain::OnDestroyDevice()
- {
- SAFE_RELEASE(m_pVB);
- SAFE_RELEASE(m_pIB);
- SAFE_RELEASE(m_pTexture);
- }
- bool CZFXTerrain::CreateTerrain( LPDIRECT3DDEVICE9 pd3dDevice, int iWidth, int iHeight, float fWidth, float fHeight,
- float height[][200], LPCTSTR strTexFileName )
- {
- m_iWidth = iWidth;
- m_iHeight = iHeight;
- // 创建纹理
- if(strTexFileName != NULL)
- {
- if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexFileName, &m_pTexture )))
- {
- m_pTexture = NULL;
- }
- }
- else
- {
- m_pTexture = NULL;
- }
- CUSTOMVERTEX* vertices;
- vertices = new CUSTOMVERTEX[iWidth * iHeight];
- //// 调试用语句
- //float fMin = 100.0f;
- //float fMax = -100.0f;
- //// 调试用语句end
- for(int i=0;i<iHeight;i++)
- {
- for(int j=0;j<iWidth;j++)
- {
- //求出顶点的位置
- float x = (((float)(j-iWidth/2))*fWidth)/(float)iWidth;
- float y = (float)(height[i][j]-MINELEV)/2.0f;
- //// 调试用语句
- //if( y < -20.0f )
- // fMin = y;
- //if( y < fMin )
- // fMin = y;
- //if( y > fMax )
- // fMax = y;
- //// 调试用语句end
- float z = (((float)(i-iHeight/2))*fHeight)/(float)iHeight;
- vertices[i*(iWidth)+j].position = D3DXVECTOR3( x, y, z);
- //确定顶点的颜色
- vertices[i*(iWidth)+j].color = 0xffffffff;
- //求该点的法线向量,两向量叉乘
- // / (i+1,j)
- // ||
- // ||<----(i,j+1)
- // (i,j)
- float deltaHeight1, deltaHeight2;
- if(i<iHeight-1)
- deltaHeight1 = float(height[i][j]-height[i+1][j]);
- else
- deltaHeight1 = float(height[i-1][j]-height[i][j]);
- if(j<iWidth-1)
- deltaHeight2 = float(height[i][j+1]-height[i][j]);
- else
- deltaHeight2 = float(height[i][j]-height[i][j-1]);
- D3DXVECTOR3 vec1( -1.0f, 0.0f, deltaHeight1 );
- D3DXVECTOR3 vec2( 0.0f, 1.0f, deltaHeight2 );
- D3DXVec3Cross( &vertices[i*(iWidth)+j].normal, &vec1, &vec2 );
- // ASSERT(vertices[i*(iHeight+1)+j].normal
- //得到顶点的纹理坐标
- vertices[i*(iWidth)+j].tu = (float)i*20.0f/(float)iWidth;
- vertices[i*(iWidth)+j].tv = (float)j*20.0f/(float)iHeight;
- }
- }
- // WORD的大小仅限于256*256,所以当indices数组中某元素大于256*256时,将发生溢出
- // 相应的,创建索引缓冲的时候,D3DFMT_INDEX16需替换成D3DFMT_INDEX32
- DWORD* indices;
- indices=new DWORD[6*(iWidth-1)*(iHeight-1)];
- int baseIndex = 0;
- for(DWORD i=0;i<(DWORD)iHeight-1;i++)
- {
- for(DWORD j=0;j<(DWORD)iWidth-1;j++)
- {
- indices[baseIndex]=i*(DWORD)iWidth+j;
- indices[baseIndex+1]=(i+1)*(DWORD)iWidth+j;
- indices[baseIndex+2]=(i+1)*(DWORD)iWidth+j+1;
- indices[baseIndex+3]=i*(DWORD)iWidth+j;
- indices[baseIndex+4]=(i+1)*(DWORD)iWidth+j+1;
- indices[baseIndex+5]=i*(DWORD)iWidth+j+1;
- baseIndex+=6;
- }
- }
- if( FAILED( pd3dDevice->CreateIndexBuffer( 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD),
- D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED,
- &m_pIB, NULL ) ) )
- return false;
- if( FAILED( pd3dDevice->CreateVertexBuffer( (iHeight)*(iWidth)*sizeof(CUSTOMVERTEX),
- 0 /*Usage*/, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVB, NULL )))
- return false;
- VOID* pVertices;
- if( FAILED( m_pVB->Lock( 0, (iHeight)*(iWidth)*sizeof( CUSTOMVERTEX ), (void**)&pVertices, 0 ) ) )
- return false;
- memcpy( pVertices, vertices, (iHeight)*(iWidth)*sizeof( CUSTOMVERTEX ) );
- m_pVB->Unlock();
- VOID* pIndices;
- if( FAILED( m_pIB->Lock(
- 0, // Fill from start of the buffer
- 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD),// Size of the data to load
- (void**)&pIndices, // Returned index data
- 0 ) ) ) // Send default flags to the lock
- {
- //SAFE_RELEASE(m_pIB);
- return false;
- }
- memcpy( pIndices, indices, 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD) );
- m_pIB->Unlock();
- delete [] vertices;
- delete [] indices;
- return false;
- }