📄 matrix.c
字号:
/***********************************************************************************
Function Name : glLoadMatrix[f/x]
Inputs : m
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets the current matrix to the incoming data.
************************************************************************************/
#if defined( PROFILE_COMMON )
GLAPI void APIENTRY glLoadMatrixf( GLfloat const * m )
{
Matrix4f* pMat = 0;
__GL_GET_CONTEXT();
if( !m )
{
SetError( gc, GL_INVALID_VALUE );
return;
} // if
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
memcpy( pMat, m, sizeof( *pMat ));
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glLoadMatrixf */
GLAPI void APIENTRY glLoadMatrixx( GLfixed const * m )
{
GLfloat mf[16] = { 0.0f };
ArrayXtoF( mf, m, 16 );
glLoadMatrixf( mf );
} /* glLoadMatrixx */
#elif defined( PROFILE_COMMON_LITE )
GLAPI void APIENTRY glLoadMatrixx( GLfixed const * m )
{
Matrix4x* pMat = 0;
__GL_GET_CONTEXT();
if( !m )
{
SetError( gc, GL_INVALID_VALUE );
return;
} // if
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
memcpy( pMat, m, sizeof( *pMat ));
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glLoadMatrixx */
#else
#error "Profile not defined for glFrustum"
#endif /* PROFILE */
/***********************************************************************************
Function Name : glMultMatrix[f/x]
Inputs : m
Outputs : -
Returns : -
Description : ENTRYPOINT: Multiplies the current matrix by the incoming data.
************************************************************************************/
#if defined( PROFILE_COMMON )
GLAPI void APIENTRY glMultMatrixf( GLfloat const * m )
{
Matrix4f* pMat = 0;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
if( !m )
{
SetError( gc, GL_INVALID_VALUE );
return;
} // if
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4f_Multiply( (F32*)pMat, (F32*)m, (F32*)pMat );
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glMultMatrixf */
GLAPI void APIENTRY glMultMatrixx( GLfixed const * m )
{
GLfloat mf[16] = { 0.0f };
ArrayXtoF( mf, m, 16 );
glMultMatrixf( mf );
} /* glMultMatrixx */
#elif defined( PROFILE_COMMON_LITE )
GLAPI void APIENTRY glMultMatrixx( GLfixed const * m )
{
Matrix4x* pMat = 0;
__GL_GET_CONTEXT();
if( !m )
{
SetError( gc, GL_INVALID_VALUE );
return;
} // if
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4x_Multiply( (X32*)pMat, (X32*)m, (X32*)pMat );
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glMultMatrixx */
#else
#error "Profile not defined for glMultMatrix"
#endif /* PROFILE */
/***********************************************************************************
Function Name : glRotate[f/x]
Inputs : fAngle, x, y, z
Outputs : -
Returns : -
Description : ENTRYPOINT: Multiplies the current matrix by a rotation matrix
************************************************************************************/
#if defined( PROFILE_COMMON )
GLAPI void APIENTRY glRotatef( GLfloat fAngle, GLfloat x, GLfloat y, GLfloat z )
{
Matrix4f* pMat = 0;
Matrix4f tmp;
F32 s, c;
BOOL optimized = FALSE;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4f_SetIdentity( (F32*)&tmp );
// s = HSinFX( angle );
// c = HCosFX( angle );
// -- FIXME Debug impl to check accuracy.
s = (F32)sin( fAngle * fDEG_TO_RAD );
c = (F32)cos( fAngle * fDEG_TO_RAD );
// FIXME - add epsilon
if( x == fZERO )
{
if( y == fZERO )
{
if( z != fZERO )
{
optimized = TRUE;
/* rotate only around z-axis */
tmp._11 = c;
tmp._22 = c;
if( z < fZERO )
{
tmp._12 = -s;
tmp._21 = s;
} // if
else
{
tmp._12 = s;
tmp._21 = -s;
} // else
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
} // if
} // if
else if( z == fZERO )
{
optimized = TRUE;
/* rotate only around y-axis */
tmp._11 = c;
tmp._33 = c;
if( y < fZERO )
{
tmp._13 = s;
tmp._31 = -s;
} // if
else
{
tmp._13 = -s;
tmp._31 = s;
} // else
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
} // if
} // if
else if( y == fZERO )
{
if( z == fZERO )
{
optimized = TRUE;
/* rotate only around x-axis */
tmp._22 = c;
tmp._33 = c;
if( x < fZERO )
{
tmp._23 = -s;
tmp._32 = s;
} // if
else
{
tmp._23 = s;
tmp._32 = -s;
} // else
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
} // if
} // if
if( !optimized )
{
F32 T, AB, BC, CA, xs, ys, zs, one_c, l;
F32 const mag = x * x + y * y + z * z;
if( mag <= 0x00000001 ) // FIXME
{
return; /* no rotation, leave mat as-is */
} // if
l = 1.0f / (float)sqrt( mag );
x = x * l;
y = y * l;
z = z * l;
xs = x * s;
ys = y * s;
zs = z * s;
one_c = fONE - c;
AB = x * y * one_c;
BC = y * z * one_c;
CA = z * x * one_c;
T = x * x;
tmp._11 = T + c * ( fONE - T );
tmp._32 = BC - xs;
tmp._23 = BC + xs;
T = y * y;
tmp._22 = T + c * ( fONE - T );
tmp._31 = CA + ys;
tmp._13 = CA - ys;
T = z * z;
tmp._33 = T + c * ( fONE - T );
tmp._21 = AB - zs;
tmp._12 = AB + zs;
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
}
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glRotatef */
GLAPI void APIENTRY glRotatex( GLfixed angle, GLfixed x, GLfixed y, GLfixed z )
{
glRotatef( XtoF( angle ), XtoF( x ), XtoF( y ), XtoF( z ));
} /* glRotatex */
#elif defined( PROFILE_COMMON_LITE )
GLAPI void APIENTRY glRotatex( GLfixed angle, GLfixed x, GLfixed y, GLfixed z )
{
Matrix4x* pMat = 0;
Matrix4x tmp;
X32 s, c;
BOOL optimized = FALSE;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4x_SetIdentity( (X32*)&tmp );
// s = HSinFX( angle );
// c = HCosFX( angle );
// -- FIXME Debug impl to check accuracy.
s = FtoX( (float)sin( XtoF( angle ) * fDEG_TO_RAD ));
c = FtoX( (float)cos( XtoF( angle ) * fDEG_TO_RAD ));
if( x == xZERO )
{
if( y == xZERO )
{
if( z != xZERO )
{
optimized = TRUE;
/* rotate only around z-axis */
tmp._11 = c;
tmp._22 = c;
if( z < xZERO )
{
tmp._12 = -s;
tmp._21 = s;
} // if
else
{
tmp._12 = s;
tmp._21 = -s;
} // else
Matrix4x_Multiply( (X32*)pMat, (X32*)&tmp, (X32*)pMat );
} // if
} // if
else if( z == xZERO )
{
optimized = TRUE;
/* rotate only around y-axis */
tmp._11 = c;
tmp._33 = c;
if( y < xZERO )
{
tmp._13 = s;
tmp._31 = -s;
} // if
else
{
tmp._13 = -s;
tmp._31 = s;
} // else
Matrix4x_Multiply( (X32*)pMat, (X32*)&tmp, (X32*)pMat );
} // if
} // if
else if( y == xZERO )
{
if( z == xZERO )
{
optimized = TRUE;
/* rotate only around x-axis */
tmp._22 = c;
tmp._33 = c;
if( x < xZERO )
{
tmp._23 = -s;
tmp._32 = s;
} // if
else
{
tmp._23 = s;
tmp._32 = -s;
} // else
Matrix4x_Multiply( (X32*)pMat, (X32*)&tmp, (X32*)pMat );
} // if
} // if
if( !optimized )
{
X32 T, AB, BC, CA, xs, ys, zs, one_c, l;
X32 const mag = Fixed_Mul( x, x ) + Fixed_Mul( y, y ) + Fixed_Mul( z, z );
if( mag <= 0x00000001 ) // FIXME
{
HXFASSERT(0);
return; /* no rotation, leave mat as-is */
} // if
l = Fixed_InvSqrt( mag );
x = Fixed_Mul( x, l );
y = Fixed_Mul( y, l );
z = Fixed_Mul( z, l );
xs = Fixed_Mul( x, s );
ys = Fixed_Mul( y, s );
zs = Fixed_Mul( z, s );
one_c = xONE - c;
AB = Fixed_Mul( x, Fixed_Mul( y, one_c ));
BC = Fixed_Mul( y, Fixed_Mul( z, one_c ));
CA = Fixed_Mul( z, Fixed_Mul( x, one_c ));
T = Fixed_Mul( x, x );
tmp._11 = T + Fixed_Mul( c, xONE - T );
tmp._32 = BC - xs;
tmp._23 = BC + xs;
T = Fixed_Mul( y, y );
tmp._22 = T + Fixed_Mul( c, xONE - T );
tmp._31 = CA + ys;
tmp._13 = CA - ys;
T = Fixed_Mul( z, z );
tmp._33 = T + Fixed_Mul( c, xONE - T );
tmp._21 = AB - zs;
tmp._12 = AB + zs;
Matrix4x_Multiply( (X32*)pMat, (X32*)&tmp, (X32*)pMat );
}
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glRotatex */
#else
#error "Profile not defined for glRotate"
#endif /* PROFILE */
/***********************************************************************************
Function Name : glScale[f/x]
Inputs : x, y, z
Outputs : -
Returns : -
Description : ENTRYPOINT: Multiplies the current matrix by a scaling matrix
************************************************************************************/
#if defined( PROFILE_COMMON )
GLAPI void APIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z )
{
Matrix4f* pMat = 0;
Matrix4f tmp;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4f_SetIdentity( (F32*)&tmp );
tmp._11 = x;
tmp._22 = y;
tmp._33 = z;
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glScalef */
GLAPI void APIENTRY glScalex( GLfixed x, GLfixed y, GLfixed z )
{
glScalef( XtoF( x ), XtoF( y ), XtoF( z ));
} /* glScalex */
#elif defined( PROFILE_COMMON_LITE )
GLAPI void APIENTRY glScalex( GLfixed x, GLfixed y, GLfixed z )
{
Matrix4x* pMat = 0;
Matrix4x tmp;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4x_SetIdentity( (X32*)&tmp );
tmp._11 = x;
tmp._22 = y;
tmp._33 = z;
Matrix4x_Multiply( (X32*)pMat, (X32*)&tmp, (X32*)pMat );
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glScalex */
#else
#error "Profile not defined for glScale"
#endif /* PROFILE */
/***********************************************************************************
Function Name : glTranslate[f/x]
Inputs : x, y, z
Outputs : -
Returns : -
Description : ENTRYPOINT: Multiplies the current matrix by a translation matrix
************************************************************************************/
#if defined( PROFILE_COMMON )
GLAPI void APIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z )
{
Matrix4f* pMat = 0;
Matrix4f tmp;
__GL_GET_CONTEXT();
HXF_PROFILER_START( HXFPROFILE_STATE_MATRIX );
pMat = gc->sProcs.pfnGetCurrentMatrix( gc, TRUE );
Matrix4f_SetIdentity( (F32*)&tmp );
tmp._41 = x;
tmp._42 = y;
tmp._43 = z;
Matrix4f_Multiply( (F32*)pMat, (F32*)&tmp, (F32*)pMat );
HXF_PROFILER_STOP( HXFPROFILE_STATE_MATRIX );
} /* glTranslatef */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -