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.
171 lines
5.8 KiB
171 lines
5.8 KiB
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: procver.h
|
|
* Content: Generic implementation for process vertices function
|
|
*
|
|
* This file is included several times with different defines:
|
|
* _PV_NAME - function name
|
|
* _PV_EXTENT - if updating extent is required
|
|
* _PV_CLIP - if clipping is required
|
|
* _PV_VIEWPORT - if the function is used by TransformVertices call
|
|
* _PV_LVERTEX - if D3DLVERTEX is used as input
|
|
* _PV_APPLY_LIGHT - if lighting is required
|
|
* _PV_FOG - if fog is required
|
|
*
|
|
***************************************************************************/
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Viewport->TransformVertices
|
|
// For clipped and unclipped cases
|
|
// for unclipped case H vertices should not be written
|
|
//
|
|
long _PV_NAME(D3DFE_PROCESSVERTICES *pv, DWORD count, LPD3DTRANSFORMDATAI data)
|
|
{
|
|
// We use power of 2 because it preserves the mantissa when we multiply
|
|
const D3DVALUE __HUGE_PWR2 = 1024.0f*1024.0f*2.0f;
|
|
CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
|
|
|
|
D3DLVERTEX* in = (LPD3DLVERTEX)data->lpIn;
|
|
size_t in_size = data->dwInSize;
|
|
D3DTLVERTEX *out =(LPD3DTLVERTEX) data->lpOut;
|
|
size_t out_size = data->dwOutSize;
|
|
DWORD i;
|
|
DWORD flags = pv->dwFlags;
|
|
#ifdef _PV_CLIP
|
|
D3DHVERTEX *hout = data->lpHOut;
|
|
int clip_intersection = ~0;
|
|
int clip_union = 0;
|
|
#endif // _PV_CLIP
|
|
D3DVALUE minx, maxx, miny, maxy;
|
|
|
|
minx = data->drExtent.x1;
|
|
miny = data->drExtent.y1;
|
|
maxx = data->drExtent.x2;
|
|
maxy = data->drExtent.y2;
|
|
D3DFE_VIEWPORTCACHE& VPORT = pv->vcache;
|
|
for (i = count; i; i--)
|
|
{
|
|
#ifdef _PV_CLIP
|
|
int clip;
|
|
#endif // _PV_CLIP
|
|
float x, y, z, w, we;
|
|
|
|
x = in->x*pv->mCTM._11 + in->y*pv->mCTM._21 +
|
|
in->z*pv->mCTM._31 + pv->mCTM._41;
|
|
y = in->x*pv->mCTM._12 + in->y*pv->mCTM._22 +
|
|
in->z*pv->mCTM._32 + pv->mCTM._42;
|
|
z = in->x*pv->mCTM._13 + in->y*pv->mCTM._23 +
|
|
in->z*pv->mCTM._33 + pv->mCTM._43;
|
|
we= in->x*pv->mCTM._14 + in->y*pv->mCTM._24 +
|
|
in->z*pv->mCTM._34 + pv->mCTM._44;
|
|
#ifdef _PV_CLIP
|
|
hout->hx = x * VPORT.imclip11 + we * VPORT.imclip41;
|
|
hout->hy = y * VPORT.imclip22 + we * VPORT.imclip42;
|
|
hout->hz = z * VPORT.imclip33 + we * VPORT.imclip43;
|
|
{
|
|
D3DVALUE xx = we - x;
|
|
D3DVALUE yy = we - y;
|
|
D3DVALUE zz = we - z;
|
|
clip = ((ASINT32(x) & 0x80000000) >> (32-1)) | // D3DCLIP_LEFT
|
|
((ASINT32(y) & 0x80000000) >> (32-4)) | // D3DCLIP_BOTTOM
|
|
((ASINT32(z) & 0x80000000) >> (32-5)) | // D3DCLIP_FRONT
|
|
((ASINT32(xx) & 0x80000000) >> (32-2)) | // D3DCLIP_RIGHT
|
|
((ASINT32(yy) & 0x80000000) >> (32-3)) | // D3DCLIP_TOP
|
|
((ASINT32(zz) & 0x80000000) >> (32-6)); // D3DCLIP_BACK
|
|
}
|
|
|
|
if (clip == 0)
|
|
#endif // _PV_CLIP
|
|
{
|
|
w = D3DVAL(1)/we;
|
|
#ifdef _PV_CLIP
|
|
clip_intersection = 0;
|
|
#endif // _PV_CLIP
|
|
x = x * w * VPORT.scaleX + VPORT.offsetX;
|
|
y = y * w * VPORT.scaleY + VPORT.offsetY;
|
|
if (x < minx) minx = x;
|
|
if (x > maxx) maxx = x;
|
|
if (y < miny) miny = y;
|
|
if (y > maxy) maxy = y;
|
|
out->sx = x;
|
|
out->sy = y;
|
|
out->sz = z*w;
|
|
out->rhw = w;
|
|
}
|
|
#ifdef _PV_CLIP
|
|
else
|
|
{
|
|
if (!FLOAT_EQZ(we))
|
|
out->rhw = D3DVAL(1)/we;
|
|
else
|
|
out->rhw = __HUGE_PWR2;
|
|
clip_intersection &= clip;
|
|
clip_union |= clip;
|
|
}
|
|
hout->dwFlags = clip;
|
|
hout++;
|
|
#endif // !_PV_CLIP
|
|
|
|
out->tu = in->tu;
|
|
out->tv = in->tv;
|
|
out->color = in->color;
|
|
out->specular = in->specular;
|
|
|
|
in = (D3DLVERTEX*) ((char*) in + in_size);
|
|
out = (D3DTLVERTEX*) ((char*) out + out_size);
|
|
}
|
|
|
|
/*
|
|
* extend to cover lines. XXX
|
|
*/
|
|
maxx += pv->dvExtentsAdjust;
|
|
maxy += pv->dvExtentsAdjust;
|
|
minx -= pv->dvExtentsAdjust;
|
|
miny -= pv->dvExtentsAdjust;
|
|
#ifndef _PV_CLIP
|
|
/* Clamp to viewport */
|
|
/* Clamp for legacy apps */
|
|
if (minx < VPORT.minX || miny < VPORT.minY ||
|
|
maxx > VPORT.maxX || maxy > VPORT.maxY)
|
|
#endif // _PV_CLIP
|
|
{
|
|
/* Clamp to viewport */
|
|
if (minx < VPORT.minX)
|
|
minx = VPORT.minX;
|
|
if (miny < VPORT.minY)
|
|
miny = VPORT.minY;
|
|
if (maxx > VPORT.maxX)
|
|
maxx = VPORT.maxX;
|
|
if (maxy > VPORT.maxY)
|
|
maxy = VPORT.maxY;
|
|
#ifndef _PV_CLIP
|
|
if(pv->dwDeviceFlags & D3DDEV_PREDX5DEVICE)
|
|
{ /* Clamp vertices */
|
|
int i;
|
|
D3D_WARN(4, "Old semantics: Clamping Vertices");
|
|
for (i = count, out = (LPD3DTLVERTEX)data->lpOut; i; i--)
|
|
{
|
|
if (out->sx < VPORT.minX) out->sx = VPORT.minX;
|
|
if (out->sx > VPORT.maxX) out->sx = VPORT.maxX;
|
|
if (out->sy < VPORT.minY) out->sy = VPORT.minY;
|
|
if (out->sy > VPORT.maxY) out->sy = VPORT.maxY;
|
|
|
|
out = (D3DTLVERTEX*) ((char*) out + out_size);
|
|
}
|
|
}
|
|
#endif // _PV_CLIP
|
|
}
|
|
data->drExtent.x1 = minx;
|
|
data->drExtent.y1 = miny;
|
|
data->drExtent.x2 = maxx;
|
|
data->drExtent.y2 = maxy;
|
|
#ifdef _PV_CLIP
|
|
data->dwClipIntersection = clip_intersection;
|
|
data->dwClipUnion = clip_union;
|
|
return clip_intersection;
|
|
#else
|
|
return 0;
|
|
#endif // _PVCLIP
|
|
}
|