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

📄 vertex.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			else if(psContext->eCurrentPrimType == D3DMPT_LINESTRIP		|| 
					psContext->eCurrentPrimType == D3DMPT_TRIANGLESTRIP ||
					psContext->eCurrentPrimType == D3DMPT_TRIANGLEFAN)
			{
				/* Take the flat shade colour */
				psDst->sDiffuseOut = *psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse;
			}
		}
		else
		{
			/* No lighting, and no diffuse value, so default to All F's (From d3dm spec) */
			psDst->sDiffuseOut.r = D3DM_One;
			psDst->sDiffuseOut.g = D3DM_One;
			psDst->sDiffuseOut.b = D3DM_One;
			psDst->sDiffuseOut.a = D3DM_One;
		}

		if(psVertA->ui32Flags & D3DM_HASFLAG_SPECULAR_COLOR && 
		   psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_SPECULAR)
		{
			/* 
				No lighting, but we've got a specular value and specular is enbled so pass it through.
				Note: Inputs will have been copied to outputs during vertex validation
			*/
			/* 
				If we're flat shading we will just copy the flat shading colours when we output,
				unless we're drawing triangle or line strips, in which case we use flat shade clour
			*/
			if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_FLAT_SHADING)
			{
				if(psContext->eCurrentPrimType == D3DMPT_LINESTRIP		|| 
				   psContext->eCurrentPrimType == D3DMPT_TRIANGLESTRIP  ||
				   psContext->eCurrentPrimType == D3DMPT_TRIANGLEFAN)
				{
					/* Take the flat shade colour */
					psDst->sSpecularOut = *psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular;
				}

				/* We need to interpolate the fog value if there is one */
				if(psVertA->ui32Flags & D3DM_HASFLAG_FOG)
				{
					psDst->sSpecularOut.a =	Add(Mul(T, Sub(psVertA->sSpecularOut.a, psVertB->sSpecularOut.a)), psVertB->sSpecularOut.a);
				}
			}
			else /* Gourad shading requires interpolated colour */
			{
				psDst->sSpecularOut.r =	Add(Mul(T, Sub(psVertA->sSpecularOut.r, psVertB->sSpecularOut.r)), psVertB->sSpecularOut.r);
				psDst->sSpecularOut.g =	Add(Mul(T, Sub(psVertA->sSpecularOut.g, psVertB->sSpecularOut.g)), psVertB->sSpecularOut.g);
				psDst->sSpecularOut.b =	Add(Mul(T, Sub(psVertA->sSpecularOut.b, psVertB->sSpecularOut.b)), psVertB->sSpecularOut.b);
				psDst->sSpecularOut.a =	Add(Mul(T, Sub(psVertA->sSpecularOut.a, psVertB->sSpecularOut.a)), psVertB->sSpecularOut.a);
			}
		}
		else
		{
			/* No lighting, and no specular value, so default to 0 (From d3dm spec) */
			psDst->sSpecularOut.r = D3DM_Zero;
			psDst->sSpecularOut.g = D3DM_Zero;
			psDst->sSpecularOut.b = D3DM_Zero;
            if(psVertA->ui32Flags & D3DM_HASFLAG_FOG)
            {
				psDst->sSpecularOut.a = Add(Mul(T, Sub(psVertA->sSpecularOut.a, psVertB->sSpecularOut.a)), psVertB->sSpecularOut.a);
			}
			else
			{
				psDst->sSpecularOut.a = D3DM_Zero;
			}
		}
    }

	for (i=0; i < sPVRD3DMCaps.MaxSimultaneousTextures; i++)
	{
		/* re-calc texture coordinates based on texture stage state */
		if (psContext->dwFlags & (D3DM_CONTEXT_SWFLAGS_LAYER0ENABLED << i))
		{
			psDst->sTextures[i].x			= Add(Mul(T, Sub(psVertA->sTextures[i].x, psVertB->sTextures[i].x)), psVertB->sTextures[i].x);
			psDst->sTextures[i].y			= Add(Mul(T, Sub(psVertA->sTextures[i].y, psVertB->sTextures[i].y)), psVertB->sTextures[i].y);
			psDst->sTextures[i].ui32NumOut	= psVertA->sTextures[i].ui32NumOut;
		}
	}

	PROFILE_STOP_FUNC(CLIP_TO_PLANE);
}
    
/***********************************************************************************
 Function Name      : FastclipToPlane
 Inputs             : psContext, ppsInVert, ui32NumIn, psPlane
 Outputs            : ppsOutVert
 Returns            : Number of vertices post-clipping
 Description        : Clips some input vertices against a clip psPlane. Outputs
					  list of pointers to post-clipping vertices.
************************************************************************************/
static IMG_UINT32 FastclipToPlane(LPD3DM_CONTEXT psContext,
								  PVR_NATIVE_VERTEX **ppsInVert, 
								  IMG_UINT32 ui32NumIn, 
								  PVR_NATIVE_VERTEX **ppsOutVert,
								  PVR_VECTOR4 *psPlane)
{
    IMG_UINT32 i, ui32NumOut, ui32Generated;
    PVR_NATIVE_VERTEX *psVertS, *psVertP, *psNewVertex, *psTemp;
    NTV_TYPE PDist, SDist, T;

	PROFILE_START_FUNC(FAST_CLIP_TO_PLANE);

    ui32NumOut = 0;
    ui32Generated = 0;

    psTemp = psContext->sTState.sSWTNLState.psNextClipTemp;

    psVertS = ppsInVert[ui32NumIn-1];
    
    SDist = DotProduct4(&psVertS->sClip, psPlane);

    for (i = 0; i < ui32NumIn; i++) 
	{
		psVertP = ppsInVert[i];

		PDist = DotProduct4(&psVertP->sClip, psPlane);

		if (PDist >= D3DM_Zero) 
		{
			/* psVertP is inside the clipping psPlane half space */
			if (SDist >= D3DM_Zero) 
			{
				/* psVertS is inside the clipping psPlane half space */			

				if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_FLAT_SHADING)
				{
					*psTemp = *psVertP;
					psTemp->sDiffuseOut = *psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse;
					psTemp->sSpecularOut = *psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular;
					*ppsOutVert++ = psTemp++;
				}
				else
				{
					*ppsOutVert++ = psVertP;
				}	
				
				ui32NumOut++;
			} 
			else 
			{
				/* s is outside the clipping psPlane half space */
				T = Sub(PDist, SDist) ? Div(PDist, Sub(PDist, SDist)) : D3DM_Zero;
				psNewVertex = psTemp++;
				ClipToPlane (psContext, psNewVertex, psVertS, psVertP, T);

				D3DM_COPY_FLAGBITS(psNewVertex, psVertS);

				*ppsOutVert++ = psNewVertex;
				
				if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_FLAT_SHADING)
				{
					*psTemp = *psVertP;
					psTemp->sDiffuseOut  = *psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse;
					psTemp->sSpecularOut = *psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular;
					*ppsOutVert++ = psTemp++;
				}
				else
				{
					*ppsOutVert++ = psVertP;
				}				
				
				ui32NumOut += 2;

				if (++ui32Generated >= 3) 
				{
					/* Toss the non-convex polygon */
					return 0;
				}
			}
		} 
		else 
		{
			/* p is outside the clipping psPlane half space */
			if (SDist >= D3DM_Zero) 
			{
				/*
				** s is inside the clipping psPlane half space
				**
				** NOTE: To avoid cracking in polygons with shared
				** clipped edges we always compute "fT" from the out
				** vertex to the in vertex.  The above clipping code gets
				** this for free (p is in and s is out).  In this code p
				** is out and s is in, so we reverse the fT computation
				** and the argument order to __glDoClip.
				*/
				T = Sub(SDist, PDist) ? Div(SDist, Sub(SDist, PDist)) : D3DM_Zero;
				psNewVertex = psTemp++;
				ClipToPlane (psContext, psNewVertex, psVertP, psVertS, T);
				D3DM_COPY_FLAGBITS(psNewVertex, psVertS);

				*ppsOutVert++ = psNewVertex;
				ui32NumOut++;
				
				if (++ui32Generated >= 3) 
				{
					/* Toss the non-convex polygon */
					return 0;
				}
			} 
			else 
			{
				/* both points are outside */
			}
		}
		psVertS = psVertP;
		SDist = PDist;
    }

    psContext->sTState.sSWTNLState.psNextClipTemp = psTemp;

	PROFILE_STOP_FUNC(FAST_CLIP_TO_PLANE);
    
    return ui32NumOut;
}
/***********************************************************************************
 Function Name      : DoLineClip
 Inputs             : psContext, ppsInVert, ui32NumOut, ui32AllClipCodes
 Outputs            : -
 Returns            : Number of vertices post-clipping
 Description        : Clips some input vertices against a list of clip planes. List
					  points to post-clipping vertices stored in context, returns
					  number of vertices in said list.
************************************************************************************/
IMG_UINT32 DoLineClip(LPD3DM_CONTEXT psContext,
						PVR_NATIVE_VERTEX *psVertA,
						PVR_NATIVE_VERTEX *psVertB,
						IMG_UINT32 ui32AllClipCodes)
{
    PVR_NATIVE_VERTEX *psTemp;
    PVR_VECTOR4 *psPlane;
    PVR_NATIVE_VERTEX **ppsOutVert;
    PVR_VP_TRANSFORM *psVPTransform = &psContext->sHWState.sTACtl3DState.sVPTrans;
    PVR_VECTOR4	asFrustumClipPlanes[2];
    
	PROFILE_START_FUNC(DO_LINE_CLIP);

    /* near */
    asFrustumClipPlanes[0].x = D3DM_Zero;
    asFrustumClipPlanes[0].y = D3DM_Zero;
    asFrustumClipPlanes[0].z = D3DM_One;
    asFrustumClipPlanes[0].w = FL2NTV(-0.001f);

	/* far */
    asFrustumClipPlanes[1].x = D3DM_Zero;
    asFrustumClipPlanes[1].y = D3DM_Zero;
    asFrustumClipPlanes[1].z = -D3DM_One;
    asFrustumClipPlanes[1].w = D3DM_One;

    psTemp = psContext->sTState.sSWTNLState.asClipVertex;  

    ui32AllClipCodes >>= D3DM_CLIPFLAG_SHIFT;

    /*
    ** Check each of the clipping planes by examining the ui32AllClipCodes
    ** mask. Note that no bits will be set in ui32AllClipCodes for clip
    ** planes that are not enabled.
    */
    if (ui32AllClipCodes) 
	{
		NTV_TYPE x[2], y[2], z[2], invw[2];

		/* Now clip against the clipping planes */
		psPlane = &asFrustumClipPlanes[0];
			
		do 
		{
			if (ui32AllClipCodes & (D3DM_CLIPFLAG_NEAR >> D3DM_CLIPFLAG_SHIFT)) 
			{
				NTV_TYPE T, D1, D2;
				
				D1 = DotProduct4(&psVertA->sClip, psPlane);
				D2 = DotProduct4(&psVertB->sClip, psPlane);

				if (D1 <= D3DM_Zero) 
				{
					/* psVertA is out */
					if (D2 <= D3DM_Zero) 
					{
						/* psVertA & psVertB are out */
						return 0;
					}
					
					/*
					** A is out and B is in.  Compute new A coordinate
					** clipped to the psPlane.
					*/
					T = Div(D2,  Sub(D2, D1));
					ClipToPlane (psContext, psTemp, psVertA, psVertB, T);
					psVertA = psTemp;
					psTemp++;
				} 
				else 
				{
					/* psVertA is in */
					if (D2 <= D3DM_Zero) 
					{
						/*
						** A is in and B is out.  Compute new B
						** coordinate clipped to the psPlane.
						**
						** NOTE: To avoid cracking in polygons with
						** shared clipped edges we always compute "fT"
						** from the out vertex to the in vertex.  The
						** above clipping code gets this for free (psVertB is
						** in and psVertA is out).  In this code psVertB is out and psVertA
						** is in, so we reverse the fT computation and the
						** argument order to (*clip).
						*/
						T = Div(D1, Sub(D1, D2));
						ClipToPlane (psContext, psTemp, psVertB, psVertA, T);
						psVertB = psTemp;
						psTemp++;
					}
					else
					{
						/* A and B are in */
					}
				}
			}
			
			psPlane++;
			ui32AllClipCodes >>= 1;
		} while (ui32AllClipCodes);


		/* Compute window coordinates for both vertices. */
		x[0] = psVertA->sClip.x; 
		y[0] = psVertA->sClip.y; 
		z[0] = psVertA->sClip.z;
		invw[0] = psVertA->sClip.w ? DivPR_Y(D3DM_One, psVertA->sClip.w) : D3DM_Zero;

		x[1] = psVertB->sClip.x; 
		y[1] = psVertB->sClip.y; 
		z[1] = psVertB->sClip.z;
		invw[1] = psVertB->sClip.w ? DivPR_Y(D3DM_One, psVertB->sClip.w) : D3DM_Zero;

		/* Rotate if this is a presentable rendertarget */
		if(psContext->dwRotationAngle == 0										||
		   psContext->dwRotationAngle == 180									||	
		   psContext->psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_SURFACE	||
		   psContext->psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_TEXTURE)
		{
			psVertA->sWindow.x = Add(Mul(Mul(x[0], psVPTransform->XScale), PR_UNSHIFT(invw[0])), psVPTransform->XOffset);
			psVertA->sWindow.y = Add(Mul(Mul(y[0], psVPTransform->YScale), PR_UNSHIFT(invw[0])), psVPTransform->YOffset);
			psVertB->sWindow.x = Add(Mul(Mul(x[1], psVPTransform->XScale), PR_UNSHIFT(invw[1])), psVPTransform->XOffset);
			psVertB->sWindow.y = Add(Mul(Mul(y[1], psVPTransform->YScale), PR_UNSHIFT(invw[1])), psVPTransform->YOffset);
		}
		else
		{
			psVertA->sWindow.x = Add(Mul(Mul(y[0], psVPTransform->XScale), PR_UNSHIFT(invw[0])), psVPTransform->XOffset);
			psVertA->sWindow.y = Add(Mul(Mul(x[0], psVPTransform->YScale), PR_UNSHIFT(invw[0])), psVPTransform->YOffset);
			psVertB->sWindow.x = Add(Mul(Mul(y[1], psVPTransform->XScale), PR_UNSHIFT(invw[1])), psVPTransform->XOffset);
			psVertB->sWindow.y = Add(Mul(Mul(x[1], psVPTransform->YScale), PR_UNSHIFT(invw[1])), psVPTransform->YOffset);
		}

		psVertA->sWindow.z = Add(MulPR_XY(MulPR_X(z[0],psVPTransform->ZScale), invw[0]), PR_SHIFT(psVPTransform->ZOffset));
		psVertA->sWindow.w = invw[0];
		psVertB->sWindow.z = Add(MulPR_XY(MulPR_X(z[1],psVPTransform->ZScale), invw[1]), PR_SHIFT(psVPTransform->ZOffset));
		psVertB->sWindow.w = invw[1];
    }

	ppsOutVert = &psContext->sTState.sSWTNLState.apsOutputVert[0][0];

	psContext->sTState.sSWTNLState.ppsOutputArray = ppsOutVert;

	ppsOutVert[0] = psVertA;
	ppsOutVert[1] = psVertB;

	PROFILE_STOP_FUNC(DO_LINE_CLIP);

	return 2;
}
/***********************************************************************************
 Function Name      : DoPolygonClip
 Inputs             : psContext, ppsInVert, ui32NumOut, ui32AllClipCodes
 Outputs            : -
 Returns            : Number of vertices post-clipping
 Description        : Clips some input vertices against a list of clip planes. List
					  points to post-clipping vertices stored in context, returns
					  number of vertices in said list.
************************************************************************************/
IMG_INT32 DoPolygonClip(LPD3DM_CONTEXT psContext,
						PVR_NATIVE_VERTEX **ppsInVertex,
						IMG_UINT32 ui32NumIn,
						IMG_UINT32 ui32AllClipCodes)
{
	PVR_NATIVE_VERTEX *apsInVert[3];
    PVR_NATIVE_VERTEX **ppsInVert;
    PVR_NATIVE_VERTEX **ppsOutVert;
    PVR_NATIVE_VERTEX *psTemp;
    PVR_VECTOR4 *psPlane;
    IMG_UINT32 i;
	IMG_UINT32 ui32NumOut = ui32NumIn;
    NTV_TYPE wx, wy;
    PVR_VP_TRANSFORM *psVPTransform = &psContext->sHWState.sTACtl3DState.sVPTrans;
	PVR_VECTOR4	asFrustumClipPlanes[2];

	PROFILE_START_FUNC(DO_POLYGON_CLIP);
    
    /* near */
    asFrustumClipPlanes[0].x = D3DM_Zero;
    asFrustumClipPlanes[0].y = D3DM_Zero;
    asFrustumClipPlanes[0].z = D3DM_One;
    asFrustumClipPlanes[0].w = FL2NTV(-0.001f);

	/* far */
    asFrustumClipPlanes[1].x = D3DM_Zero;
    asFrustumClipPlanes[1].y = D3DM_Zero;
    asFrustumClipPlanes[1].z = -D3DM_One;
    asFrustumClipPlanes[1].w = D3DM_One;
    

    ui32AllClipCodes >>= D3DM_CLIPFLAG_SHIFT;

    /*
    ** Reset psNextClipTemp pointer for any new verticies that are Generated
    ** during the clipping.
    */
    psContext->sTState.sSWTNLState.psNextClipTemp = psContext->sTState.sSWTNLState.asClipVertex;

	/* Form initial input vertex pointer list */
	apsInVert[0] = *ppsInVertex++;
	apsInVert[1] = *ppsInVertex++;
	apsInVert[2] = *ppsInVertex++;

    ppsInVert = &apsInVert[0];

⌨️ 快捷键说明

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