91 lines
3.1 KiB
C++
91 lines
3.1 KiB
C++
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// Copyright (C) Microsoft Corporation, 2000.
|
||
|
//
|
||
|
// rastedge.cpp
|
||
|
//
|
||
|
// Direct3D Reference Device - Edge Function Processing
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
#include "pch.cpp"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Set - Computes edge function and associated information.
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void
|
||
|
RDEdge::Set(
|
||
|
BOOL bDetPositive,
|
||
|
INT32 iX0, INT32 iY0,
|
||
|
INT32 iX1, INT32 iY1)
|
||
|
{
|
||
|
// compute A,B (gradient) terms - these are n.4 fixed point
|
||
|
m_iA = iY0 - iY1;
|
||
|
m_iB = iX1 - iX0;
|
||
|
|
||
|
// flip gradient signs if backfacing so functions are consistently
|
||
|
// greater than zero outside of primitive
|
||
|
if ( bDetPositive ) { m_iA = -m_iA; m_iB = -m_iB; }
|
||
|
|
||
|
// compute C term
|
||
|
//
|
||
|
// function is by definition zero at the vertices, so:
|
||
|
// 0 = A*Xv + B*Yv + C => C = - A*Xv - B*Yv
|
||
|
//
|
||
|
// A*Xv & B*Yv are n.4 * n.4 = n.8, so C is n.8 fixed point
|
||
|
m_iC = - ( (INT64)iX0 * (INT64)m_iA ) - ( (INT64)iY0 * (INT64)m_iB );
|
||
|
|
||
|
// compute edge function sign flags - must be done consistently for vertical
|
||
|
// and horizontal cases to adhere to point sample fill rules
|
||
|
BOOL bEdgeAEQZero = ( m_iA == 0. );
|
||
|
BOOL bEdgeBEQZero = ( m_iB == 0. );
|
||
|
BOOL bEdgeAGTZero = ( m_iA > 0. );
|
||
|
BOOL bEdgeBGTZero = ( m_iB > 0. );
|
||
|
m_bAPos = bEdgeAEQZero ? bEdgeBGTZero : bEdgeAGTZero;
|
||
|
m_bBPos = bEdgeBEQZero ? bEdgeAGTZero : bEdgeBGTZero;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Supports the Direct3D left-top fill rule.
|
||
|
//
|
||
|
// inputs are n.4 floating point
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
RDEdge::Test( INT32 iX, INT32 iY )
|
||
|
{
|
||
|
// evaluate edge distance function (n.8 fixed point)
|
||
|
INT64 iEdgeDist =
|
||
|
( (INT64)m_iA * (INT64)iX ) + // n.4 * n.4 = n.8
|
||
|
( (INT64)m_iB * (INT64)iY ) + // n.4 * n.4 = n.8
|
||
|
(INT64)m_iC; // n.8
|
||
|
|
||
|
// pixel sample position is outside edge if distance is > zero
|
||
|
//
|
||
|
// This implements the D3D left-top fill rule
|
||
|
//
|
||
|
// For exactly-on-edge case (distance == zero), the sign of the Y gradient
|
||
|
// is used to determine if the pixel is to be considered inside or outside
|
||
|
// of the edge. For the non-horizontal case, the m_bAPos bit is based
|
||
|
// simply on the sign of the Y slope. This implements the 'left' part of
|
||
|
// the 'left-top' rule.
|
||
|
//
|
||
|
// For the horizontal case, the sign of the B gradient (X slope) is taken
|
||
|
// into account in the computation of the m_bAPos bit when the A gradient
|
||
|
// is exactly zero, which forces a pixel exactly on a 'top' edge to be
|
||
|
// considered in and a pixel exactly on a 'bottom' edge to be considered out.
|
||
|
//
|
||
|
if ( ( iEdgeDist > 0 ) || ( ( iEdgeDist == 0 ) && m_bAPos ) )
|
||
|
{
|
||
|
// pixel is out
|
||
|
return FALSE;
|
||
|
}
|
||
|
// pixel is in
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// end
|