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

📄 boidsland.cpp

📁 3D的Boids效果演示源程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*	Filename:		BoidsLand.cpp
	Author:			Robert Platt
	Creation date:	29/08/1999
	Modified:		13/05/2000
	Version:		0.54
	Description:	Implementation file for the boids landscape class.
*/


#include "BoidsWin.h"


// Constructor for the landscape class.
BoidsLand::BoidsLand( )
{
	// Initialise the COM interface pointers.
	landFrame = NULL;

	solidStyle = DEFAULT_LANDSCAPE_SOLID_STYLE;
	solidColour = LSC_GREEN;


	wireframeOn = true;  // Initialize the flags.
	solidOn = false;

	exists = false;  // This will be set by the build function.

	// Call the member function to produce the landscape altitudes.
	calcHeights( );
}


// Build the full landscape using the previously set flags.
void BoidsLand::build( CFrameWnd *win, LPDIRECT3DRM d,
					  LPDIRECT3DRMFRAME s, D3DRMRENDERQUALITY solidStyle )
{
	window = win;
	d3drm = d;  // Store two pointers to the D3D interfaces inside the object.
	scene = s;  // This helps to keep future calls to the object concise.

	// Abort the build if nothing to do.
	if ( solidOn == false && wireframeOn == false )
	{
		return;
	}

	// Calculate the uniform sizes of all the landscape patches.
	xSpacing = X_LIMIT * 2 / LAND_X_SIZE;
	ySpacing = LAND_HEIGHT;
	zSpacing = Z_LIMIT * 2 / LAND_Z_SIZE;


	// Create the main landscape root frame.
	d3drm -> CreateFrame( scene, &landFrame );
	landFrame -> SetPosition( scene, D3DVALUE( 0.0 ),
										D3DVALUE( 0.0 ), D3DVALUE( 0.0 ) );

	// Create the landscape mesh.
	d3drm -> CreateMesh( &landMesh );


	// Used for producing each patch of land.
	D3DRMVERTEX patchVertices[ 6 ];
	unsigned vertOrder[] = { 0, 1, 2, 3, 4, 5 };


	// Generate the surface for the landMesh.
	for ( int row = 0; row < LAND_Z_SIZE; row++ )
	{
		for ( int col = 0; col < LAND_X_SIZE; col++ )
		{
			// Create the solid representation if required.
			if ( solidOn )
			{
				landMesh -> AddGroup( 6, 2, 3, vertOrder,
										&patchGroups[ 0 ][ row ][ col ] );
			}

			// Create the wireframe overlay if required.
			if ( wireframeOn )
			{
				landMesh -> AddGroup( 6, 2, 3, vertOrder,
										&patchGroups[ 1 ][ row ][ col ] );
			}


			// Call the auxillary function to position the land patch.
			positionPatch( patchVertices, row, col );


			// Apply flat shading to the patch of land.
			if ( solidOn )
			{
				flatShading( row, col, patchVertices );
			}


			// Complete the production of the patch of -
			// - land for solid representation.
			if ( solidOn )
			{
				landMesh -> SetVertices( patchGroups[ 0 ][ row ][ col ],
													0, 6, patchVertices );
				landMesh -> SetGroupQuality(
							patchGroups[ 0 ][ row ][ col ], solidStyle );


				// Set the landscape's colours.
				// Colour the central tower brown.
				if ( row == 4 && col == 4 )
				{
					// Brown.
					landMesh -> SetGroupColor(
								patchGroups[ 0 ][ row ][ col ], RGB_BROWN );
				}
				else  // Colour the land.
				{
					if  ( solidColour == LSC_CHECKERED )
					{
						// Colour the land checkered style.
						if ( row % 2 == 0 )
						{
							if ( col % 2 == 0 )
							{
								// Black.
								landMesh -> SetGroupColor(
									patchGroups[ 0 ][ row ][ col ], RGB_BLACK );
							}
							else
							{
								// White.
								landMesh -> SetGroupColor(
									patchGroups[ 0 ][ row ][ col ], RGB_WHITE );
							}
						}
						else
						{
							if ( col % 2 == 0 )
							{
								// White.
								landMesh -> SetGroupColor(
									patchGroups[ 0 ][ row ][ col ], RGB_WHITE );
							}
							else
							{
								// Black.
								landMesh -> SetGroupColor(
									patchGroups[ 0 ][ row ][ col ], RGB_BLACK );
							}
						}
					}

					if  ( solidColour == LSC_GREEN )
					{
						// Colour the land green.
						landMesh -> SetGroupColor(
							patchGroups[ 0 ][ row ][ col ], RGB_LAND_GREEN );
					}
				}
			}


			if ( wireframeOn )
			{
				// Complete the production of the patch of land.
				landMesh -> SetVertices( patchGroups[ 1 ][ row ][ col ],
														0, 6, patchVertices );
				landMesh -> SetGroupQuality( patchGroups[ 1 ][ row ][ col ],
													D3DRMRENDER_WIREFRAME );
				// Set the wireframe landscape colour.
				if ( solidOn )
				{
					// Black.
					landMesh -> SetGroupColor(
								patchGroups[ 1 ][ row ][ col ], RGB_BLACK );
				}
				else
				{
					// If there is no solid land, colour -
					// - the wireframe black for clarity.
					// Black.
					landMesh -> SetGroupColor(
								patchGroups[ 1 ][ row ][ col ], RGB_BLACK );
				}

			}

			// If the patch of land was a tower, add the sides of the tower.
			if ( row == 4 && col == 4 )
			{
				buildTowerSides( row, col );
			}
		}
	}


	// Add the land to the land frame.
	landFrame -> AddVisual(	landMesh );

	// Apply gouraud shading to the landscape if selected.
	if ( solidStyle == D3DRMRENDER_GOURAUD && solidOn )
	{
		gouraudShading( );
	}

	exists = true;  // Set the flag.
}


// Auxillary function to set the position of a patch of land.
void BoidsLand::positionPatch( D3DRMVERTEX vertices[ ], int r, int c )
{
	// Set the vertices for the patch of land.
	// First triangle.
	//////////////////////////////////
	// South west corner vertex <0>.
	//////////////////////////////////
	vertices[ 0 ].position.x = c * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 0 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 0 ].position.y = landHeights[ r ][ c ]
												* ySpacing - Y_LIMIT;
	}
	vertices[ 0 ].position.z = r * zSpacing - Z_LIMIT;


	//////////////////////////////////
	// North west corner vertex <1>.
	//////////////////////////////////
	vertices[ 1 ].position.x = c * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 1 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 1 ].position.y = landHeights[ r + 1 ][ c ] *
													ySpacing - Y_LIMIT;
	}
	vertices[ 1 ].position.z = ( r + 1 ) * zSpacing - Z_LIMIT;


	//////////////////////////////////
	// North east corner vertex <2>.
	//////////////////////////////////
	vertices[ 2 ].position.x = ( c + 1 ) * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 2 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 2 ].position.y = landHeights[ r + 1 ][ c + 1 ] *
														ySpacing - Y_LIMIT;
	}
	vertices[ 2 ].position.z = ( r + 1 ) * zSpacing - Z_LIMIT;



	// Second triangle.
	//////////////////////////////////
	// South west corner vertex <3>.
	//////////////////////////////////
	vertices[ 3 ].position.x = c * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 3 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 3 ].position.y = landHeights[ r ][ c ]
												* ySpacing - Y_LIMIT;
	}
	vertices[ 3 ].position.z = r * zSpacing - Z_LIMIT;


	//////////////////////////////////
	// North east corner vertex <4>.
	//////////////////////////////////
	vertices[ 4 ].position.x = ( c + 1 ) * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 4 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 4 ].position.y = landHeights[ r + 1 ][ c + 1 ] *
														ySpacing - Y_LIMIT;
	}
	vertices[ 4 ].position.z = ( r + 1 ) * zSpacing - Z_LIMIT;


	//////////////////////////////////
	// South east corner vertex <5>.
	//////////////////////////////////
	vertices[ 5 ].position.x = ( c + 1 ) * xSpacing - X_LIMIT;
	// If the patch of land is a tower.
	if ( r == 4 && c == 4 )
	{
		// Raise the height of the vertex to the top of the tower.
		vertices[ 5 ].position.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
	}
	else
	{
		// Just keep the normal height.
		vertices[ 5 ].position.y = landHeights[ r ][ c + 1 ] *
													ySpacing - Y_LIMIT;
	}
	vertices[ 5 ].position.z = r * zSpacing - Z_LIMIT;
}


// Build the faces for the sides of a tower.
void BoidsLand::buildTowerSides( int row, int col )
{
	unsigned vertOrder[] = { 0, 1, 2, 3, 4, 5 };
	D3DRMVERTEX towerVertices[ 6 ];


	for ( int side = 0; side <= 3; side++ )
	{
		// Create the solid representation if required.
		if ( solidOn )
		{
			landMesh -> AddGroup( 6, 2, 3, vertOrder,
											&towerGroups[ 0 ][ side ] );
		}

		// Create the wireframe overlay if required.
		if ( wireframeOn )
		{
			landMesh -> AddGroup( 6, 2, 3, vertOrder,
											&towerGroups[ 1 ][ side ] );
		}


		// Set the vertices for the patch of land.
		D3DVECTOR	topLeftPoint,
					topRightPoint,
					bottomLeftPoint,
					bottomRightPoint;


		// These values are the same for all the sides.
		topLeftPoint.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;
		topRightPoint.y = TOWER_HEIGHT * ySpacing - Y_LIMIT;


		// The north facing side.
		if ( side == 0 )
		{
			// Define the top left point.
			topLeftPoint.x = col * xSpacing - X_LIMIT;
			topLeftPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;

			// Define the top right point.
			topRightPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			topRightPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;

			// Define the bottom left point.
			bottomLeftPoint.x = col * xSpacing - X_LIMIT;
			bottomLeftPoint.y = landHeights[ row + 1 ][ col ]
											* ySpacing - Y_LIMIT;
			bottomLeftPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;

			// Define the bottom right point.
			bottomRightPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			bottomRightPoint.y = landHeights[ row + 1 ][ col + 1 ]
											* ySpacing - Y_LIMIT;
			bottomRightPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;
		}


		// The east facing side.
		if ( side == 1 )
		{
			// Define the top left point.
			topLeftPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			topLeftPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;

			// Define the top right point.
			topRightPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			topRightPoint.z = row * zSpacing - Z_LIMIT;

			// Define the bottom left point.
			bottomLeftPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			bottomLeftPoint.y = landHeights[ row + 1 ][ col + 1 ]
											* ySpacing - Y_LIMIT;
			bottomLeftPoint.z = ( row + 1 ) * zSpacing - Z_LIMIT;

			// Define the bottom right point.
			bottomRightPoint.x = ( col + 1 ) * xSpacing - X_LIMIT;
			bottomRightPoint.y = landHeights[ row ][ col + 1 ]
											* ySpacing - Y_LIMIT;
			bottomRightPoint.z = row * zSpacing - Z_LIMIT;
		}

⌨️ 快捷键说明

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