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

📄 ctl.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ************************************************************************* *\
** ************************************************************************* **
**
**    INTEL Corporation Proprietary Information
**
**    This listing is supplied under the terms of a license
**    agreement with INTEL Corporation and may not be copied
**    nor disclosed except in accordance with the terms of
**    that agreement.
**
**    Copyright (c) 2004 Intel Corporation.
**    All Rights Reserved.
**
** ************************************************************************* **
**
**	FILE: CTL.c
**	DESCRIPTION: Common Transform & lighting Library implementation
**
**	CREATED: September 14, 2004
**
** ************************************************************************* **
\* ************************************************************************* */
#include "CTL.h"
#include "XPL.h"
#include "HXFTypes.h"
#include "HXFLocal.h"
#include "HXForm.h"
#include "HXFProfiler.h"

/* ************************************************************************* *\
** ************************************************************************* **
** Macros
** ************************************************************************* **
\* ************************************************************************* */
#define __CTL_GET_STATE(handle)  ((HXFState*)handle)


/* ************************************************************************* *\
** ************************************************************************* **
** Globals - Local
** ************************************************************************* **
\* ************************************************************************* */
static Matrix4x s_HSpaceScaleMatrix =
   {
   xHALF,     0,     0,    0,
       0, xHALF,     0,    0,
       0,     0, xHALF,    0,
   xHALF, xHALF, xHALF, xONE
   };

static Matrix4x s_YInvertMatrix =
   {
   xONE,     0,    0,    0,
      0, -xONE,    0,    0,
      0,     0, xONE,    0,
      0,     0,    0, xONE
   };


/* ************************************************************************* *\
** ************************************************************************* **
** Functions - Local
** ************************************************************************* **
\* ************************************************************************* */
static void Process_Fog( HXFState* pState )
   {
	float fr  = 0.0f;
	float fir = 0.0f;

   if( pState->ctl.FogStart == pState->FogEnd )
      {
      pState->FogInvRange = xONE;
      return;
      }  // if

	fr  = XtoF( pState->FogEnd - pState->ctl.FogStart );
	fir = 1.0f / fr;

	pState->FogInvRange = FtoX( fir );

   }  /* Process_Fog */


static void Process_Viewport( HXFState* pState )
   {
   CTL_VIEWPORT* psViewport = 0;
   HFIXED w, h, l, t;
   HFIXED s = xZERO, c = xONE;

   psViewport = &pState->ctl.sViewport;

   // NOTE: Viewport -- x and Y, Width and Height Pre-swapped in 90 and 270 cases.
	// So the viewport rectangle is not in a well defined state - the point could refer to any corner of the viewport
	switch( pState->ctl.eRotation )
      {
      case CTLROTATION_0:
         // 1 0
         // 0-1
         l = IasX( psViewport->i32X );
         t = IasX( pState->ctl.u32ScreenHeight - 
               ( psViewport->i32Y + psViewport->u32Height ));
         s = xZERO;
         c = xONE;
         break;  // CTLROTATION_0
      
      case CTLROTATION_90:
         // 0-1
         //-1 0
         l = IasX( pState->ctl.u32ScreenWidth - 
               ( psViewport->i32X + psViewport->u32Width ));
         t = IasX( pState->ctl.u32ScreenHeight - 
               ( psViewport->i32Y + psViewport->u32Height ));
         s = -xONE;
         c = xZERO;
         break;  // CTLROTATION_90
      
      case CTLROTATION_180:
         //-1 0
         // 0 1
         l = IasX( pState->ctl.u32ScreenWidth - 
               ( psViewport->i32X + psViewport->u32Width ));
         t = IasX( psViewport->i32Y );
         s = xZERO;
         c = -xONE;
         break;  // CTLROTATION_180
      
      case CTLROTATION_270:
         // 0 1
         // 1 0
         l = IasX( psViewport->i32X );
         t = IasX( psViewport->i32Y );
         s = xONE;
         c = xZERO;
         break;  // CTLROTATION_270
      
      default:
         HXFASSERT( 0 );
         break;  // default
      }  // switch

	w = IasX( psViewport->u32Width );
	h = IasX( psViewport->u32Height );

	pState->Viewport[0] = w;		                                 // XScale
	pState->Viewport[1] = h;		                                 // YScale
	pState->Viewport[2] = ( psViewport->Far - psViewport->Near );  // ZScale

	pState->Viewport[3] = l;	               // XTrans
	pState->Viewport[4] = t;	               // YTrans
	pState->Viewport[5] = psViewport->Near;   // ZTrans

	/*	rotation about the Z axis
		cos		sin		0	0
		-sin	cos		0	0
		0		0		1	0
		0		0		0	1
   */
	Matrix4x_SetIdentity( (X32*)&pState->ctl.mScreen );
	
	// Not just a rotation of the screen also contains a (180deg) rotation of the y Axis
	// for the transform from HSpace to Screen space. This rotation must be done prior to
	// the clipping so that the correct y coordinates are clipped. (This is required when the
	// clip space is defined as 0-1) since prior to the y rotation the y coordinate are -1-0 and
	// would be clipped in correctly.
	pState->ctl.mScreen.m11 =  c;	pState->ctl.mScreen.m21 = s;
	pState->ctl.mScreen.m12 = -s;	pState->ctl.mScreen.m22 = c;

	Matrix4x_Multiply( (X32*)&pState->ctl.mScreen, (X32*)&pState->ctl.mScreen, (X32*)&s_YInvertMatrix );
	Matrix4x_Multiply( (X32*)&pState->ctl.mScreen, (X32*)&pState->ctl.mScreen, (X32*)&s_HSpaceScaleMatrix );

   }  /* Process_Viewport */


/* ************************************************************************* *\
** ************************************************************************* **
** Functions - Interface
** ************************************************************************* **
\* ************************************************************************* */

/* ************************************************************************* *\
\* ************************************************************************* */
CTLHANDLE CTL_Init( void )
   {
   HXFState* pState = 0;
   CTLU32 i;
   
   if( 0 == ( pState = HXFAllocateState() ))
      {
      HXFASSERT( 0 );
      return CTLHANDLE_NULL;
      }  // if

   // Initialize fog parameters.
   pState->pfFogProc   = HXFFogExpProc;
   pState->FogDensity  = xONE;
   pState->FogEnd      = xONE;
   pState->FogInvRange = xONE;
   
   pState->FogXForm[0] = xZERO;
   pState->FogXForm[1] = xZERO;
   pState->FogXForm[2] = xONE;
   pState->FogXForm[3] = xZERO;
   
   pState->ctl.FogStart = xZERO;

   // Initialize light parameters.
   for( i = 0; i < CTLLIGHT_MAX_NUM; ++i )
      {
      HXFAlignedColor4S_Initialize( &pState->pLights[i].sAmbient );
      HXFAlignedColor4S_Initialize( &pState->pLights[i].sDiffuse );
      HXFAlignedColor4S_Initialize( &pState->pLights[i].sSpecular );

      pState->pLights[i].CosSpotCutoff  = HXF_MAX_FIXED;
      pState->pLights[i].Attenuation[1] = -xONE;
      }  // for

   // Initialize CTL specific state.
   pState->ctl.eRotation = CTLROTATION_0;

   pState->ctl.fPointSize = fONE;
   pState->ctl.fLineWidth = fONE;

	Matrix4x_SetIdentity( (X32*)&pState->ctl.mScreen );
	Matrix4x_SetIdentity( (X32*)&pState->ctl.mView );
	Matrix4x_SetIdentity( (X32*)&pState->ctl.mProj );

   pState->ctl.bfLightEnable = 0;

   pState->ctl.pLights = pState->pLights;

   HXFAlignedColor4S_Initialize( &pState->ctl.sAmbient );

   return pState;

   }  /* CTL_Init */


/* ************************************************************************* *\
\* ************************************************************************* */
CTLBOOL CTL_Done( CTLHANDLE h )
   {
   HXFState* pState = __CTL_GET_STATE( h );
   HXFFreeState( pState );
   
   return CTLTRUE;

   }  /* CTL_Done */


/* ************************************************************************* *\
\* ************************************************************************* */
static CTLBOOL SetupLighting( HXFState* pState )
   {
   Vector3x sEyeVector, sEye = { xZERO, xZERO, xONE };
   Matrix4x sMatrixInverse;
   int i;

   HXFALIGNEDCOLOR4S sMaterialAmbient;
   HXFALIGNEDCOLOR4S sMaterialDiffuse;
   HXFALIGNEDCOLOR4S sMaterialSpecular;

   HXFLight** ppHXFLightPrev = 0;

   HXFASSERT( 0 != pState );
   HXFAlignedColor4S_Initialize( &sMaterialAmbient );
   Color4s_Pack4x( (U16*)sMaterialAmbient.pClr, (HFIXED*)&pState->ctl.sMaterial.sAmbient );
   HXFAlignedColor4S_Initialize( &sMaterialDiffuse );
   Color4s_Pack4x( (U16*)sMaterialDiffuse.pClr, (HFIXED*)&pState->ctl.sMaterial.sDiffuse );
   HXFAlignedColor4S_Initialize( &sMaterialSpecular );
   Color4s_Pack4x( (U16*)sMaterialSpecular.pClr, (HFIXED*)&pState->ctl.sMaterial.sSpecular );
 
   if( 0 == ( HXF_LIGHT_ENABLE & pState->Flags ))
      {
      pState->pLights = 0;
      return CTLTRUE;
      }  // if

   if( FALSE == Matrix4x_Invert3x4( (X32*)&sMatrixInverse, (X32*)&pState->ctl.mView ))
      {
      return CTLFALSE;
      }  // if

   Vector3x_Transform( (X32*)&sEyeVector, (X32*)&sEye, (X32*)&sMatrixInverse );
   Vector3x_Normalize( (X32*)&sEyeVector, (X32*)&sEyeVector );
   Normal_Pack3x( (X16_14*)&pState->EyeVector, sEyeVector.x, sEyeVector.y, sEyeVector.z );

   if( HXF_LM_COLOR_CONSTANT & pState->Flags )
      {
      Color4s_Multiply( (U16*)&pState->MaterialAmbient, (U16*)sMaterialAmbient.pClr,
            (U16*)pState->ctl.sAmbient.pClr );       
      }  // if
   else
      {
      pState->MaterialAmbient = *sMaterialAmbient.pClr;
      }  // else

   // Setup light linking
   pState->pLights = 0;
   ppHXFLightPrev  = &pState->pLights;

   // Calculate each light's contribution
   for( i = 0; i < CTLLIGHT_MAX_NUM; ++i )
      {
      HXFLight*  pHXFLight  = &pState->ctl.pLights[i];
      CTL_LIGHT* pCTLLight  = &pState->ctl.asLights[i];
      HUINT32    LightNeeds = 0;

      HXFASSERT( 0 != pHXFLight );
      HXFASSERT( 0 != pCTLLight );

      if( 0 == (( 1L << i ) & pState->ctl.bfLightEnable ))
         {
         continue;
         }  // if
   
      if( HXF_SPECULAR_ENABLE & pState->Flags )
         {
         Color4s_Multiply( (U16*)&pHXFLight->Specular, (U16*)pHXFLight->sSpecular.pClr,
               (U16*)sMaterialSpecular.pClr );

         LightNeeds += 2;
         }  // if
      
      if( HXF_LM_COLOR_CONSTANT & pState->Flags )
         {
         LightNeeds += 1;
         }  // if

      pHXFLight->pfLightProc = g_pfLightProcs[pCTLLight->eType][LightNeeds];

      if( CTLLIGHT_POINT == pCTLLight->eType )
         {
         Vector3x tmp;

         // Position
         Vector4x_Transform( (X32*)&pHXFLight->Position, (X32*)&pCTLLight->sPosition, (X32*)&sMatrixInverse );
         // Pre negate w so MIA is a MIS ie Add -> Subtract in Point light proc.
         pHXFLight->Position.w = -pHXFLight->Position.w; 

         // Direction
         Vector3x_Transform3x3( (X32*)&tmp, (X32*)&pCTLLight->sDirection, (X32*)&sMatrixInverse );
         Vector3x_Normalize( (X32*)&tmp, (X32*)&tmp );
         Normal_Pack3x( (X16_14*)&pHXFLight->Direction, tmp.x, tmp.y, tmp.z );

         // Attenuation
         if(( pCTLLight->Attenuation[0] == xONE ) && 
            ( pCTLLight->Attenuation[1] == 0 ) && 
            ( pCTLLight->Attenuation[2] == 0 ))
            {
            pHXFLight->Attenuation[0] = 0;
            pHXFLight->Attenuation[1] = -xONE;
            pHXFLight->Attenuation[2] = 0;
            }  // if
         else
            {
            pHXFLight->Attenuation[0] = pCTLLight->Attenuation[0];
            pHXFLight->Attenuation[1] = pCTLLight->Attenuation[1];
            pHXFLight->Attenuation[2] = pCTLLight->Attenuation[2];
            }  // else

         }  // if - point/positional light
      else
         {
         Vector3x tmp;
         Vector3x_Transform3x3( (X32*)&tmp, (X32*)&pCTLLight->sPosition, (X32*)&sMatrixInverse );
         Vector3x_Normalize( (X32*)&tmp, (X32*)&tmp );
         Normal_Pack3x( (X16_14*)&pHXFLight->Direction, tmp.x, tmp.y, tmp.z );
         }  // else - directional light

      if( HXF_LM_COLOR_CONSTANT & pState->Flags )
         {
         // if( using material )
            {
            Color4s_Multiply( (U16*)&pHXFLight->Ambient, (U16*)pHXFLight->sAmbient.pClr,
                  (U16*)sMaterialAmbient.pClr );
            Color4s_Multiply( (U16*)&pHXFLight->Diffuse, (U16*)pHXFLight->sDiffuse.pClr,
                  (U16*)sMaterialDiffuse.pClr );
            }  // if
         //else
            {  // using current color
/*            HXFColor4S_Multiply( &pHXFLight->Ambient, pHXFLight->sAmbient.pClr,
                  gc->sState.sCurrent.sColor.pClr );
            HXFColor4S_Multiply( &pHXFLight->Diffuse, pHXFLight->sDiffuse.pClr,
                  gc->sState.sCurrent.sColor.pClr );
*/
            }  // else
         
         }  // if
      else
         {
         pHXFLight->Ambient = *pHXFLight->sAmbient.pClr;
         pHXFLight->Diffuse = *pHXFLight->sDiffuse.pClr;
         }  // else

      *ppHXFLightPrev = pHXFLight;
      ppHXFLightPrev = &pHXFLight->pNext;

      }  // for - each light's contribution

   *ppHXFLightPrev = 0;

   return CTLTRUE;

   }  /* SetupLighting */


static void SetupPrimitiveType( HXFState* pState, CTL_PRIMITIVE_TYPE eType )
   {
	pState->Flags &= ~(HXF_HAS_PRIMITIVE_SIZE | HXF_PT_MASK);
   switch( eType )
      {
      case CTLPRIMITIVE_POINTS:
   		pState->Flags |= HXF_SET_PT(HXF_PT_POINT_LIST);
		   pState->Flags |= HXF_HAS_PRIMITIVE_SIZE;
         pState->PrimitiveSize = pState->ctl.fPointSize;
         break;  // CTLPRIMITIVE_POINTS

      case CTLPRIMITIVE_LINELIST:
   		pState->Flags |= HXF_SET_PT(HXF_PT_LINE_LIST);
		   pState->Flags |= HXF_HAS_PRIMITIVE_SIZE;
         pState->PrimitiveSize = pState->ctl.fLineWidth;
         break;  // CTLPRIMITIVE_LINELIST

      case CTLPRIMITIVE_LINESTRIP:
   		pState->Flags |= HXF_SET_PT(HXF_PT_LINE_STRIP);
	   	pState->Flags |= HXF_HAS_PRIMITIVE_SIZE;
         pState->PrimitiveSize = pState->ctl.fLineWidth;
         break;  // CTLPRIMITIVE_LINESTRIP

      case CTLPRIMITIVE_LINELOOP:
   		pState->Flags |= HXF_SET_PT(HXF_PT_LINE_LOOP);
   		pState->Flags |= HXF_HAS_PRIMITIVE_SIZE;
         pState->PrimitiveSize = pState->ctl.fLineWidth;
         break;  // CTLPRIMITIVE_LINELOOP

      case CTLPRIMITIVE_TRILIST:
   		pState->Flags |= HXF_SET_PT(HXF_PT_TRI_LIST);
         break;  // CTLPRIMITIVE_TRILIST

      case CTLPRIMITIVE_TRISTRIP:
   		pState->Flags |= HXF_SET_PT(HXF_PT_TRI_STRIP);
         break;  // CTLPRIMITIVE_TRISTRIP

      case CTLPRIMITIVE_TRIFAN:
   		pState->Flags |= HXF_SET_PT(HXF_PT_TRI_FAN);
         break;  // CTLPRIMITIVE_TRIFAN

      default:
         HXFASSERT( 0 );
         break;  // default

      }  // switch

   }  /* SetupPrimitiveType */


static void SetupPointers( HXFState* pState )
   {
   // Offset array pointers by minimum index.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -