📄 vertex.c
字号:
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 + -