📄 tnl.c
字号:
/* 2(E.N)N */
ScalarMultiply(&sN, ntvTmp, &sVecTemp);
/* R = 2(E.N)N-E */
DistanceVector(&sVecTemp, &sE, (PVR_VECTOR3*)&psVertex->sTextures[i]);
}
else
{
/* 2Nz */
ntvTmp = Mul(D3DM_Two ,psVertex->WorldNormalZ);
/* 2NzN */
ScalarMultiply(&sN, ntvTmp, &sVecTemp);
/* 2NzN-I */
DistanceVector(&sVecTemp, &sI, (PVR_VECTOR3*)&psVertex->sTextures[i]);
}
}
else
{
psVertex->sTextures[i].x = D3DM_Zero;
psVertex->sTextures[i].y = D3DM_Zero;
psVertex->sTextures[i].z = D3DM_Zero;
psContext->hrLastError = D3DMERR_INVALIDCALL;
}
break;
}
}
case D3DMTSS_TCI_PASSTHRU:
{
if(psLState->dwCoordSetNum != i)
{
psVertex->sTextures[i].x = psVertex->sTextures[psLState->dwCoordSetNum].x;
psVertex->sTextures[i].y = psVertex->sTextures[psLState->dwCoordSetNum].y;
psVertex->sTextures[i].z = psVertex->sTextures[psLState->dwCoordSetNum].z;
psVertex->sTextures[i].ui32NumOut = psVertex->sTextures[psLState->dwCoordSetNum].ui32NumOut;
}
break;
}
}
}
/* Texture Coordinate transformation */
for(i=0; i < sPVRD3DMCaps.MaxSimultaneousTextures; i++)
{
PSWTNLSTATE psSWTNLState;
PLAYER_TSTATE psLState;
psSWTNLState = &psContext->sTState.sSWTNLState;
psLState = &psContext->sTState.sLState[i];
/* Transformation */
if((psLState->dwD3DTexTransFlags & ~D3DMTTFF_PROJECTED) != D3DMTTFF_DISABLE)
{
PVR_TEXVECTOR sVecTemp;
TransformVector(&psContext->sTState.sSWTNLState.sTexMatrix[i], (PVR_VECTOR3*)&psVertex->sTextures[i], (PVR_VECTOR3*)&sVecTemp);
psVertex->sTextures[i] = sVecTemp;
psVertex->sTextures[i].ui32NumOut = (psLState->dwD3DTexTransFlags & ~D3DMTTFF_PROJECTED);
}
/* Texture Co-ordinate projection */
if(psLState->dwD3DTexTransFlags & D3DMTTFF_PROJECTED)
{
IMG_UINT32 j;
IMG_UINT32 ui32NumOut = psVertex->sTextures[i].ui32NumOut;
NTV_TYPE *pCoord = (NTV_TYPE *) &psVertex->sTextures[i];
/* Div by Zero Protect */
if(pCoord[ui32NumOut-1] == D3DM_Zero)
{
psContext->hrLastError = D3DM_GENERICFAILURE;
continue;
}
for(j=0; j< ui32NumOut - 1; j++)
{
pCoord[j] = Div(pCoord[j], pCoord[ui32NumOut-1]);
}
psVertex->sTextures[i].ui32NumOut--;
}
}
/*
unconditionally calc output colour
*/
CalcRGBColor(psContext, psVertex);
psVertex->ui32Flags |= D3DM_TNLFLAG_VERTEX_VALIDATED;
}
PROFILE_STOP_FUNC(VALIDATE_VERTEX);
}
/***********************************************************************************
Function Name : TriangleMaxDepthSlope
Inputs : psVertex
Outputs : NTV_TYPE
Returns : -
Description : finds max depth slope for given primitive
************************************************************************************/
NTV_TYPE TriangleMaxDepthSlope(PVR_NATIVE_VERTEX* psVertex)
{
NTV_TYPE ntvZX, ntvZY, ntvRes;
NTV_TYPE ntvDeltaX, ntvDeltaY, ntvDeltaZ;
NTV_TYPE ntvXMax, ntvXMin, ntvYMax, ntvYMin, ntvZMax, ntvZMin;
ntvXMin = NTV_MIN(psVertex[0].sWindow.x, NTV_MIN(psVertex[1].sWindow.x, psVertex[2].sWindow.x));
ntvXMax = NTV_MAX(psVertex[0].sWindow.x, NTV_MAX(psVertex[1].sWindow.x, psVertex[2].sWindow.x));
ntvDeltaX = Sub(ntvXMax, ntvXMin);
ntvYMin = NTV_MIN(psVertex[0].sWindow.y, NTV_MIN(psVertex[1].sWindow.y, psVertex[2].sWindow.y));
ntvYMax = NTV_MAX(psVertex[0].sWindow.y, NTV_MAX(psVertex[1].sWindow.y, psVertex[2].sWindow.y));
ntvDeltaY = Sub(ntvYMax, ntvYMin);
ntvZMin = NTV_MIN(psVertex[0].sWindow.z, NTV_MIN(psVertex[1].sWindow.z, psVertex[2].sWindow.z));
ntvZMax = NTV_MAX(psVertex[0].sWindow.z, NTV_MAX(psVertex[1].sWindow.z, psVertex[2].sWindow.z));
ntvDeltaZ = PR_UNSHIFT(Sub(ntvZMax,ntvZMin));
if(ntvDeltaX != D3DM_Zero)
{
ntvZX = NTV_ABS(Div(ntvDeltaZ, ntvDeltaX));
}
else
{
ntvZX = D3DM_Zero;
}
if(ntvDeltaY != D3DM_Zero)
{
ntvZY = NTV_ABS(Div(ntvDeltaZ, ntvDeltaY));
}
else
{
ntvZY = D3DM_Zero;
}
ntvRes = NTV_MAX(ntvZY, ntvZY);
return ntvRes == D3DM_Zero ? D3DM_One : ntvRes;
}
/***********************************************************************************
Function Name : CalculateDepthBias
Inputs : psContext, bPrimitiveStarted, ntvNewDepthM
Outputs :
Returns : -
Description : Performs depth bias calculation
************************************************************************************/
IMG_VOID CalculateDepthBias(LPD3DM_CONTEXT psContext, NTV_TYPE ntvNewDepthM)
{
NTV_TYPE ntvDepthBias = D3DM_Zero;
ntvDepthBias = Mul(psContext->sTState.D3DSSDBias, ntvNewDepthM);
psContext->sTState.D3DZBiasOffset = Add(psContext->sTState.D3DZBias, ntvDepthBias);
}
#endif /*(defined(SUPPORT_VGP) && (COREVERSION < 13)) ||
(defined(SUPPORT_VGP_LITE) && (COREVERSION < 120)) ||
(!defined(SUPPORT_VGP) && !defined(SUPPORT_VGP_LITE))*/
/*****************************************************************************
FUNCTION : SetupViewportTransform
PURPOSE : Configures the MBX1 VGP viewport-transform according to the
current chosen viewport, depth-buffer mode and w/z ranges.
PARAMETERS : psContext - The 3D rendering context to update
RETURNS : none
*****************************************************************************/
IMG_VOID SetupViewportTransform(LPD3DM_CONTEXT psContext)
{
PTRANSIENT_STATE psTState;
PVR_VP_TRANSFORM* psVPTrans;
LPD3DMRECT psViewPortRect;
D3DMRECT sNewRect;
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
float fTmp;
#endif
if(psContext->psCurrentRenderTarget == NULL)
{
/*
No render target so this must be initialisation.
We will be called again when the rendertarget is set
*/
return;
}
psTState = &psContext->sTState;
psViewPortRect = &sNewRect;
psVPTrans = &psContext->sHWState.sTACtl3DState.sVPTrans;
/* Rotate viewport rect if required */
RotateRects(psContext,
psViewPortRect,
&psTState->sViewPortRect,
1,
psContext->psCurrentRenderTarget->dwWidth,
psContext->psCurrentRenderTarget->dwHeight);
/*
Setup the X and Y portion of the viewport transform to map the canonical
post-projection view volume (-1.0,1.0) -> (1.0,-1.0) to the current
viewport rectangle in screen space.
*/
switch(psContext->dwRotationAngle)
{
case 0:
{
psVPTrans->XScale = Div(LONG_AS_NTV(psViewPortRect->x2 - psViewPortRect->x1), D3DM_Two);
psVPTrans->XOffset = Add(LONG_AS_NTV(psViewPortRect->x1), psVPTrans->XScale);
psVPTrans->YScale = Div(LONG_AS_NTV(psViewPortRect->y1 - psViewPortRect->y2), D3DM_Two);
psVPTrans->YOffset = Sub(LONG_AS_NTV(psViewPortRect->y1), psVPTrans->YScale);
break;
}
case 90:
{
psVPTrans->XScale = Div(LONG_AS_NTV(psViewPortRect->x1 - psViewPortRect->x2), D3DM_Two);
psVPTrans->XOffset = Sub(LONG_AS_NTV(psViewPortRect->x1), psVPTrans->XScale);
psVPTrans->YScale = Div(LONG_AS_NTV(psViewPortRect->y1 - psViewPortRect->y2), D3DM_Two);
psVPTrans->YOffset = Sub(Sub(LONG_AS_NTV(psViewPortRect->y1), psVPTrans->YScale), D3DM_One);
break;
}
case 180:
{
psVPTrans->XScale = Div(LONG_AS_NTV(psViewPortRect->x1 - psViewPortRect->x2), D3DM_Two);
psVPTrans->XOffset = Sub(Sub(LONG_AS_NTV(psViewPortRect->x1), psVPTrans->XScale), D3DM_One);
psVPTrans->YScale = Div(LONG_AS_NTV(psViewPortRect->y2 - psViewPortRect->y1), D3DM_Two);
psVPTrans->YOffset = Sub(Add(LONG_AS_NTV(psViewPortRect->y1), psVPTrans->YScale), D3DM_One);
break;
}
case 270:
{
psVPTrans->XScale = Div(LONG_AS_NTV(psViewPortRect->x2 - psViewPortRect->x1), D3DM_Two);
psVPTrans->XOffset = Sub(Add(LONG_AS_NTV(psViewPortRect->x1), psVPTrans->XScale), D3DM_One);
psVPTrans->YScale = Div(LONG_AS_NTV(psViewPortRect->y2 - psViewPortRect->y1), D3DM_Two);
psVPTrans->YOffset = Add(LONG_AS_NTV(psViewPortRect->y1), psVPTrans->YScale);
break;
}
}
/*
Setup the depth portion of the viewport transform depending upon the
current depth-buffering mode
*/
if(psTState->dwRSFlags & TSTATE_RSFLAGS_WENABLE)
{
NTV_TYPE WNear, WFar;
/*
W-buffering: Set the z-scale and z-offset parameters to map the
current w-range into 0.0 -> 1.0.
*/
WNear = psTState->WNear;
WFar = psTState->WFar;
if (WNear == WFar)
{
float fTmp = 1e-6f;//////PVRDXHAL_MINWRANGE//FIXME - add define
WFar = Add(WNear, FL2NTV(fTmp));
}
psVPTrans->ZScale = Div(D3DM_One, Sub(WFar, WNear));
psVPTrans->ZOffset = -Mul(WNear, psVPTrans->ZScale);
}
else
{
NTV_TYPE ZMin, ZMax;
/*
Z-buffering: Set the z-scale and offset parameters to map the
canonical post-projection 0.0 -> 1.0 depth range to the current
z-range
*/
ZMin = psTState->ZMin;
ZMax = psTState->ZMax;
if (ZMin == ZMax)
{
float fTmp = 1e-6f;//////PVRDXHAL_MINZRANGE//FIXME - add define
ZMax = Add(ZMin, FL2NTV(fTmp));
}
psVPTrans->ZScale = Div(D3DM_One, Sub(ZMax, ZMin));
psVPTrans->ZOffset = -Mul(ZMin, psVPTrans->ZScale);
}
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
/*
Set the HW W/RHW-clamping value to the near-clip plane position
*/
fTmp = NTV2FL(psTState->WNear);
psContext->sHWState.sTACtl3DState.dwVGPWClamp = FLOAT_TO_LONG(fTmp);
/*
Record that the HW viewport transform and W-clamp value have
been modified
*/
psContext->sTState.sSWTNLState.dwTNLFlags |= PVRD3DTNL_FLAGS_ZBIAS_PARAMS_CHANGED;
psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_VGP_VIEWPORTTRANS |
MBX1_TASTATEPRES_VGP_WCLAMPVAL;
#endif
}
/***********************************************************************************
Function Name : UpdateMatrices
Inputs : psContext
Outputs : NTV_TYPE
Returns : -
Description : Recalculates all matrices
************************************************************************************/
IMG_VOID UpdateMatrices(LPD3DM_CONTEXT psContext)
{
PSWTNLSTATE psSWTNLState = &psContext->sTState.sSWTNLState;
/* concatenate transforms */
if(psSWTNLState->dwTNLFlags & PVRD3DTNL_FLAGS_WORLD_CHANGED ||
psSWTNLState->dwTNLFlags & PVRD3DTNL_FLAGS_VIEW_CHANGED)
{
/* WorldViewProj Matrix */
MultiplyMatrix(&psSWTNLState->sWorldMatrix, &psSWTNLState->sViewMatrix, &psSWTNLState->sWorldView);
MultiplyMatrix(&psSWTNLState->sWorldView, &psSWTNLState->sProjMatrix, &psSWTNLState->sWorldViewProj);
/* Inverse Transpose and transpose of World View Matrix */
TransposeMatrix(&psSWTNLState->sWorldView,
&psSWTNLState->sWorldViewT);
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
/*
For normal transformations we require the inverse transpose of WorldView.
We have to transpose for VGP however, cancelling out transposition.
Solution is to not transpose to begin with if we are using VGP
*/
InverseMatrix(&psSWTNLState->sWorldView,
&psSWTNLState->sWorldViewInvT);
#else
InverseMatrix(&psSWTNLState->sWorldViewT,
&psSWTNLState->sWorldViewInvT);
#endif
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
TransposeMatrix(&psSWTNLState->sWorldViewProj,
&psSWTNLState->sWorldViewProjT);
psSWTNLState->dwConstantFlags |= (VGPTNL_CONST_WVT_CHANGED |
VGPTNL_CONST_WVIT_CHANGED|
VGPTNL_CONST_WVPT_CHANGED);
#endif
if(psSWTNLState->dwTNLFlags & PVRD3DTNL_FLAGS_VIEW_CHANGED)
{
/* Inverse Transpose of View Set-up */
InverseMatrix(&psSWTNLState->sViewMatrix, &psSWTNLState->sViewInvT);
TransposeMatrix(&psSWTNLState->sViewInvT, &psSWTNLState->sViewInvT);
}
/* Clear all the flags */
psSWTNLState->dwTNLFlags &= ~(PVRD3DTNL_FLAGS_WORLD_CHANGED |
PVRD3DTNL_FLAGS_VIEW_CHANGED |
PVRD3DTNL_FLAGS_PROJECTION_CHANGED);
}
if(psSWTNLState->dwTNLFlags & PVRD3DTNL_FLAGS_PROJECTION_CHANGED)
{
MultiplyMatrix(&psSWTNLState->sWorldView, &psSWTNLState->sProjMatrix, &psSWTNLState->sWorldViewProj);
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
TransposeMatrix(&psSWTNLState->sWorldViewProj,
&psSWTNLState->sWorldViewProjT);
psSWTNLState->dwConstantFlags |= VGPTNL_CONST_WVPT_CHANGED;
#endif
/* Clear flag */
psSWTNLState->dwTNLFlags &= ~(PVRD3DTNL_FLAGS_PROJECTION_CHANGED);
}
}
/*****************************************************************************
End of file (tnl.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -