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

📄 primindexed.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
<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 + -