|
|
一段初始化地面顶点的代码,看了一个小时,看得头发晕,主要是两个for循环(产生螺旋状三角形),请赐教一下.谁能把公式写一下,最好是再稍加讲解.请赐教(作揖).
//-----------------------------------------------------------------------------
// 名称: GenerateTerrain()
// 功能: 初始化用于地面的顶点
//
//-----------------------------------------------------------------------------
struct FOGVERTEX
{
D3DXVECTOR3 p;
D3DXVECTOR3 n;
FLOAT tu, tv;
};
LPDIRECT3DVERTEXBUFFER9 g_pTerrainVB = NULL
#define D3DFVF_FOGVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
GenerateTerrain( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwNumSegments,
FLOAT fScale )
{
HRESULT hr;
g_dwNumTerrainVertices = 2 * dwNumSegments * (dwNumSegments);
// Destroy the old vertex buffer, if any
SAFE_RELEASE( g_pTerrainVB );
// Create a vertex buffer
hr = pd3dDevice->CreateVertexBuffer( g_dwNumTerrainVertices*sizeof(FOGVERTEX),
D3DUSAGE_WRITEONLY, D3DFVF_FOGVERTEX,
D3DPOOL_MANAGED, &g_pTerrainVB ,NULL);
if( FAILED(hr) )
return hr;
FOGVERTEX* pVertices = NULL;
hr = g_pTerrainVB->Lock( 0, g_dwNumTerrainVertices*sizeof(FOGVERTEX),
(void**)&pVertices, 0 );
if( FAILED(hr) )
return hr;
// Generate a spiralized trianglestrip
for( DWORD ring = 0; ring < dwNumSegments; ring++ )
{
for( DWORD seg=0; seg < dwNumSegments; seg++ )
{
FLOAT fTheta = (seg*2*D3DX_PI) / dwNumSegments;
FLOAT r0 = (ring + fTheta/(2*D3DX_PI))*fScale/dwNumSegments;
FLOAT r1 = r0 + fScale/dwNumSegments;
FLOAT x = (FLOAT)sin( fTheta );
FLOAT z = (FLOAT)cos( fTheta );
FLOAT y0 = (FLOAT)sin(r0*z*z+r0*x*x);
FLOAT nx0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*x;
FLOAT ny0 = 1.0f;
FLOAT nz0 = -(FLOAT)cos(r0*z*z+r0*x*x)*r0*2*z;
FLOAT y1 = (FLOAT)sin(r1*z*z+r1*x*x);
FLOAT nx1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*x;
FLOAT ny1 = 1.0f;
FLOAT nz1 = -(FLOAT)cos(r1*z*z+r1*x*x)*r1*2*z;
// Add two vertices to the strip at each step
pVertices->p.x = r0*x;
pVertices->p.y = y0;
pVertices->p.z = r0*z;
pVertices->n.x = nx0;
pVertices->n.y = ny0;
pVertices->n.z = nz0;
pVertices->tu = (r0*x)/fScale;
pVertices->tv = (r0*z)/fScale;
pVertices++;
pVertices->p.x = r1*x;
pVertices->p.y = y1;
pVertices->p.z = r1*z;
pVertices->n.x = nx1;
pVertices->n.y = ny1;
pVertices->n.z = nz1;
pVertices->tu = (r1*x)/fScale;
pVertices->tv = (r1*z)/fScale;
pVertices++;
}
}
g_pTerrainVB->Unlock();
return S_OK;
} |
|