📄 hxfclip.c
字号:
// Calculate vertex indices
pFace[0] = pStartSeg->pVtx;
pFace[1] = pSeg2->pVtx;
pFace[2] = pSeg1->pVtx;
if(0 < HXFCullTest(pFace[0], pFace[1], pFace[2],
pState->StorageLR[0] & HXF_PA_CULLDIR_CW))
{
pState->NumClippedPrimitives++;
faceidx += 3;
}
pSeg2 = pSeg1;
pSeg1 = pSeg1->pNext;
} while (pSeg1 != pStartSeg);
}
else
{
do
{
void** pFace = &(pState->pClippedIndices[faceidx]);
// Form a face from pStartSeg, pSeg2, pSeg1
// Calculate vertex indices
pFace[0] = pStartSeg->pVtx;
pFace[1] = pSeg2->pVtx;
pFace[2] = pSeg1->pVtx;
pState->NumClippedPrimitives++;
faceidx += 3;
pSeg2 = pSeg1;
pSeg1 = pSeg1->pNext;
} while (pSeg1 != pStartSeg);
}
HXF_PROFILER_TRANSITION(HXFPROFILE_DRAW_ASSEMBLE);
return pState;
}
#ifndef HXF_HARNESS
/* ************************************************************************* *\
FUNCTION: HXFDrawClippedTriangles
DESCRIPTION: The raster must not be in an active primitive when this
function is called.
\* ************************************************************************* */
HXFState* HXFDrawClippedTriangles(HXFState* pState)
{
void** pFace = (void**)pState->pClippedIndices;
HUINT32 i = pState->NumClippedPrimitives;
HXF_PROFILER_TRANSITION(HXFPROFILE_DRAW_CLIP);
#ifdef HXF_FIX_PRN725
/* FIX PRN725 - Detect if an offset color and TexCoord 2 is present
If this is the case then only submit one triangle at a time otherwise
Submit all the triangles as an single list.
*/
if(pState->OutSpecularOffset != 0 && pState->OutTex2Offset != 0)
{
while(i--)
{
ctlBeginClipList( pState );
ctlVertex( pState, pFace[0], pFace[1], pFace[2] );
pFace+=3; // step to next primitive
ctlEndPrimitiveList( pState );
}
}
else
{
#endif // HXF_FIX_PRN725
ctlBeginClipList( pState );
while(i--)
{
ctlVertex( pState, pFace[0], pFace[1], pFace[2] );
pFace+=3; // step to next primitive
}
ctlEndPrimitiveList( pState );
#ifdef HXF_FIX_PRN725
}
#endif // HXF_FIX_PRN725
pState->pClippedVertices = pState->pClippedVertices
- (pState->NumClippedVertices * pState->OutVertexSize);
pState->NumClippedVertices = 0;
pState->NumClippedPrimitives = 0;
HXF_PROFILER_TRANSITION(HXFPROFILE_DRAW_ASSEMBLE);
return pState;
}
/* ************************************************************************* *\
FUNCTION: HXFDrawClippedLines
DESCRIPTION: The raster must not be in an active primitive when this
function is called.
\* ************************************************************************* */
HXFState* HXFDrawClippedLines(HXFState* pState)
{
void** pFace = (void**)pState->pClippedIndices;
HUINT32 i = pState->NumClippedPrimitives;
HXF_PROFILER_TRANSITION(HXFPROFILE_DRAW_CLIP);
while(i--)
{
ctlBeginClipList( pState );
ctlVertex( pState, pFace[0], pFace[1], NULL );
ctlEndPrimitiveList( pState );
pFace+=2; // step to next primitive
}
pState->pClippedVertices = pState->pClippedVertices
- (pState->NumClippedVertices * pState->OutVertexSize);
pState->NumClippedVertices = 0;
pState->NumClippedPrimitives = 0;
HXF_PROFILER_TRANSITION(HXFPROFILE_DRAW_ASSEMBLE);
return pState;
}
#endif // HXF_HARNESS
/* ************************************************************************* *\
FUNCTION: ClipInterp
DESCRIPTION:
// FIXME Interp Needs to do Perspective correct
\* ************************************************************************* */
void HXFClipInterpolate(HXFState* pState, HBYTE* pIn, HBYTE* pOut,
HXFClipSegment* pNewSeg, HUINT32 boundary)
{
HUINT32 valueIdx = 0;
HUINT8* pFlags = NULL;
HVECTOR4FX* pInPos = NULL;
HVECTOR4FX* pOutPos = NULL;
HVECTOR4FX* pNewPos = NULL;
HVECTOR4FX* pNewClipPos = NULL;
HFIXED alpha = 0;
HFIXED BC0 = 0;
HFIXED BC1 = 0;
HFIXED plane = 0;
pNewPos = (HVECTOR4FX*)pNewSeg->pVtx;
pFlags = &(pNewSeg->Flags);
pInPos = (HVECTOR4FX*)(pIn + pState->OutClipPosOffset);
pOutPos = (HVECTOR4FX*)(pOut + pState->OutClipPosOffset);
pNewClipPos = (HVECTOR4FX*)(pNewSeg->pVtx + pState->OutClipPosOffset);
// *********************************************************************
// Compute alpha
// *********************************************************************
// Must calculate what percentage of the line is inside the plane
// This is done in homogeneous space after the viewport and device
// transform. So the clip planes for X and Y are defined by the viewport
// multiplied by w. if the viewport is defined by (l, r, t, b)
// *********************************************************************
// using BC0 as numerator, BC1 as denominator...
// instead of a switch, we can now just use boundary" as an index.
valueIdx = boundary>>1; // divide by 2 to convert an attribute index
BC0 = pInPos->v[valueIdx];
BC1 = pOutPos->v[valueIdx];
if(boundary&1)
{
BC0 = pInPos->w - BC0;
BC1 = pOutPos->w - BC1;
}
alpha = Fixed_Div( BC0, BC0 - BC1 );
// P(a) = P0 + a(P1 - P0)
if(valueIdx != 0)
{
pNewClipPos->x = pInPos->x + Fixed_Mul( alpha, pOutPos->x - pInPos->x );
}
if(valueIdx != 1)
{
pNewClipPos->y = pInPos->y + Fixed_Mul( alpha, pOutPos->y - pInPos->y );
}
if(valueIdx != 2)
{
pNewClipPos->z = pInPos->z + Fixed_Mul( alpha, pOutPos->z - pInPos->z );
}
pNewClipPos->w = pInPos->w + Fixed_Mul( alpha, pOutPos->w - pInPos->w );
if(boundary&1)
{
pNewClipPos->v[valueIdx] = pNewClipPos->w;
}
else
{
pNewClipPos->v[valueIdx] = 0;
}
// Compute the updated clipflags
*pFlags = 0;
if (pNewClipPos->x < 0)
{
*pFlags = HXF_VTX_CLIP_FLAG_NEG_X;
}
if ((pNewClipPos->w - pNewClipPos->x) < 0)
{
*pFlags |= HXF_VTX_CLIP_FLAG_POS_X;
}
if (pNewClipPos->y < 0)
{
*pFlags |= HXF_VTX_CLIP_FLAG_NEG_Y;
}
if ((pNewClipPos->w - pNewClipPos->y) < 0)
{
*pFlags |= HXF_VTX_CLIP_FLAG_POS_Y;
}
if (pNewClipPos->z < 0)
{
*pFlags |= HXF_VTX_CLIP_FLAG_NEG_Z;
}
if ((pNewClipPos->w - pNewClipPos->z) < 0)
{
*pFlags |= HXF_VTX_CLIP_FLAG_POS_Z;
}
// Compute the new screen position.
if(*pFlags == 0)
{
if(pNewClipPos->w != 0)
{
HXFViewportTransform(pState, pNewClipPos, pNewPos);
}
else
{
pNewPos->x = 0;
pNewPos->y = 0;
pNewPos->z = 0;
pNewPos->w = 0;
}
}
// Interpolate Colors
// FIXME Make perspective correct. - ((in->c * in->w) + alpha((out->c * out->w) - (in->c * in->w))) / (new->w)
if (pState->OutDiffuseOffset)
{
HUINT32* pInClr = NULL;
HUINT32* pOutClr = NULL;
HFIXED ir, ib, ig, ia;
HFIXED or, ob, og, oa;
pInClr = (HUINT32*)((pIn) + pState->OutDiffuseOffset);
pOutClr = (HUINT32*)((pOut) + pState->OutDiffuseOffset);
// unpack colors
ir = ((*pInClr >> 24) & 0x000000FF );
ig = ((*pInClr >> 16) & 0x000000FF );
ib = ((*pInClr >> 8) & 0x000000FF );
ia = (*pInClr & 0x000000FF );
or = ((*pOutClr >> 24) & 0x000000FF );
og = ((*pOutClr >> 16) & 0x000000FF );
ob = ((*pOutClr >> 8) & 0x000000FF );
oa = (*pOutClr & 0x000000FF );
ir += Fixed_Mul( alpha, or - ir );
ig += Fixed_Mul( alpha, og - ig );
ib += Fixed_Mul( alpha, ob - ib );
ia += Fixed_Mul( alpha, oa - ia );
pOutClr = (HUINT32*)((pNewSeg->pVtx) + pState->OutDiffuseOffset);
*pOutClr = (HUINT32)((( ir << 24 ) & 0xFF000000 ) |
( ( ig << 16 ) & 0x00FF0000 ) |
( ( ib << 8 ) & 0x0000FF00 ) |
( ia & 0x000000FF ));
}
// FIXME Make perspective correct.
if (pState->OutSpecularOffset)
{
HUINT32* pInClr = NULL;
HUINT32* pOutClr = NULL;
HFIXED ir, ib, ig, ia;
HFIXED or, ob, og, oa;
pInClr = (HUINT32*)((pIn) + pState->OutSpecularOffset);
pOutClr = (HUINT32*)((pOut) + pState->OutSpecularOffset);
// unpack colors
ir = ((*pInClr >> 24) & 0x000000FF );
ig = ((*pInClr >> 16) & 0x000000FF );
ib = ((*pInClr >> 8) & 0x000000FF );
ia = (*pInClr & 0x000000FF );
or = ((*pOutClr >> 24) & 0x000000FF );
og = ((*pOutClr >> 16) & 0x000000FF );
ob = ((*pOutClr >> 8) & 0x000000FF );
oa = (*pOutClr & 0x000000FF );
ir += Fixed_Mul( alpha, or - ir );
ig += Fixed_Mul( alpha, og - ig );
ib += Fixed_Mul( alpha, ob - ib );
ia += Fixed_Mul( alpha, oa - ia );
pOutClr = (HUINT32*)((pNewSeg->pVtx) + pState->OutSpecularOffset);
*pOutClr = (HUINT32)((( ir << 24 ) & 0xFF000000 ) |
( ( ig << 16 ) & 0x00FF0000 ) |
( ( ib << 8 ) & 0x0000FF00 ) |
( ia & 0x000000FF ));
}
//
// Linear interpolation of Texture coordinates
// FIXME Make perspective correct.
if (pState->OutTex1Offset)
{
HVECTOR2FX* pInTex = NULL;
HVECTOR2FX* pOutTex = NULL;
HVECTOR2FX* pNewTex = NULL;
pInTex = (HVECTOR2FX*)((pIn) + pState->OutTex1Offset);
pOutTex = (HVECTOR2FX*)((pOut) + pState->OutTex1Offset);
pNewTex = (HVECTOR2FX*)((pNewSeg->pVtx) + pState->OutTex1Offset);
pNewTex->x = pInTex->x + Fixed_Mul( alpha, pOutTex->x - pInTex->x );
pNewTex->y = pInTex->y + Fixed_Mul( alpha, pOutTex->y - pInTex->y );
}
// FIXME Make perspective correct.
if (pState->OutTex2Offset)
{
HVECTOR2FX* pInTex = NULL;
HVECTOR2FX* pOutTex = NULL;
HVECTOR2FX* pNewTex = NULL;
pInTex = (HVECTOR2FX*)((pIn) + pState->OutTex2Offset);
pOutTex = (HVECTOR2FX*)((pOut) + pState->OutTex2Offset);
pNewTex = (HVECTOR2FX*)((pNewSeg->pVtx) + pState->OutTex2Offset);
pNewTex->x = pInTex->x + Fixed_Mul( alpha, pOutTex->x - pInTex->x );
pNewTex->y = pInTex->y + Fixed_Mul( alpha, pOutTex->y - pInTex->y );
}
}
/* ************************************************************************* *\
** ************************************************************************* **
** EOF
** ************************************************************************* **
\* ************************************************************************* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -