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

📄 terrain.cpp

📁 game programing code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//					the generated texture map does not look incredibly blocky
// Arguments:		-x, z: coordinates to get the height at
//					-fHeightToTexRatio: Height map size to texture 
//										map size ratio
// Return Value:	An unsigned char value: the interpolated height
//--------------------------------------------------------------
unsigned char CTERRAIN::InterpolateHeight( int x, int z, float fHeightToTexRatio )
{
	unsigned char ucLow, ucHighX, ucHighZ;
	float ucX, ucZ;
	float fScaledX= x*fHeightToTexRatio;
	float fScaledZ= z*fHeightToTexRatio;
	float fInterpolation;

	//set the middle boundary
	ucLow= GetTrueHeightAtPoint( ( int )fScaledX, ( int )fScaledZ );

	//start off by interpolating along the X axis
	//set the high boundary
	if( ( fScaledX+1 )>m_iSize )
		return ucLow;
	else
		ucHighX= GetTrueHeightAtPoint( ( int )fScaledX+1, ( int )fScaledZ );

	//calculate the interpolation (for the X axis)
	fInterpolation= ( fScaledX-( int )fScaledX );
	ucX= ( ( ucHighX-ucLow )*fInterpolation )+ucLow;

	//interpolate along the Z axis now
	//set the high boundary
	if( ( fScaledZ+1 )>m_iSize )
		return ucLow;
	else
		ucHighZ= GetTrueHeightAtPoint( ( int )fScaledX, ( int )fScaledZ+1 );

	//calculate the interpolation (for the Z axis)
	fInterpolation= ( fScaledZ-( int )fScaledZ );
	ucZ= ( ( ucHighZ-ucLow )*fInterpolation )+ucLow;

	//calculate the overall interpolation (average of the two values)
	return ( ( unsigned char )( ( ucX+ucZ )/2 ) );
}

//--------------------------------------------------------------
// Name:			CTERRAIN::GenerateTextureMap - public
// Description:		Generate a texture map from the four tiles (that must
//					be loaded before this function is called)
// Arguments:		-uiSize: the size of the texture map to be generated
// Return Value:	None
//--------------------------------------------------------------
void CTERRAIN::GenerateTextureMap( unsigned int uiSize )
{
	unsigned char ucRed, ucGreen, ucBlue;
	unsigned int iTempID;
	unsigned int x, z;
	unsigned int uiTexX, uiTexZ;
	float fTotalRed, fTotalGreen, fTotalBlue;
	float fBlend[4];
	float fMapRatio;
	int iLastHeight;
	int i;

	//find out the number of tiles that we have
	m_tiles.iNumTiles= 0;
	for( i=0; i<TRN_NUM_TILES; i++ )
	{
		//if the current tile is loaded, then we add one to the total tile count
		if( m_tiles.textureTiles[i].IsLoaded( ) )
			m_tiles.iNumTiles++;
	}

	//now, re-loop through, and calculate the texture regions
	iLastHeight= -1;
	for( i=0; i<TRN_NUM_TILES; i++ )
	{
		//we only want to perform these calculations if we actually have a tile loaded
		if( m_tiles.textureTiles[i].IsLoaded( ) )
		{
			//calculate the three height boundaries
			m_tiles.m_regions[i].m_iLowHeight= iLastHeight+1;
			iLastHeight+= 255/m_tiles.iNumTiles;

			m_tiles.m_regions[i].m_iOptimalHeight= iLastHeight;

			m_tiles.m_regions[i].m_iHighHeight= ( iLastHeight-m_tiles.m_regions[i].m_iLowHeight )+iLastHeight;
		}
	}

	//create room for a new texture
	m_texture.Create( uiSize, uiSize, 24 );

	//get the height map to texture map ratio (since, most of the time,
	//the texture map will be a higher resolution than the height map, so
	//we need the ratio of height map pixels to texture map pixels)
	fMapRatio= ( float )m_iSize/uiSize;

	//time to create the texture data
	for( z=0; z<uiSize; z++ )
	{
		for( x=0; x<uiSize; x++ )
		{
			//set our total color counters to 0.0f
			fTotalRed  = 0.0f;
			fTotalGreen= 0.0f;
			fTotalBlue = 0.0f;

			//loop through the tiles (for the third time in this function!)
			for( i=0; i<TRN_NUM_TILES; i++ )
			{
				//if the tile is loaded, we can do the calculations
				if( m_tiles.textureTiles[i].IsLoaded( ) )
				{
					uiTexX= x;
					uiTexZ= z;

					//get texture coordinates
					GetTexCoords( m_tiles.textureTiles[i], &uiTexX, &uiTexZ );

					//get the current color in the texture at the coordinates that we got
					//in GetTexCoords
					m_tiles.textureTiles[i].GetColor( uiTexX, uiTexZ, &ucRed, &ucGreen, &ucBlue );

					//get the current coordinate's blending percentage for this tile
					fBlend[i]= RegionPercent( i, Limit( InterpolateHeight( x, z, fMapRatio ) ) );

					//calculate the RGB values that will be used
					fTotalRed  += ucRed*fBlend[i];
					fTotalGreen+= ucGreen*fBlend[i];
					fTotalBlue += ucBlue*fBlend[i];
				}
			}			

			//set our terrain's texture color to the one that we previously calculated
			m_texture.SetColor( x, z, Limit( ( unsigned char )fTotalRed ),
									  Limit( ( unsigned char )fTotalGreen ),
									  Limit( ( unsigned char )fTotalBlue ) );
		}
	}

	//build the OpenGL texture
	glGenTextures( 1, &iTempID );
	glBindTexture( GL_TEXTURE_2D, iTempID );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );						

	//make the texture
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, uiSize, uiSize, 0, GL_RGB, GL_UNSIGNED_BYTE, m_texture.GetData( ) );

	//set the texture's ID
	m_texture.SetID( iTempID );
}

//--------------------------------------------------------------
// Name:			CTERRAIN::LoadLightMap - public
// Description:		Load a grayscale RAW light map
// Arguments:		-szFilename: the file name of the light map
//					-im_iSize: the m_iSize (power of 2) of the map
// Return Value:	A boolean value: -true: successful load
//									 -false: unsuccessful load
//--------------------------------------------------------------
bool CTERRAIN::LoadLightMap( char* szFilename, int iSize )
{
	FILE* pFile;

	//check to see if the data has been set
	if( m_lightmap.m_ucpData )
		UnloadLightMap( );

	//open the RAW lightmap
	pFile= fopen( szFilename, "rb" );
	if( pFile==NULL )
	{
		//bad filename
		g_log.Write( LOG_FAILURE, "Could not load %s\n", szFilename );
		return false;
	}

	//allocate the memory for our lightmap
	m_lightmap.m_ucpData= new unsigned char [iSize*iSize];

	//check to see if memory was successfully allocated
	if( m_lightmap.m_ucpData==NULL )
	{
        //the memory could not be allocated something is seriously wrong here
		g_log.Write( LOG_FAILURE, "Could not allocate memory for%s\n", szFilename );
		return false;
	}

	//read the lightmap into context
	fread( m_lightmap.m_ucpData, 1, iSize*iSize, pFile );
	
	//Close the file
	fclose( pFile );

	//set the m_iSize data
	m_lightmap.m_iSize= iSize;

	//WOOHOO! The lightmap has been successfully loaded
	g_log.Write( LOG_SUCCESS, "Loaded %s\n", szFilename );
	return true;
}

//--------------------------------------------------------------
// Name:			CTERRAIN::SaveLightMap - public
// Description:		Save a grayscale RAW light map to a file
// Arguments:		-szFilename: the filename of the light map
// Return Value:	A boolean value: -true: successful save
//									 -false: unsuccessful save
//--------------------------------------------------------------
bool CTERRAIN::SaveLightMap( char* szFilename )
{
	FILE* pFile;

	//open a file for the RAW lightmap to be saved to
	pFile= fopen( szFilename, "wb" );
	if( pFile==NULL )
	{
		//could not open the file for writing
		g_log.Write( LOG_FAILURE, "Could not create %s\n", szFilename );
		return false;
	}

	//check to see if we have data to actually write to a file
	if( m_lightmap.m_ucpData==NULL )
	{
		//something is seriously wrong here
		g_log.Write( LOG_FAILURE, "The height data buffer for %s is empty\n", szFilename );
		return false;
	}

	//write the lightmap to the file
	fwrite( m_lightmap.m_ucpData, 1, m_lightmap.m_iSize*m_lightmap.m_iSize, pFile );
	
	//close the file
	fclose( pFile );

	//yahoo! The lightmap has been successfully written
	g_log.Write( LOG_SUCCESS, "Saved %s\n", szFilename );
	return true;
}

//--------------------------------------------------------------
// Name:			CTERRAIN::UnloadLightMap - public
// Description:		Unload the class's light map (if there is one)
// Arguments:		None
// Return Value:	None
//--------------------------------------------------------------
void CTERRAIN::UnloadLightMap( void )
{
	//check to see if the data has been set
	if( m_lightmap.m_ucpData )
	{
		//delete the data
		delete[] m_lightmap.m_ucpData;

		//reset the map dimensions also
		m_iSize= 0;
	}

	//the height map has been unloaded
	g_log.Write( LOG_SUCCESS, "Successfully unloaded the light map\n" );
}

//--------------------------------------------------------------
// Name:			CTERRAIN::CalculateLighting - public
// Description:		Calculates lighting for the pre-set technique, and
//					stores all computations in a lightmap
// Arguments:		None
// Return Value:	None
//--------------------------------------------------------------
void CTERRAIN::CalculateLighting( void )
{
	float fShade;
	int x, z;

	//a lightmap has already been provided, no need to create one :)
	if( m_lightingType==LIGHTMAP )
		return;

	//allocate memory if it is needed
	if( m_lightmap.m_iSize!=m_iSize || m_lightmap.m_ucpData==NULL )
	{
		//delete the memory for the old data
		delete[] m_lightmap.m_ucpData;

		//allocate memory for the new lightmap data buffer
		m_lightmap.m_ucpData= new unsigned char [m_iSize*m_iSize];
		m_lightmap.m_iSize= m_iSize;
	}

	//loop through all vertices
	for( z=0; z<m_iSize; z++ )
	{
		for( x=0; x<m_iSize; x++ )
		{
			//using height-based lighting, trivial
			if( m_lightingType==HEIGHT_BASED )
				SetBrightnessAtPoint( x, z, GetTrueHeightAtPoint( x, z ) );

			//using the slope-lighting technique
			else if( m_lightingType==SLOPE_LIGHT )
			{
				//ensure that we won't be stepping over array boundaries by doing this
				if( z>=m_iDirectionZ && x>=m_iDirectionX )
				{
					//calculate the shading value using the "slope lighting" algorithm
					fShade= 1.0f-( GetTrueHeightAtPoint( x-m_iDirectionX, z-m_iDirectionZ ) - 
								   GetTrueHeightAtPoint( x, z ) )/m_fLightSoftness;
				}

				//if we are, then just return a very bright color value (white)
				else
					fShade= 1.0f;

				//clamp the shading value to the min/max brightness boundaries
				if( fShade<m_fMinBrightness )
					fShade= m_fMinBrightness;
				if( fShade>m_fMaxBrightness )
					fShade= m_fMaxBrightness;

				//set the new brightness for our lightmap
				SetBrightnessAtPoint( x, z, ( unsigned char )( fShade*255 ) );
			}
		}
	}
}

⌨️ 快捷键说明

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