📄 primindexed.c
字号:
/******************************************************************************
<module>
* Name : primindexed.c
* Title : D3DM indexed primitive functions
* Author(s) : Imagination Technologies
* Created : 2 March 2004
*
* Copyright : 2004 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : D3DM indexed primitive functions
*
* Platform : Windows CE
*
$Log: primindexed.c $
********************************************************************************/
#include "context.h"
#if !defined(SUPPORT_VGP) && !defined (SUPPORT_VGP_LITE)
// #define NON_OPT_IDX_TRI_LIST
/***********************************************************************************
Function Name : IndexedTriangleList
************************************************************************************/
IMG_VOID IndexedTriangleList (LPD3DM_CONTEXT psContext,
IMG_UINT32 ui32FVFcode,
BYTE *pbVBData,
IMG_UINT32 ui32VBByteStride,
BYTE *pbIBData,
IMG_UINT32 ui32IBByteStride,
IMG_UINT32 ui32PrimCount)
{
#ifdef NON_OPT_IDX_TRI_LIST
IMG_UINT32 i;
IMG_INT32 i32NumVerts/*, j*/;
IMG_UINT32 ui32ClipCode;
PVR_NATIVE_VERTEX asVertex[3], **ppsVertex, *apsVertex[3];
IMG_BOOL bStartPrimitive = IMG_TRUE;
IMG_UINT32 ui32IndexMask;
UNALIGNED IMG_UINT32 *pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
NTV_TYPE ntvDepthM = D3DM_Zero;
ui32IndexMask = psContext->ui32IndexMask;
/* set up next triangle */
apsVertex[0] = &asVertex[0];
apsVertex[1] = &asVertex[1];
apsVertex[2] = &asVertex[2];
for(i=0; i<ui32PrimCount; i++)
{
IMG_BOOL bPassCullTest;
IMG_BOOL bIsCounterClockwise;
/* construct native vertices */
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, (*pui32IBData & ui32IndexMask)))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + ((*pui32IBData & ui32IndexMask) * ui32VBByteStride)),
ui32FVFcode,
apsVertex[0]);
/* Advance pointer */
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, (*pui32IBData & ui32IndexMask)))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + ((*pui32IBData & ui32IndexMask) * ui32VBByteStride)),
ui32FVFcode,
apsVertex[1]);
/* Advance pointer */
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, (*pui32IBData & ui32IndexMask)))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + ((*pui32IBData & ui32IndexMask) * ui32VBByteStride)),
ui32FVFcode,
apsVertex[2]);
/* Advance pointer */
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Store pointers to colours for flat shading */
psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse = &apsVertex[0]->sDiffuseOut;
psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular = &apsVertex[0]->sSpecularOut;
/**********************
clip test
**********************/
DoClipTestandVPTransform(psContext, &apsVertex[0], 3);
/**********************
Depth bias
**********************/
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
{
/* Calculate value of m */
NTV_TYPE ntvNewDepthM = TriangleMaxDepthSlope(apsVertex[0]);
/* if m is different from previous m then calculate depth bias offset */
if(ntvNewDepthM != ntvDepthM)
{
CalculateDepthBias(psContext,ntvNewDepthM);
ntvDepthM = ntvNewDepthM;
}
}
/* any vertices clipped? */
ui32ClipCode = (apsVertex[0]->ui32Flags
| apsVertex[1]->ui32Flags
| apsVertex[2]->ui32Flags) & D3DM_CLIPFLAG_MASK;
if ((ui32ClipCode & D3DM_CLIPFLAG_NEAR) == 0)
{
/* Check cull status */
bIsCounterClockwise = IsCounterClockWise(&apsVertex[0]);
switch(psContext->dwTAPrimCtl & MBX1_TAPRIM_CULLMODEMASK)
{
case MBX1_TAPRIM_CULLMODENONE:
bPassCullTest = IMG_TRUE;
break;
case MBX1_TAPRIM_CULLMODECW:
bPassCullTest = bIsCounterClockwise;
break;
case MBX1_TAPRIM_CULLMODECCW:
bPassCullTest = !bIsCounterClockwise;
break;
default:
///error
break;
}
}
else
{
bPassCullTest = IMG_TRUE;
}
if(!bPassCullTest)
{
continue;
}
else if(ui32ClipCode == 0) /* no clipping: */
{
if(bStartPrimitive)
{
/*
Start a new primitive block
*/
TACSWritePrimHdr(psContext, psContext->dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACELIST);
bStartPrimitive = IMG_FALSE;
}
ValidateVertex(psContext, &apsVertex[0], 3);
OutputVertices(psContext, &apsVertex[0], 3);
}
else if(!(apsVertex[0]->ui32Flags
& apsVertex[1]->ui32Flags
& apsVertex[2]->ui32Flags & D3DM_CLIPFLAG_MASK))
{
ValidateVertex(psContext, &apsVertex[0], 3);
i32NumVerts = DoPolygonClip(psContext, &apsVertex[0], 3, ui32ClipCode);
ppsVertex = psContext->sTState.sSWTNLState.ppsOutputArray;
if(!bStartPrimitive)
{
TACSWriteLastPrim(psContext);
}
TACSWritePrimHdr(psContext, psContext->dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACEFAN);
OutputVertices(psContext, ppsVertex, i32NumVerts);
TACSWriteLastPrim(psContext);
bStartPrimitive = IMG_TRUE;
}
}
ErrorExit:
/*
End the primitive-block if we've had geometry
*/
if(!bStartPrimitive)
{
TACSWriteLastPrim(psContext);
}
#else /* NON_OPT_IDX_TRI_LIST */
/***********************************************************************************
* Optimised Indexed Triangle List *
***********************************************************************************/
IMG_UINT32 i;
IMG_INT32 i32NumVerts, j;
PVR_NATIVE_VERTEX asVertex[3], *apsVertex[3], *psVTmp, **ppsVertex;
IMG_UINT32 ui32ClipCode;
IMG_BOOL bNewStrip = IMG_TRUE, bPassCullTest;
IMG_UINT32 ui32NumStrips = 0;
IMG_UINT32 ui32IndexMask;
UNALIGNED IMG_UINT32 *pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
NTV_TYPE ntvDepthM = D3DM_Zero;
IMG_UINT32 ui32PrevIndices[3], ui32CurrentIndices[3];
IMG_UINT32 ui32StripCount = 1, ui32NextIndex = 2;
ui32IndexMask = psContext->ui32IndexMask;
psContext->eCurrentPrimType = D3DMPT_TRIANGLESTRIP;
/* initialise the vertex ptr array */
apsVertex[0] = &asVertex[0];
apsVertex[1] = &asVertex[1];
apsVertex[2] = &asVertex[2];
/* construct native vertices */
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, (*pui32IBData & ui32IndexMask)))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
ui32CurrentIndices[0] = (*pui32IBData & ui32IndexMask);
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + (ui32CurrentIndices[0] * ui32VBByteStride)),
ui32FVFcode,
apsVertex[0]);
/* Advance pointer */
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, (*pui32IBData & ui32IndexMask)))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
ui32CurrentIndices[1] = (*pui32IBData & ui32IndexMask);
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + (ui32CurrentIndices[1] * ui32VBByteStride)),
ui32FVFcode,
apsVertex[1]);
/* Advance pointer */
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Pick up last index and Advance pointer */
ui32CurrentIndices[2] = (*pui32IBData & ui32IndexMask);
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/************************
first time clip test
************************/
DoClipTestandVPTransform(psContext, &apsVertex[0], 2);
for(i=0; i<ui32PrimCount; i++)
{
IMG_BOOL bIsCounterClockwise;
/* construct native vertices */
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, ui32CurrentIndices[ui32NextIndex]))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + (ui32CurrentIndices[ui32NextIndex] * ui32VBByteStride)),
ui32FVFcode,
apsVertex[2]);
/* Store pointers to colours for flat shading */
psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse = &apsVertex[0]->sDiffuseOut;
psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular = &apsVertex[0]->sSpecularOut;
/**********************
clip test
**********************/
DoClipTestandVPTransform(psContext, &apsVertex[2], 1);
/**********************
Depth bias
**********************/
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
{
/* Calculate value of m */
NTV_TYPE ntvNewDepthM = TriangleMaxDepthSlope(apsVertex[0]);
/* if m is different from previous m then calculate depth bias offset */
if(ntvNewDepthM != ntvDepthM)
{
CalculateDepthBias(psContext,ntvNewDepthM);
ntvDepthM = ntvNewDepthM;
}
}
/* any vertices clipped? */
ui32ClipCode = (apsVertex[0]->ui32Flags
| apsVertex[1]->ui32Flags
| apsVertex[2]->ui32Flags) & D3DM_CLIPFLAG_MASK;
if ((ui32ClipCode & D3DM_CLIPFLAG_NEAR) == 0)
{
/* Check cull status */
bIsCounterClockwise = IsCounterClockWise(&apsVertex[0]);
switch(psContext->dwTAPrimCtl & MBX1_TAPRIM_CULLMODEMASK)
{
case MBX1_TAPRIM_CULLMODENONE:
bPassCullTest = IMG_TRUE;
break;
case MBX1_TAPRIM_CULLMODECW:
bPassCullTest = bIsCounterClockwise;
break;
case MBX1_TAPRIM_CULLMODECCW:
bPassCullTest = !bIsCounterClockwise;
break;
default:
///error
break;
}
if(((psContext->dwTAPrimCtl & MBX1_TAPRIM_CULLMODEMASK) != MBX1_TAPRIM_CULLMODENONE) &&
(ui32StripCount % 2) == 0)
{
/* Invert Cull sense on odd prims */
bPassCullTest = !bPassCullTest;
}
}
else
{
bPassCullTest = IMG_TRUE;
}
if(!bPassCullTest)
{
bNewStrip = IMG_TRUE;
}
else if (ui32ClipCode == 0) /* no clipping: */
{
if(bNewStrip)
{
if(ui32NumStrips)
{
TACSWriteEndPrim(psContext);
}
else
{
TACSWritePrimHdr(psContext, psContext->dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACESTRIP);
}
ui32NumStrips++;
ValidateVertex(psContext, &apsVertex[0], 3);
OutputVertices(psContext, &apsVertex[0], 3);
bNewStrip = IMG_FALSE;
}
else
{
ValidateVertex(psContext, &apsVertex[2], 1);
OutputVertices(psContext, &apsVertex[2], 1);
}
}
else if (!( apsVertex[0]->ui32Flags
& apsVertex[1]->ui32Flags
& apsVertex[2]->ui32Flags & D3DM_CLIPFLAG_MASK))
{
ValidateVertex(psContext, &apsVertex[0], 3);
i32NumVerts = DoPolygonClip(psContext, &apsVertex[0], 3, ui32ClipCode);
ppsVertex = psContext->sTState.sSWTNLState.ppsOutputArray;
if(ui32NumStrips)
{
TACSWriteLastPrim(psContext);
}
TACSWritePrimHdr(psContext, psContext->dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACEFAN);
if(!bNewStrip && (ui32ClipCode & D3DM_CLIPFLAG_NEAR) && ((ui32StripCount % 2) == 0))
{
/* Special case for optimised */
OutputVertices(psContext, ppsVertex, 1);
for(j = i32NumVerts-1; j>0; j--)
{
OutputVertices(psContext, ppsVertex+j, 1);
}
}
else
{
OutputVertices(psContext, ppsVertex, i32NumVerts);
}
TACSWriteLastPrim(psContext);
ui32NumStrips = 0;
bNewStrip = IMG_TRUE;
}
else
{
bNewStrip = IMG_TRUE;
}
/* We dont want to process any more indices if this is the last prim */
if(i == (ui32PrimCount - 1))
{
goto ErrorExit;
}
/* Store indices */
ui32PrevIndices[0] = ui32CurrentIndices[0];
ui32PrevIndices[1] = ui32CurrentIndices[1];
ui32PrevIndices[2] = ui32CurrentIndices[2];
/* Grab next 3 indices */
ui32CurrentIndices[0] = (*pui32IBData & ui32IndexMask);
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
ui32CurrentIndices[1] = (*pui32IBData & ui32IndexMask);
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
ui32CurrentIndices[2] = (*pui32IBData & ui32IndexMask);
pbIBData += ui32IBByteStride;
pui32IBData = (UNALIGNED IMG_UINT32*)pbIBData;
/* Optimise List to strip */
if((!bNewStrip) &&
((ui32StripCount % 2) == 1) &&
(ui32PrevIndices[1] == ui32CurrentIndices[0]) &&
(ui32PrevIndices[2] == ui32CurrentIndices[2]))
{
/* Setup vertex for processing on current strip */
psVTmp = apsVertex[0];
apsVertex[0] = apsVertex[1];
apsVertex[1] = apsVertex[2];
apsVertex[2] = psVTmp;
ui32NextIndex = 1;
ui32StripCount++;
}
else if((!bNewStrip) &&
((ui32StripCount % 2) == 0) &&
(ui32PrevIndices[1] == ui32CurrentIndices[1]) &&
(ui32PrevIndices[2] == ui32CurrentIndices[0]))
{
/* Setup vertex for processing on current strip */
psVTmp = apsVertex[0];
apsVertex[0] = apsVertex[1];
apsVertex[1] = apsVertex[2];
apsVertex[2] = psVTmp;
ui32NextIndex = 2;
ui32StripCount++;
}
else
{
/* End the current strip */
bNewStrip = IMG_TRUE;
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, ui32CurrentIndices[0]))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + (ui32CurrentIndices[0] * ui32VBByteStride)),
ui32FVFcode,
apsVertex[0]);
/* Validate index value to prevent access violations */
if(!VALIDATE_INDEX(psContext, ui32CurrentIndices[1]))
{
psContext->hrLastError = D3DMERR_INVALIDCALL;
goto ErrorExit;
}
SetupNativeVertex(psContext, (IMG_UINT32*)(pbVBData + (ui32CurrentIndices[1] * ui32VBByteStride)),
ui32FVFcode,
apsVertex[1]);
/************************
first time clip test
************************/
DoClipTestandVPTransform(psContext, &apsVertex[0], 2);
ui32NextIndex = 2;
ui32StripCount = 1;
}
}
ErrorExit:
/*
Finish the primitive block
*/
if(ui32NumStrips)
{
TACSWriteLastPrim(psContext);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -