예제 #1
0
//--------------------------------------------------------------
// Name:			CGEOMIPMAPPING::RenderPatch - private
// Description:		Render a patch of terrain
// Arguments:		-PX, PZ: the patch location
//					-bMultitex: use multitexturing or not
//					-bDetail: render with a detail map or not
// Return Value:	None
//--------------------------------------------------------------
void CGEOMIPMAPPING::RenderPatch( int PX, int PZ, bool bMultiTex, bool bDetail )
{
	SGEOMM_NEIGHBOR patchNeighbor;
	SGEOMM_NEIGHBOR fanNeighbor;
	float fSize;
	float fHalfSize;
	float x, z;
	int iPatch= GetPatchNumber( PX, PZ );
	int iDivisor;
	int iLOD;

	//find out information about the patch to the current patch's left, if the patch is of a
	//greater detail or there is no patch to the left, we can render the mid-left vertex
	if( m_pPatches[GetPatchNumber( PX-1, PZ )].m_iLOD<=m_pPatches[iPatch].m_iLOD || PX==0 )
		patchNeighbor.m_bLeft= true;
	else
		patchNeighbor.m_bLeft= false;

	//find out about the upper patch
	if( m_pPatches[GetPatchNumber( PX, PZ+1 )].m_iLOD<=m_pPatches[iPatch].m_iLOD || PZ==m_iNumPatchesPerSide )
		patchNeighbor.m_bUp= true;
	else
		patchNeighbor.m_bUp= false;

	//find out about the right patch
	if( m_pPatches[GetPatchNumber( PX+1, PZ )].m_iLOD<=m_pPatches[iPatch].m_iLOD || PX==m_iNumPatchesPerSide )
		patchNeighbor.m_bRight= true;
	else
		patchNeighbor.m_bRight= false;

	//find out about the lower patch
	if( m_pPatches[GetPatchNumber( PX, PZ-1 )].m_iLOD<=m_pPatches[iPatch].m_iLOD || PZ==0 )
		patchNeighbor.m_bDown= true;
	else
		patchNeighbor.m_bDown= false;

	//we need to determine the distance between each triangle-fan that
	//we will be rendering
	iLOD    = m_pPatches[GetPatchNumber( PX, PZ )].m_iLOD+1;
	fSize   = ( float )m_iPatchSize;
	iDivisor= m_iPatchSize-1;

	//find out how many fan divisions we are going to have
	while( --iLOD>-1 )
		iDivisor= iDivisor>>1;

	//the size between the center of each triangle fan
	fSize/= iDivisor;

	//half the size between the center of each triangle fan (this will be
	//the size between each vertex)
	fHalfSize= fSize/2.0f;
	for( z=fHalfSize; ( ( int )( z+fHalfSize ) )<m_iPatchSize+1; z+=fSize )
	{
		for( x=fHalfSize; ( ( int )( x+fHalfSize ))<m_iPatchSize+1; x+=fSize )
		{
			//if this fan is in the left row, we may need to adjust it's rendering to
			//prevent cracks
			if( x==fHalfSize )
				fanNeighbor.m_bLeft= patchNeighbor.m_bLeft;
			else
				fanNeighbor.m_bLeft= true;

			//if this fan is in the bottom row, we may need to adjust it's rendering to
			//prevent cracks
			if( z==fHalfSize )
				fanNeighbor.m_bDown= patchNeighbor.m_bDown;
			else
				fanNeighbor.m_bDown= true;

			//if this fan is in the right row, we may need to adjust it's rendering to
			//prevent cracks
			if( x>=( m_iPatchSize-fHalfSize ) )
				fanNeighbor.m_bRight= patchNeighbor.m_bRight;
			else
				fanNeighbor.m_bRight= true;

			//if this fan is in the top row, we may need to adjust it's rendering to
			//prevent cracks
			if( z>=( m_iPatchSize-fHalfSize ) )
				fanNeighbor.m_bUp= patchNeighbor.m_bUp;
			else
				fanNeighbor.m_bUp= true;

			//render the triangle fan
			RenderFan( ( PX*m_iPatchSize )+x, ( PZ*m_iPatchSize )+z,
					   fSize, fanNeighbor, bMultiTex, bDetail );
		}
	}
}
예제 #2
0
void GeoMipMapping::RenderPatch(int px, int pz)
{
	SGEOMM_NEIGHBOR patchNeighbor;
	SGEOMM_NEIGHBOR fanNeighbor;

	float fSize = 0.0f;
	float fHalfSize = 0.0f;
	float z, x;
	int iPatch = GetPatchNumber(px, pz);
	int iDivisor = 0;
	int iLOD = 0;

	//左边的比较精细,所以不用管,直接可以绘制
	if (m_pPatches[GetPatchNumber(px - 1, pz)].m_iLOD <= m_pPatches[iPatch].m_iLOD || px == 0)
		patchNeighbor.m_bLeft = true;  //可以绘制
	else
		patchNeighbor.m_bLeft = false; //不能绘制

	if (m_pPatches[GetPatchNumber(px, pz + 1)].m_iLOD <= m_pPatches[iPatch].m_iLOD || pz == m_iNumPatchesPerSide)
		patchNeighbor.m_bUp = true;
	else
		patchNeighbor.m_bUp = false;

	if (m_pPatches[GetPatchNumber(px + 1, pz)].m_iLOD <= m_pPatches[iPatch].m_iLOD || px == m_iNumPatchesPerSide)
		patchNeighbor.m_bRight = true;
	else
		patchNeighbor.m_bRight = false;

	if (m_pPatches[GetPatchNumber(px, pz - 1)].m_iLOD <= m_pPatches[iPatch].m_iLOD || pz == 0)
		patchNeighbor.m_bBottom = true;
	else
		patchNeighbor.m_bBottom = false;

	fSize = (float)m_iPatchSize;
	iDivisor = m_iPatchSize - 1;
	iLOD = m_pPatches[iPatch].m_iLOD;

	while (iLOD-- >= 0)
		iDivisor >>= 1;

	fSize /= iDivisor;
	
	fHalfSize = fSize / 2.0f;

	for (z = fHalfSize; ((int)z + fHalfSize ) < m_iPatchSize + 1; z += fSize)
	{
		for (x = fHalfSize; ((int)x + fHalfSize) < m_iPatchSize + 1; x += fSize)
		{
			if (x == fHalfSize)
				fanNeighbor.m_bLeft = patchNeighbor.m_bLeft;
			else
				fanNeighbor.m_bLeft = true;

			if (z == fHalfSize)
				fanNeighbor.m_bBottom = patchNeighbor.m_bBottom;
			else
				fanNeighbor.m_bBottom = true;

			if (x >= (m_iPatchSize - fHalfSize))
				fanNeighbor.m_bRight = patchNeighbor.m_bRight;
			else
				fanNeighbor.m_bRight = true;

			if (z >= (m_iPatchSize - fHalfSize))
				fanNeighbor.m_bUp = patchNeighbor.m_bUp;
			else
				fanNeighbor.m_bUp = true;

			RenderFan((px * m_iPatchSize) + x, (pz * m_iPatchSize) + z, 
				fSize, fanNeighbor);
		}
	}
}