You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
9.6 KiB
293 lines
9.6 KiB
#ifndef __CLIPPER_HPP_
|
|
#define __CLIPPER_HPP_
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipping macros
|
|
//----------------------------------------------------------------------------
|
|
// Interpolation flags
|
|
#define RRCLIP_INTERPOLATE_COLOR (1<< 0)
|
|
#define RRCLIP_INTERPOLATE_SPECULAR (1<< 1)
|
|
#define RRCLIP_INTERPOLATE_TEXTURE (1<< 2)
|
|
#define RRCLIP_INTERPOLATE_S (1<< 3)
|
|
#define RRCLIP_INTERPOLATE_EYENORMAL (1<< 4)
|
|
#define RRCLIP_INTERPOLATE_EYEXYZ (1<< 5)
|
|
|
|
// Non guardband clipping bits
|
|
#define RRCLIP_LEFT D3DCLIP_LEFT
|
|
#define RRCLIP_RIGHT D3DCLIP_RIGHT
|
|
#define RRCLIP_TOP D3DCLIP_TOP
|
|
#define RRCLIP_BOTTOM D3DCLIP_BOTTOM
|
|
#define RRCLIP_FRONT D3DCLIP_FRONT
|
|
#define RRCLIP_BACK D3DCLIP_BACK
|
|
|
|
//----------------------------------------------------------------------------
|
|
// User define clip plane bits.
|
|
// Each of these bits is set if the vertex is clipped by the associated
|
|
// clip plane.
|
|
//----------------------------------------------------------------------------
|
|
#define RRCLIP_USERCLIPPLANE0 D3DCLIP_GEN0
|
|
#define RRCLIP_USERCLIPPLANE1 D3DCLIP_GEN1
|
|
#define RRCLIP_USERCLIPPLANE2 D3DCLIP_GEN2
|
|
#define RRCLIP_USERCLIPPLANE3 D3DCLIP_GEN3
|
|
#define RRCLIP_USERCLIPPLANE4 D3DCLIP_GEN4
|
|
#define RRCLIP_USERCLIPPLANE5 D3DCLIP_GEN5
|
|
const DWORD RRCLIP_USERPLANES_ALL = (RRCLIP_USERCLIPPLANE0 |
|
|
RRCLIP_USERCLIPPLANE1 |
|
|
RRCLIP_USERCLIPPLANE2 |
|
|
RRCLIP_USERCLIPPLANE3 |
|
|
RRCLIP_USERCLIPPLANE4 |
|
|
RRCLIP_USERCLIPPLANE5 );
|
|
|
|
//---------------------------------------------------------------------
|
|
// Guard band clipping bits
|
|
//
|
|
// A guard bit is set when a point is out of guard band
|
|
// Guard bits should be cleared before a call to clip a triangle, because
|
|
// they are the same as CLIPPED_... bits
|
|
//
|
|
// Example of clipping bits setting for X coordinate:
|
|
//
|
|
// if -w < x < w no clipping bit is set
|
|
// if -w*ax1 < x <= -w RRCLIP_LEFT bit is set
|
|
// if x < -w*ax1 RRCLIPGB_LEFT bit is set
|
|
//---------------------------------------------------------------------
|
|
|
|
#define RRCLIPGB_LEFT (RRCLIP_USERCLIPPLANE5 << 1)
|
|
#define RRCLIPGB_RIGHT (RRCLIP_USERCLIPPLANE5 << 2)
|
|
#define RRCLIPGB_TOP (RRCLIP_USERCLIPPLANE5 << 3)
|
|
#define RRCLIPGB_BOTTOM (RRCLIP_USERCLIPPLANE5 << 4)
|
|
|
|
|
|
|
|
|
|
#define RRCLIP_ALL (RRCLIP_LEFT | RRCLIP_RIGHT | \
|
|
RRCLIP_TOP | RRCLIP_BOTTOM | \
|
|
RRCLIP_FRONT | RRCLIP_BACK | \
|
|
RRCLIP_USERPLANES_ALL)
|
|
|
|
#define RRCLIPGB_ALL (RRCLIPGB_LEFT | RRCLIPGB_RIGHT | \
|
|
RRCLIPGB_TOP | RRCLIPGB_BOTTOM | \
|
|
RRCLIP_FRONT | RRCLIP_BACK | \
|
|
RRCLIP_USERPLANES_ALL)
|
|
|
|
// If only these bits are set, then this point is inside the guard band
|
|
#define RRCLIP_INGUARDBAND (RRCLIP_LEFT | RRCLIP_RIGHT | \
|
|
RRCLIP_TOP | RRCLIP_BOTTOM)
|
|
//---------------------------------------------------------------------
|
|
// Bit numbers for each clip flag
|
|
//
|
|
#define RRCLIP_LEFTBIT 1
|
|
#define RRCLIP_RIGHTBIT 2
|
|
#define RRCLIP_TOPBIT 3
|
|
#define RRCLIP_BOTTOMBIT 4
|
|
#define RRCLIP_FRONTBIT 5
|
|
#define RRCLIP_BACKBIT 6
|
|
|
|
#define RRCLIP_USERCLIPLANE0BIT 7
|
|
#define RRCLIP_USERCLIPLANE1BIT 8
|
|
#define RRCLIP_USERCLIPLANE2BIT 9
|
|
#define RRCLIP_USERCLIPLANE3BIT 10
|
|
#define RRCLIP_USERCLIPLANE4BIT 11
|
|
#define RRCLIP_USERCLIPLANE5BIT 12
|
|
|
|
#define RRCLIPGB_LEFTBIT 13
|
|
#define RRCLIPGB_RIGHTBIT 14
|
|
#define RRCLIPGB_TOPBIT 15
|
|
#define RRCLIPGB_BOTTOMBIT 16
|
|
|
|
#define CLIPPED_LEFT (RRCLIP_USERCLIPPLANE5 << 1)
|
|
#define CLIPPED_RIGHT (RRCLIP_USERCLIPPLANE5 << 2)
|
|
#define CLIPPED_TOP (RRCLIP_USERCLIPPLANE5 << 3)
|
|
#define CLIPPED_BOTTOM (RRCLIP_USERCLIPPLANE5 << 4)
|
|
#define CLIPPED_FRONT (RRCLIP_USERCLIPPLANE5 << 5)
|
|
#define CLIPPED_BACK (RRCLIP_USERCLIPPLANE5 << 6)
|
|
|
|
#define CLIPPED_ENABLE (RRCLIP_USERCLIPPLANE5 << 7) // wireframe enable flag
|
|
|
|
#define CLIPPED_ALL (CLIPPED_LEFT|CLIPPED_RIGHT \
|
|
|CLIPPED_TOP|CLIPPED_BOTTOM \
|
|
|CLIPPED_FRONT|CLIPPED_BACK)
|
|
|
|
const DWORD CLIPPED_USERCLIPPLANE0 = RRCLIP_USERCLIPPLANE5 << 8;
|
|
const DWORD CLIPPED_USERCLIPPLANE1 = RRCLIP_USERCLIPPLANE5 << 9;
|
|
const DWORD CLIPPED_USERCLIPPLANE2 = RRCLIP_USERCLIPPLANE5 << 10;
|
|
const DWORD CLIPPED_USERCLIPPLANE3 = RRCLIP_USERCLIPPLANE5 << 11;
|
|
const DWORD CLIPPED_USERCLIPPLANE4 = RRCLIP_USERCLIPPLANE5 << 12;
|
|
const DWORD CLIPPED_USERCLIPPLANE5 = RRCLIP_USERCLIPPLANE5 << 13;
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// Make clip vertex from D3D vertex
|
|
//
|
|
// device - DIRECT3DDEVICEI *
|
|
// cn - clipVertex
|
|
// pVtx - a TL vertex
|
|
// qwFVF - FVF of the input TL vertex
|
|
//---------------------------------------------------------------------
|
|
inline void
|
|
MakeClipVertexFromFVF( RRCLIPVTX& cv, LPVOID pVtx,
|
|
const RRVIEWPORTDATA& VData,
|
|
DWORD dwTexCoordSize,
|
|
UINT64 qwFVF, DWORD dwClipFlag,
|
|
DWORD dwClipMask)
|
|
{
|
|
LPBYTE pv = (LPBYTE)pVtx;
|
|
|
|
// If the clip flag for this vertex is set, that means that the
|
|
// transformation loop has not computed the screen coordinates for
|
|
// this vertex, it has simply stored the clip coordinates for this
|
|
// vertex
|
|
|
|
#if 0
|
|
float x = *(D3DVALUE *)&((DWORD *)pv)[0]
|
|
float y = *(D3DVALUE *)&((DWORD *)pv)[1]
|
|
float z = *(D3DVALUE *)&((DWORD *)pv)[2]
|
|
float w = *(D3DVALUE *)&((DWORD *)pv)[3]
|
|
#endif
|
|
|
|
if (dwClipFlag & dwClipMask)
|
|
{
|
|
// This is a clipped vertex, simply no screen coordinates
|
|
cv.sx = D3DVALUE(0);
|
|
cv.sy = D3DVALUE(0);
|
|
cv.sz = D3DVALUE(0);
|
|
cv.rhw = D3DVALUE(0);
|
|
|
|
// Since this vertex has been clipped, the transformation loop
|
|
// has put in the clip coordinates instead
|
|
cv.hx = ((D3DVALUE*)pv)[0];
|
|
cv.hy = ((D3DVALUE*)pv)[1];
|
|
cv.hz = ((D3DVALUE*)pv)[2];
|
|
cv.hw = ((D3DVALUE*)pv)[3];
|
|
}
|
|
else
|
|
{
|
|
// This vertex is not clipped, so its screen coordinates have been
|
|
// computed
|
|
cv.sx = ((D3DVALUE*)pv)[0];
|
|
cv.sy = ((D3DVALUE*)pv)[1];
|
|
cv.sz = ((D3DVALUE*)pv)[2];
|
|
cv.rhw = ((D3DVALUE*)pv)[3];
|
|
|
|
// Transform the screen coordinate back to the clipping space
|
|
cv.hw = 1.0f / cv.rhw;
|
|
cv.hx = (cv.sx - VData.offsetX) * cv.hw * VData.scaleXi;
|
|
cv.hy = (cv.sy - VData.offsetY) * cv.hw * VData.scaleYi;
|
|
cv.hz = (cv.sz - VData.offsetZ) * cv.hw * VData.scaleZi;
|
|
|
|
}
|
|
|
|
pv += sizeof(D3DVALUE) * 4;
|
|
if (qwFVF & D3DFVF_DIFFUSE)
|
|
{
|
|
cv.color = *(DWORD*)pv;
|
|
pv += sizeof(D3DVALUE);
|
|
|
|
}
|
|
if (qwFVF & D3DFVF_SPECULAR)
|
|
{
|
|
cv.specular= *(DWORD*)pv;
|
|
pv += sizeof(DWORD);
|
|
}
|
|
memcpy(cv.tex, pv, dwTexCoordSize);
|
|
pv += dwTexCoordSize;
|
|
if (qwFVF & D3DFVF_S)
|
|
{
|
|
cv.s= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
if (qwFVF & D3DFVFP_EYENORMAL)
|
|
{
|
|
cv.eyenx= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
cv.eyeny= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
cv.eyenz= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
if (qwFVF & D3DFVFP_EYEXYZ)
|
|
{
|
|
cv.eyex= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
cv.eyey= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
cv.eyez= *(FLOAT*)pv;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
cv.clip = dwClipFlag;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Make TL vertex from clip vertex
|
|
//
|
|
// device - DIRECT3DDEVICEI *
|
|
// in - clipVertex
|
|
// out - TL vertex
|
|
//---------------------------------------------------------------------
|
|
inline void
|
|
MakeFVFVertexFromClip(LPVOID out, RRCLIPVTX *cv,
|
|
UINT64 qwFVF, DWORD dwTexCoordSize)
|
|
{
|
|
LPBYTE pv = (LPBYTE)out;
|
|
((D3DVALUE*)pv)[0] = cv->sx;
|
|
((D3DVALUE*)pv)[1] = cv->sy;
|
|
((D3DVALUE*)pv)[2] = cv->sz;
|
|
((D3DVALUE*)pv)[3] = D3DVAL(1)/cv->hw;
|
|
pv += sizeof(D3DVALUE)*4;
|
|
if (qwFVF & D3DFVF_DIFFUSE)
|
|
{
|
|
*(DWORD*)pv = cv->color;
|
|
pv += sizeof(DWORD);
|
|
}
|
|
if (qwFVF & D3DFVF_SPECULAR)
|
|
{
|
|
*(DWORD*)pv = cv->specular;
|
|
pv += sizeof(DWORD);
|
|
}
|
|
memcpy(pv, &cv->tex, dwTexCoordSize);
|
|
pv += dwTexCoordSize;
|
|
if (qwFVF & D3DFVF_S)
|
|
{
|
|
*(FLOAT*)pv = cv->s;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
if (qwFVF & D3DFVFP_EYENORMAL)
|
|
{
|
|
*(FLOAT*)pv = cv->eyenx;
|
|
pv += sizeof(FLOAT);
|
|
*(FLOAT*)pv = cv->eyeny;
|
|
pv += sizeof(FLOAT);
|
|
*(FLOAT*)pv = cv->eyenz;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
if (qwFVF & D3DFVFP_EYEXYZ)
|
|
{
|
|
*(FLOAT*)pv = cv->eyex;
|
|
pv += sizeof(FLOAT);
|
|
*(FLOAT*)pv = cv->eyey;
|
|
pv += sizeof(FLOAT);
|
|
*(FLOAT*)pv = cv->eyez;
|
|
pv += sizeof(FLOAT);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Returns TRUE if clipping is needed
|
|
//---------------------------------------------------------------------
|
|
inline BOOL
|
|
NeedClipping(BOOL bUseGB, RRCLIPCODE clipUnion)
|
|
{
|
|
if( bUseGB && (clipUnion & ~RRCLIP_INGUARDBAND) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else if( clipUnion )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#endif //__CLIPPER_HPP_
|