|
|
/*==========================================================================;
* * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved. * * File: clipper.c * Content: Clipper * ***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
#define GET_NEW_CLIP_VERTEX \
&pv->ClipperState.clip_vertices[pv->ClipperState.clip_vertices_used++]; //---------------------------------------------------------------------
__inline void InterpolateColor(DWORD* p, // Output
DWORD p1, DWORD p2, D3DVALUE num_denom ) { float r1, g1, b1, a1; float r2, g2, b2, a2;
r1 = (float)(RGBA_GETRED(p1)); g1 = (float)(RGBA_GETGREEN(p1)); b1 = (float)(RGBA_GETBLUE(p1)); a1 = (float)(RGBA_GETALPHA(p1)); r2 = (float)(RGBA_GETRED(p2)); g2 = (float)(RGBA_GETGREEN(p2)); b2 = (float)(RGBA_GETBLUE(p2)); a2 = (float)(RGBA_GETALPHA(p2)); DWORD r = FTOI(r1 + (r2 - r1) * num_denom); DWORD g = FTOI(g1 + (g2 - g1) * num_denom); DWORD b = FTOI(b1 + (b2 - b1) * num_denom); DWORD a = FTOI(a1 + (a2 - a1) * num_denom); *p = RGBA_MAKE(r, g, b, a); } //---------------------------------------------------------------------
__inline D3DVALUE InterpolateTexture(D3DVALUE t1, D3DVALUE t2, D3DVALUE num_denom, DWORD bWrap) { if (!bWrap) return ((t2 - t1) * num_denom + t1); else { D3DVALUE t = (TextureDiff(t2, t1, 1) * num_denom + t1); if (t > 1.0f) t -= 1.0f; return t; } } //---------------------------------------------------------------------
void Interpolate(D3DFE_PROCESSVERTICES *pv, ClipVertex *p, ClipVertex *p1, ClipVertex *p2, int code, D3DVALUE num, D3DVALUE denom) { D3DVALUE num_denom = num / denom;
p->clip = (((int)p1->clip & (int)p2->clip) & ~CLIPPED_ENABLE) | code; p->hx = p1->hx + (p2->hx - p1->hx) * num_denom; p->hy = p1->hy + (p2->hy - p1->hy) * num_denom; p->hz = p1->hz + (p2->hz - p1->hz) * num_denom; p->hw = p1->hw + (p2->hw - p1->hw) * num_denom;
// Note: for the flat shade mode we assigned the same color (except fog
// factor) to all vertices when we prepared the triangle (line) for
// clipping
if (pv->dwVIDOut & D3DFVF_DIFFUSE) { if (!(pv->dwDeviceFlags & D3DDEV_FLATSHADEMODE)) InterpolateColor(&p->color, p1->color, p2->color, num_denom); else p->color = p1->color; } if (pv->dwVIDOut & D3DFVF_SPECULAR) { if (!(pv->dwDeviceFlags & D3DDEV_FLATSHADEMODE)) InterpolateColor(&p->specular, p1->specular, p2->specular, num_denom); else { float a1 = (float)(RGBA_GETALPHA(p1->specular)); float a2 = (float)(RGBA_GETALPHA(p2->specular)); DWORD a = FTOI(a1 + (a2 - a1) * num_denom); p->specular = (p1->specular & 0xFFFFFF) + ((a & 0xFF) << 24); } }
// Assume that D3DRENDERSTATE_WRAPi are sequential
D3DVALUE *pTexture1 = p1->tex; D3DVALUE *pTexture2 = p2->tex; D3DVALUE *pTexture = p->tex; for (DWORD i = 0; i < pv->nOutTexCoord; i++) { DWORD wrapState = pv->lpdwRStates[D3DRENDERSTATE_WRAP0 + i]; DWORD n = (DWORD)(pv->dwTextureCoordSize[i] >> 2); DWORD dwWrapBit = 1; for (DWORD j=0; j < n; j++) { *pTexture = InterpolateTexture(*pTexture1, *pTexture2, num_denom, wrapState & dwWrapBit); dwWrapBit <<= 1; pTexture ++; pTexture1++; pTexture2++; } } } //------------------------------------------------------------------------------
// Functions for clipping by frustum window
//
#define __CLIP_NAME ClipLeft
#define __CLIP_LINE_NAME ClipLineLeft
#define __CLIP_FLAG CLIPPED_LEFT
#define __CLIP_COORD hx
#include "clip.h"
#define __CLIP_NAME ClipRight
#define __CLIP_LINE_NAME ClipLineRight
#define __CLIP_W
#define __CLIP_FLAG CLIPPED_RIGHT
#define __CLIP_COORD hx
#include "clip.h"
#define __CLIP_NAME ClipBottom
#define __CLIP_LINE_NAME ClipLineBottom
#define __CLIP_FLAG CLIPPED_BOTTOM
#define __CLIP_COORD hy
#include "clip.h"
#define __CLIP_NAME ClipTop
#define __CLIP_LINE_NAME ClipLineTop
#define __CLIP_W
#define __CLIP_FLAG CLIPPED_TOP
#define __CLIP_COORD hy
#include "clip.h"
#define __CLIP_NAME ClipBack
#define __CLIP_LINE_NAME ClipLineBack
#define __CLIP_W
#define __CLIP_FLAG CLIPPED_BACK
#define __CLIP_COORD hz
#include "clip.h"
#define __CLIP_NAME ClipFront
#define __CLIP_LINE_NAME ClipLineFront
#define __CLIP_FLAG CLIPPED_FRONT
#define __CLIP_COORD hz
#include "clip.h"
//------------------------------------------------------------------------------
// Functions for guard band clipping
//
#define __CLIP_GUARDBAND
#define __CLIP_NAME ClipLeftGB
#define __CLIP_LINE_NAME ClipLineLeftGB
#define __CLIP_FLAG CLIPPED_LEFT
#define __CLIP_COORD hx
#define __CLIP_SIGN -
#define __CLIP_GBCOEF Kgbx1
#include "clip.h"
#define __CLIP_NAME ClipRightGB
#define __CLIP_LINE_NAME ClipLineRightGB
#define __CLIP_FLAG CLIPPED_RIGHT
#define __CLIP_COORD hx
#define __CLIP_GBCOEF Kgbx2
#define __CLIP_SIGN +
#include "clip.h"
#define __CLIP_NAME ClipBottomGB
#define __CLIP_LINE_NAME ClipLineBottomGB
#define __CLIP_FLAG CLIPPED_BOTTOM
#define __CLIP_COORD hy
#define __CLIP_SIGN -
#define __CLIP_GBCOEF Kgby1
#include "clip.h"
#define __CLIP_NAME ClipTopGB
#define __CLIP_LINE_NAME ClipLineTopGB
#define __CLIP_FLAG CLIPPED_TOP
#define __CLIP_COORD hy
#define __CLIP_GBCOEF Kgby2
#define __CLIP_SIGN +
#include "clip.h"
#undef __CLIP_GUARDBAND
//
// Clipping a triangle by a plane
//
// Returns number of vertices in the clipped triangle
//
int ClipByPlane (D3DFE_PROCESSVERTICES *pv, ClipVertex **inv, ClipVertex **outv, D3DVECTORH *plane, DWORD dwClipFlag, int count) { int i; int out_count = 0; ClipVertex *curr, *prev; D3DVALUE curr_inside; D3DVALUE prev_inside;
prev = inv[count-1]; curr = *inv++; prev_inside = prev->hx*plane->x + prev->hy*plane->y + prev->hz*plane->z + prev->hw*plane->w; for (i = count; i; i--) { curr_inside = curr->hx*plane->x + curr->hy*plane->y + curr->hz*plane->z + curr->hw*plane->w; // We interpolate always from the inside vertex to the outside vertex
// to reduce precision problems
if (FLOAT_LTZ(prev_inside)) { // first point is outside
if (FLOAT_GEZ(curr_inside)) { // second point is inside
// Find intersection and insert in into the output buffer
outv[out_count] = GET_NEW_CLIP_VERTEX; Interpolate(pv, outv[out_count], curr, prev, (prev->clip & CLIPPED_ENABLE) | dwClipFlag, curr_inside, curr_inside - prev_inside); out_count++; } } else { // first point is inside - put it to the output buffer first
outv[out_count++] = prev; if (FLOAT_LTZ(curr_inside)) { // second point is outside
// Find intersection and put it to the output buffer
outv[out_count] = GET_NEW_CLIP_VERTEX; Interpolate(pv, outv[out_count], prev, curr, dwClipFlag, prev_inside, prev_inside - curr_inside); out_count++; } } prev = curr; curr = *inv++; prev_inside = curr_inside; } return out_count; } //-------------------------------------------------------------------------
// Clips a line by a plane
//
// Returns 1 if the line is outside the frustum, 0 otherwise
//
int ClipLineByPlane(D3DFE_PROCESSVERTICES *pv, ClipTriangle *line, D3DVECTORH *plane, DWORD dwClipBit) { D3DVALUE in1, in2; ClipVertex outv; in1 = line->v[0]->hx * plane->x + line->v[0]->hy * plane->y + line->v[0]->hz * plane->z + line->v[0]->hw * plane->w; in2 = line->v[1]->hx * plane->x + line->v[1]->hy * plane->y + line->v[1]->hz * plane->z + line->v[1]->hw * plane->w; if (in1 < 0) { if (in2 < 0) return 1; Interpolate(pv, &outv, line->v[0], line->v[1], dwClipBit, in1, in1 - in2); *line->v[0] = outv; } else { if (in2 < 0) { Interpolate(pv, &outv, line->v[0], line->v[1], dwClipBit, in1, in1 - in2); *line->v[1] = outv; } } return 0; } /*------------------------------------------------------------------------
* Calculate the screen coords for any new vertices * introduced into the polygon. */ void ComputeScreenCoordinates(D3DFE_PROCESSVERTICES *pv, ClipVertex **inv, int count) { int i; D3DFE_VIEWPORTCACHE& VPORT = pv->vcache;
for (i = 0; i < count; i++) { ClipVertex *p; p = inv[i];
/*
* Catch any vertices that need screen co-ordinates generated. * There are two possibilities * 1) Vertices generated during interpolation * 2) Vertices marked for clipping by the transform but * not clipped here due to the finite precision * of the floating point unit. */
if (p->clip & ~CLIPPED_ENABLE) { D3DVALUE w;
w = D3DVAL(1.0)/p->hw; switch ((int)p->clip & (CLIPPED_LEFT|CLIPPED_RIGHT)) { case CLIPPED_LEFT: p->sx = VPORT.minXgb; break; case CLIPPED_RIGHT: p->sx = VPORT.maxXgb; break; default: p->sx = p->hx * VPORT.scaleX * w + VPORT.offsetX; if (p->sx < VPORT.minXgb) p->sx = VPORT.minXgb; if (p->sx > VPORT.maxXgb) p->sx = VPORT.maxXgb; } switch ((int)p->clip & (CLIPPED_TOP|CLIPPED_BOTTOM)) { case CLIPPED_BOTTOM: p->sy = VPORT.maxYgb; break; case CLIPPED_TOP: p->sy = VPORT.minYgb; break; default: p->sy = p->hy * VPORT.scaleY * w + VPORT.offsetY; if (p->sy < VPORT.minYgb) p->sy = VPORT.minYgb; if (p->sy > VPORT.maxYgb) p->sy = VPORT.maxYgb; } p->sz = p->hz * w * pv->vcache.scaleZ + pv->vcache.offsetZ; p->rhw = w; } } } //---------------------------------------------------------------------
inline DWORD ComputeClipCodeUserPlanes(D3DFE_PROCESSVERTICES *pv, ClipVertex *p) { DWORD clip = 0; DWORD dwClipBit = D3DCS_PLANE0; for (DWORD i=0; i < pv->dwMaxUserClipPlanes; i++) { if ((p->hx*pv->userClipPlane[i].x + p->hy*pv->userClipPlane[i].y + p->hz*pv->userClipPlane[i].z + p->hw*pv->userClipPlane[i].w) < 0) { clip |= dwClipBit; } dwClipBit <<= 1; } return clip; } //---------------------------------------------------------------------
inline DWORD ComputeClipCodeGB(D3DFE_PROCESSVERTICES *pv, ClipVertex *p) { DWORD clip = 0; if (p->hx < p->hw * pv->vcache.Kgbx1) clip |= __D3DCLIPGB_LEFT; if (p->hx > p->hw * pv->vcache.Kgbx2) clip |= __D3DCLIPGB_RIGHT; if (p->hy < p->hw * pv->vcache.Kgby1) clip |= __D3DCLIPGB_BOTTOM; if (p->hy > p->hw * pv->vcache.Kgby2) clip |= __D3DCLIPGB_TOP; if (p->hz > p->hw) clip |= D3DCS_BACK; clip |= ComputeClipCodeUserPlanes(pv, p); p->clip = (p->clip & (CLIPPED_ENABLE | CLIPPED_FRONT)) | clip; return clip; } //---------------------------------------------------------------------
inline DWORD ComputeClipCode(D3DFE_PROCESSVERTICES *pv, ClipVertex *p) { DWORD clip = 0; if (FLOAT_LTZ(p->hx)) clip |= D3DCS_LEFT; if (p->hx > p->hw) clip |= D3DCS_RIGHT; if (FLOAT_LTZ(p->hy)) clip |= D3DCS_BOTTOM; if (p->hy > p->hw) clip |= D3DCS_TOP; if (p->hz > p->hw) clip |= D3DCS_BACK; clip |= ComputeClipCodeUserPlanes(pv, p); p->clip = (p->clip & (CLIPPED_ENABLE | CLIPPED_FRONT)) | clip; return clip; } //***********************************************************************
//
// Returns 0, if triangle is clipped. Number of vertices otherwise.
//
// Original vertices should not be modified inside the function
//
#undef DPF_MODNAME
#define DPF_MODNAME "ClipSingleTriangle"
int D3DFE_PVFUNCSI::ClipSingleTriangle(D3DFE_PROCESSVERTICES *pv, ClipTriangle *tri, ClipVertex ***clipVertexPointer) { int accept; int i; int count; ClipVertex **inv; ClipVertex **outv; ClipVertex *p; ULONG_PTR swapv;
CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
accept = (tri->v[0]->clip | tri->v[1]->clip | tri->v[2]->clip);
inv = tri->v;
count = 3; outv = pv->ClipperState.clip_vbuf1; pv->ClipperState.clip_color = tri->v[0]->color; pv->ClipperState.clip_specular = tri->v[0]->specular;
/*
* XXX assumes sizeof(void*) == sizeof(unsigned long) */ { ULONG_PTR tmp1; ULONG_PTR tmp2;
tmp1 = (ULONG_PTR)pv->ClipperState.clip_vbuf1; tmp2 = (ULONG_PTR)pv->ClipperState.clip_vbuf2;
swapv = tmp1 + tmp2; } pv->ClipperState.clip_vertices_used = 0;
#define SWAP(inv, outv) \
inv = outv; \ outv = (ClipVertex**) (swapv - (ULONG_PTR) outv)
if (accept & D3DCS_FRONT) { count = ClipFront(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (pv->dwDeviceFlags & D3DDEV_GUARDBAND) { // If there was clipping by the front plane it is better to
// compute clip code for new vertices and re-compute accept.
// Otherwise we will try to clip by sides when it is not necessary
if (accept & D3DCS_FRONT) { accept = 0; for (i = 0; i < count; i++) { ClipVertex *p; p = inv[i]; if (p->clip & CLIPPED_FRONT) accept |= ComputeClipCodeGB(pv, p); else accept |= p->clip; } } if (accept & D3DCS_BACK) { count = ClipBack(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & __D3DCLIPGB_LEFT) { count = ClipLeftGB(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & __D3DCLIPGB_RIGHT) { count = ClipRightGB(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & __D3DCLIPGB_BOTTOM) { count = ClipBottomGB(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & __D3DCLIPGB_TOP) { count = ClipTopGB(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } } else { // If there was clipping by the front plane it is better to
// compute clip code for new vertices and re-compute accept.
// Otherwise we will try to clip by sides when it is not necessary
if (accept & D3DCS_FRONT) { accept = 0; for (i = 0; i < count; i++) { ClipVertex *p; p = inv[i]; if (p->clip & (CLIPPED_FRONT)) accept |= ComputeClipCode(pv, p); else accept |= p->clip; } } if (accept & D3DCS_BACK) { count = ClipBack(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & D3DCS_LEFT) { count = ClipLeft(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & D3DCS_RIGHT) { count = ClipRight(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & D3DCS_BOTTOM) { count = ClipBottom(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } if (accept & D3DCS_TOP) { count = ClipTop(pv, inv, outv, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } } if (pv->dwMaxUserClipPlanes) { DWORD dwClipBit = D3DCS_PLANE0; DWORD dwClippedBit = CLIPPED_PLANE0; for (DWORD i=0; i < pv->dwMaxUserClipPlanes; i++) { if (accept & dwClipBit) { count = ClipByPlane(pv, inv, outv, &pv->userClipPlane[i], dwClippedBit, count); if (count < 3) goto out_of_here; SWAP(inv, outv); } dwClipBit <<= 1; dwClippedBit <<= 1; } }
#undef SWAP
ComputeScreenCoordinates(pv, inv, count);
*clipVertexPointer = inv; pv->ClipperState.current_vbuf = inv; return count;
out_of_here:
*clipVertexPointer = NULL; return 0; } //*************************************************************************
//
#undef DPF_MODNAME
#define DPF_MODNAME "ClipSingleLine"
int D3DFE_PVFUNCSI::ClipSingleLine(D3DFE_PROCESSVERTICES *pv, ClipTriangle *line) { int accept; D3DVALUE in1, in2;
CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
accept = (line->v[0]->clip | line->v[1]->clip);
pv->ClipperState.clip_color = line->v[0]->color; pv->ClipperState.clip_specular = line->v[0]->specular;
if (accept & D3DCS_FRONT) if (ClipLineFront(pv, line)) goto out_of_here; if (pv->dwDeviceFlags & D3DDEV_GUARDBAND) { // If there was clipping by the front plane it is better to
// compute clip code for new vertices and re-compute accept.
// Otherwise we will try to clip by sides when it is not necessary
if (accept & D3DCS_FRONT) { ClipVertex * p; accept = 0; p = line->v[0]; if (p->clip & CLIPPED_FRONT) accept |= ComputeClipCodeGB(pv, p); else accept |= p->clip; p = line->v[1]; if (p->clip & CLIPPED_FRONT) accept |= ComputeClipCodeGB(pv, p); else accept |= p->clip; } if (accept & D3DCS_BACK) if (ClipLineBack(pv, line)) goto out_of_here; if (accept & __D3DCLIPGB_LEFT) if (ClipLineLeftGB(pv, line)) goto out_of_here; if (accept & __D3DCLIPGB_RIGHT) if (ClipLineRightGB(pv, line)) goto out_of_here; if (accept & __D3DCLIPGB_TOP) if (ClipLineTopGB(pv, line)) goto out_of_here; if (accept & __D3DCLIPGB_BOTTOM) if (ClipLineBottomGB(pv, line)) goto out_of_here; } else { // If there was clipping by the front plane it is better to
// compute clip code for new vertices and re-compute accept.
// Otherwise we will try to clip by sides when it is not necessary
if (accept & D3DCS_FRONT) { ClipVertex * p; accept = 0; p = line->v[0]; if (p->clip & CLIPPED_FRONT) accept |= ComputeClipCode(pv, p); else accept |= p->clip; p = line->v[1]; if (p->clip & CLIPPED_FRONT) accept |= ComputeClipCode(pv, p); else accept |= p->clip; } if (accept & D3DCS_BACK) if (ClipLineBack(pv, line)) goto out_of_here; if (accept & D3DCS_LEFT) if (ClipLineLeft(pv, line)) goto out_of_here; if (accept & D3DCS_RIGHT) if (ClipLineRight(pv, line)) goto out_of_here; if (accept & D3DCS_TOP) if (ClipLineTop(pv, line)) goto out_of_here; if (accept & D3DCS_BOTTOM) if (ClipLineBottom(pv, line)) goto out_of_here; } if (pv->dwMaxUserClipPlanes) { DWORD dwClipBit = D3DCS_PLANE0; DWORD dwClippedBit = CLIPPED_PLANE0; for (DWORD i=0; i < pv->dwMaxUserClipPlanes; i++) { if (accept & dwClipBit) { if (ClipLineByPlane(pv, line, &pv->userClipPlane[i], dwClippedBit)) goto out_of_here; } dwClipBit <<= 1; dwClippedBit <<= 1; } }
ComputeScreenCoordinates(pv, line->v, 2);
return 1; out_of_here: return 0; } // ClipSingleLine
//----------------------------------------------------------------------
// GenClipFlags() Generates clip flags for a set of FVF
//
#undef DPF_MODNAME
#define DPF_MODNAME "GenClipFlags"
DWORD D3DFE_GenClipFlags(D3DFE_PROCESSVERTICES *pv) { DWORD clip_intersection, clip_union; float left = pv->vcache.minX; float top = pv->vcache.minY; float right = pv->vcache.maxX; float bottom = pv->vcache.maxY; float leftgb ; // Guard band window
float topgb ; float rightgb ; float bottomgb; DWORD clipZF, clipZB; DWORD stride = pv->position.dwStride;
clipZF = pv->lpdwRStates[D3DRENDERSTATE_ZENABLE] ? D3DCS_FRONT : 0; clipZB = pv->lpdwRStates[D3DRENDERSTATE_ZENABLE] ? D3DCS_BACK : 0;
clip_intersection = (DWORD)~0; clip_union = (DWORD)0;
if (pv->dwDeviceFlags & D3DDEV_GUARDBAND) { leftgb = pv->vcache.minXgb; topgb = pv->vcache.minYgb; rightgb = pv->vcache.maxXgb; bottomgb = pv->vcache.maxYgb; } /* Only generate clip flags */ D3DTLVERTEX *lpVertices = (D3DTLVERTEX*)pv->position.lpvData; D3DFE_CLIPCODE *clipCode = pv->lpClipFlags; DWORD i;
// Point sprites are clipped only by Z planes. Clipping by X and Y planes
// will be done when we expand point sprites
if (pv->primType == D3DPT_POINTLIST && pv->dwDeviceFlags & D3DDEV_DOPOINTSPRITEEMULATION) { for (i = pv->dwNumVertices; i; i--) { DWORD clip = 0; D3DVALUE x,y,z; if (lpVertices->rhw < 0) { x = -lpVertices->sx; y = -lpVertices->sy; z = -lpVertices->sz; } else { x = lpVertices->sx; y = lpVertices->sy; z = lpVertices->sz; }
if (z < 0.0f) clip |= clipZF; else if (z >= 1.0f) clip |= clipZB;
clip_intersection &= clip; clip_union |= clip; *clipCode++ = (D3DFE_CLIPCODE)clip; lpVertices = (D3DTLVERTEX*)((char*)lpVertices + stride); } } else for (i = pv->dwNumVertices; i; i--) { DWORD clip = 0; D3DVALUE x,y,z; if (lpVertices->rhw < 0) { x = -lpVertices->sx; y = -lpVertices->sy; z = -lpVertices->sz; } else { x = lpVertices->sx; y = lpVertices->sy; z = lpVertices->sz; }
if (x < left) clip |= D3DCS_LEFT; else if (x >= right) clip |= D3DCS_RIGHT;
if (y < top) clip |= D3DCS_TOP; else if (y >= bottom) clip |= D3DCS_BOTTOM;
if (z < 0.0f) clip |= clipZF; else if (z >= 1.0f) clip |= clipZB;
if (pv->dwDeviceFlags & D3DDEV_GUARDBAND && clip) { if (x < leftgb) clip |= __D3DCLIPGB_LEFT; else if (x >= rightgb) clip |= __D3DCLIPGB_RIGHT;
if (y < topgb) clip |= __D3DCLIPGB_TOP; else if (y >= bottomgb) clip |= __D3DCLIPGB_BOTTOM; }
clip_intersection &= clip; clip_union |= clip; *clipCode++ = (D3DFE_CLIPCODE)clip; lpVertices = (D3DTLVERTEX*)((char*)lpVertices + stride); } pv->dwClipIntersection = clip_intersection; pv->dwClipUnion = clip_union;
return clip_intersection; } // end of GenClipFlags()
//---------------------------------------------------------------------
// Make clip vertex from D3D vertex
//
// device - CD3DHal *
// pp1 - clipVertex
// p1 - TL vertex
//
void MAKE_CLIP_VERTEX_FVF(D3DFE_PROCESSVERTICES *pv, ClipVertex& pp1, BYTE* p1, DWORD clipFlag, BOOL transformed) { D3DFE_VIEWPORTCACHE& VPORT = pv->vcache; BYTE *v = (BYTE*)p1; if (transformed || !(clipFlag & pv->dwClipMaskOffScreen)) { pp1.sx = ((D3DVALUE*)v)[0]; pp1.sy = ((D3DVALUE*)v)[1]; pp1.sz = ((D3DVALUE*)v)[2]; pp1.rhw = ((D3DVALUE*)v)[3]; pp1.hw = 1.0f / ((D3DVALUE*)v)[3]; pp1.hx = (pp1.sx - VPORT.offsetX) * pp1.hw * VPORT.scaleXi; pp1.hy = (pp1.sy - VPORT.offsetY) * pp1.hw * VPORT.scaleYi; pp1.hz = (pp1.sz - VPORT.offsetZ) * pp1.hw * VPORT.scaleZi; } else { pp1.hx = ((D3DVALUE*)v)[0]; pp1.hy = ((D3DVALUE*)v)[1]; pp1.hz = ((D3DVALUE*)v)[2]; pp1.hw = ((D3DVALUE*)v)[3]; } v += sizeof(D3DVALUE) * 4; if (pv->dwVIDOut & D3DFVF_DIFFUSE) { pp1.color = *(DWORD*)v; v += sizeof(D3DVALUE); } if (pv->dwVIDOut & D3DFVF_SPECULAR) { pp1.specular= *(DWORD*)v; v += sizeof(DWORD); } memcpy(pp1.tex, v, pv->dwTextureCoordSizeTotal); pp1.clip = clipFlag; }
|