⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleterrain.cpp

📁 游戏编程精粹2第四章源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			x= -VERTEX_COUNT/2.0f;
		}

		// unlock the height map
		m_pHeightData->UnlockRect();



		// now create the vertex buffers from the global vertex data
		int center_vertex = TILE_VERTS>>1;
		for (i=0;i<TILE_COUNT;++i)
		{
			int verty = i*(TILE_VERTS-1);

			for (j=0;j<TILE_COUNT;++j)
			{
				int vertx = j*(TILE_VERTS-1);

				// create a vertex buffer for this tile
				m_TerrainTile[i][j].DetailLevel = LEVEL_0;
				m_TerrainTile[i][j].VBuffer = 0;

				if (SUCCEEDED(m_pd3dDevice->CreateVertexBuffer(sizeof(TERRAIN_VERTEX)*TILE_VERTS*TILE_VERTS, D3DUSAGE_WRITEONLY, FVF, D3DPOOL_MANAGED, &m_TerrainTile[i][j].VBuffer)))
				{
					TERRAIN_VERTEX *pData;

					if (SUCCEEDED(m_TerrainTile[i][j].VBuffer->Lock(0,0, (BYTE**)&pData, D3DLOCK_NOSYSLOCK)))
					{
						for (int y=0;y<TILE_VERTS;++y)
						{
							for (int x=0;x<TILE_VERTS;++x)
							{
								// if this is the center of the tile, store it for distance checking
								if (y==center_vertex && x==center_vertex)
								{
									m_TerrainTile[i][j].Center = TerrainVerts[vertx+x][verty+y].vert;
								}

								// copy the vertex to our buffer
								memcpy(pData, &TerrainVerts[vertx+x][verty+y], sizeof(TERRAIN_VERTEX));
								++pData;
							}
						}
						m_TerrainTile[i][j].VBuffer->Unlock();
					}
				}
			}
		}
	}
}


void SimpleTerrain::GenerateDetailLevels()
{
	//
	// Generate Tile Bodies and Connectors for our 4 sample detail levels
	//

	//
	// Detail Level 0 (lowest detail level)
	//

	m_DetailLevel[0].TileBodies[0].pIndexBuffer=0;
	if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(6*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[0].TileBodies[0].pIndexBuffer)))
	{
		WORD* pIndex;
		if (SUCCEEDED(m_DetailLevel[0].TileBodies[0].pIndexBuffer->Lock(0,6*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
		{
			pIndex[0] = BaseTile0[0];
			pIndex[1] = BaseTile0[1];
			pIndex[2] = BaseTile0[2];
			pIndex[3] = BaseTile0[3];
			pIndex[4] = BaseTile0[4];
			pIndex[5] = BaseTile0[5];

			m_DetailLevel[0].TileBodies[0].pIndexBuffer->Unlock();
			m_DetailLevel[0].TileBodies[0].IndexCount = 6;
			m_DetailLevel[0].TileBodies[0].TriangleCount = 2;
		}
	}

	//
	// Detail Level 1
	//

	// create each of the 16 tile bodies
	for (int body=0;body<16;++body)
	{
		m_DetailLevel[1].TileBodies[body].pIndexBuffer=0;
		m_DetailLevel[1].TileBodies[body].IndexCount = 0;

		int total_indexes=0;
		if (!(body & (1<<0))) total_indexes += 6;
		if (!(body & (1<<1))) total_indexes += 6;
		if (!(body & (1<<2))) total_indexes += 6;
		if (!(body & (1<<3))) total_indexes += 6;

		if (total_indexes)
		{
			if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(total_indexes*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[1].TileBodies[body].pIndexBuffer)))
			{
				WORD* pIndex;
				if (SUCCEEDED(m_DetailLevel[1].TileBodies[body].pIndexBuffer->Lock(0,total_indexes*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
				{
					int index=0;

					for (int side=0;side<TOTAL_SIDES;++side)
					{
						if (!(body & (1<<side)))
						{
							for (int data=0;data<6;++data)
							{
								pIndex[index++] = SidesOfLevel1[side][data];
							}
						}
					}
					m_DetailLevel[1].TileBodies[body].pIndexBuffer->Unlock();
					m_DetailLevel[1].TileBodies[body].IndexCount = total_indexes;
					m_DetailLevel[1].TileBodies[body].TriangleCount = total_indexes/3;
				}
			}
		}
	}

	// create the tile connectors
	for (int side=0;side<TOTAL_SIDES;++side)
	{
		m_DetailLevel[1].TileConnectors[side][0].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(3*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[1].TileConnectors[side][0].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[1].TileConnectors[side][0].pIndexBuffer->Lock(0,3*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<3;++count)
				{
					pIndex[count] = Connect1to0[side][count];
				}
				m_DetailLevel[1].TileConnectors[side][0].pIndexBuffer->Unlock();
				m_DetailLevel[1].TileConnectors[side][0].IndexCount = 3;
				m_DetailLevel[1].TileConnectors[side][0].TriangleCount = 1;
			}
		}
	}

	//
	// Detail Level 2
	//

	// create each of the 16 tile bodies
	for (body=0;body<16;++body)
	{
		m_DetailLevel[2].TileBodies[body].pIndexBuffer=0;
		m_DetailLevel[2].TileBodies[body].IndexCount = 0;

		int total_indexes=24;
		if (!(body & (1<<0))) total_indexes += 18;
		if (!(body & (1<<1))) total_indexes += 18;
		if (!(body & (1<<2))) total_indexes += 18;
		if (!(body & (1<<3))) total_indexes += 18;

		if (total_indexes)
		{
			if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(total_indexes*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[2].TileBodies[body].pIndexBuffer)))
			{
				WORD* pIndex;
				if (SUCCEEDED(m_DetailLevel[2].TileBodies[body].pIndexBuffer->Lock(0,total_indexes*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
				{
					int index=0;

					// start by copying the center portion of the tile
					for (int center_vert=0;center_vert<24;++center_vert)
					{
						pIndex[index++] = Level2_Center[center_vert];
					}

					for (int side=0;side<TOTAL_SIDES;++side)
					{
						if (!(body & (1<<side)))
						{
							for (int data=0;data<18;++data)
							{
								pIndex[index++] = SidesOfLevel2[side][data];
							}
						}
					}
					m_DetailLevel[2].TileBodies[body].pIndexBuffer->Unlock();
					m_DetailLevel[2].TileBodies[body].IndexCount = total_indexes;
					m_DetailLevel[2].TileBodies[body].TriangleCount = total_indexes/3;
				}
			}
		}
	}

	// create the tile connectors
	for (side=0;side<TOTAL_SIDES;++side)
	{
		// connections to detail level 0
		m_DetailLevel[2].TileConnectors[side][0].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(9*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[2].TileConnectors[side][0].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[2].TileConnectors[side][0].pIndexBuffer->Lock(0,9*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<9;++count)
				{
					pIndex[count] = Connect2to0[side][count];
				}
				m_DetailLevel[2].TileConnectors[side][0].pIndexBuffer->Unlock();
				m_DetailLevel[2].TileConnectors[side][0].IndexCount = 9;
				m_DetailLevel[2].TileConnectors[side][0].TriangleCount = 3;
			}
		}

		// connections to detail level 1
		m_DetailLevel[2].TileConnectors[side][1].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(12*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[2].TileConnectors[side][1].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[2].TileConnectors[side][1].pIndexBuffer->Lock(0,12*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<12;++count)
				{
					pIndex[count] = Connect2to1[side][count];
				}
				m_DetailLevel[2].TileConnectors[side][1].pIndexBuffer->Unlock();
				m_DetailLevel[2].TileConnectors[side][1].IndexCount = 12;
				m_DetailLevel[2].TileConnectors[side][1].TriangleCount = 4;
			}
		}
	}

	//
	// Detail Level 3
	//

	// create each of the 16 tile bodies
	for (body=0;body<16;++body)
	{
		m_DetailLevel[3].TileBodies[body].pIndexBuffer=0;
		m_DetailLevel[3].TileBodies[body].IndexCount = 0;

		int total_indexes=216;
		if (!(body & (1<<0))) total_indexes += 42;
		if (!(body & (1<<1))) total_indexes += 42;
		if (!(body & (1<<2))) total_indexes += 42;
		if (!(body & (1<<3))) total_indexes += 42;

		if (total_indexes)
		{
			if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(total_indexes*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[3].TileBodies[body].pIndexBuffer)))
			{
				WORD* pIndex;
				if (SUCCEEDED(m_DetailLevel[3].TileBodies[body].pIndexBuffer->Lock(0,total_indexes*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
				{
					int index=0;

					// start by copying the center portion of the tile
					for (int center_vert=0;center_vert<216;++center_vert)
					{
						pIndex[index++] = Level3_Center[center_vert];
					}

					for (int side=0;side<TOTAL_SIDES;++side)
					{
						if (!(body & (1<<side)))
						{
							for (int data=0;data<42;++data)
							{
								pIndex[index++] = SidesOfLevel3[side][data];
							}
						}
					}
					m_DetailLevel[3].TileBodies[body].pIndexBuffer->Unlock();
					m_DetailLevel[3].TileBodies[body].IndexCount = total_indexes;
					m_DetailLevel[3].TileBodies[body].TriangleCount = total_indexes/3;
				}
			}
		}
	}

	// create the tile connectors
	for (side=0;side<TOTAL_SIDES;++side)
	{
		// connections to detail level 0
		m_DetailLevel[3].TileConnectors[side][0].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(21*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[3].TileConnectors[side][0].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[3].TileConnectors[side][0].pIndexBuffer->Lock(0,21*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<21;++count)
				{
					pIndex[count] = Connect3to0[side][count];
				}
				m_DetailLevel[3].TileConnectors[side][0].pIndexBuffer->Unlock();
				m_DetailLevel[3].TileConnectors[side][0].IndexCount = 21;
				m_DetailLevel[3].TileConnectors[side][0].TriangleCount = 7;
			}
		}

		// connections to detail level 1
		m_DetailLevel[3].TileConnectors[side][1].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(24*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[3].TileConnectors[side][1].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[3].TileConnectors[side][1].pIndexBuffer->Lock(0,24*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<24;++count)
				{
					pIndex[count] = Connect3to1[side][count];
				}
				m_DetailLevel[3].TileConnectors[side][1].pIndexBuffer->Unlock();
				m_DetailLevel[3].TileConnectors[side][1].IndexCount = 24;
				m_DetailLevel[3].TileConnectors[side][1].TriangleCount = 8;
			}
		}

		// connections to detail level 2
		m_DetailLevel[3].TileConnectors[side][2].pIndexBuffer = 0;
		if (SUCCEEDED(m_pd3dDevice->CreateIndexBuffer(30*2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16 , D3DPOOL_MANAGED, &m_DetailLevel[3].TileConnectors[side][2].pIndexBuffer)))
		{
			WORD* pIndex;
			if (SUCCEEDED(m_DetailLevel[3].TileConnectors[side][2].pIndexBuffer->Lock(0,30*2, (BYTE**)&pIndex, D3DLOCK_NOSYSLOCK)))
			{
				int index=0;

				for (int count=0;count<30;++count)
				{
					pIndex[count] = Connect3to2[side][count];
				}
				m_DetailLevel[3].TileConnectors[side][2].pIndexBuffer->Unlock();
				m_DetailLevel[3].TileConnectors[side][2].IndexCount = 30;
				m_DetailLevel[3].TileConnectors[side][2].TriangleCount = 10;
			}
		}
	}
}

//- End of SimpleTerrain -----------------------------------------------------------------
//****************************************************************************************
#endif  // end of file      ( SimpleTerrain.h )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -