📄 ctl.c
字号:
/* ************************************************************************* *\
** ************************************************************************* **
**
** 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 + -