19fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 29fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamCopyright (C) 1996-1997 Id Software, Inc. 39fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 49fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is free software; you can redistribute it and/or 59fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammodify it under the terms of the GNU General Public License 69fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamas published by the Free Software Foundation; either version 2 79fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamof the License, or (at your option) any later version. 89fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 99fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is distributed in the hope that it will be useful, 109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreambut WITHOUT ANY WARRANTY; without even the implied warranty of 119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamSee the GNU General Public License for more details. 149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamYou should have received a copy of the GNU General Public License 169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamalong with this program; if not, write to the Free Software 179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// r_draw.c 229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h" 249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "r_local.h" 259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "d_local.h" // FIXME: shouldn't need to include this 269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define MAXLEFTCLIPEDGES 100 289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// !!! if these are changed, they must be changed in asm_draw.h too !!! 309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FULLY_CLIPPED_CACHED 0x80000000 319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FRAMECOUNT_MASK 0x7FFFFFFF 329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamunsigned int cacheoffset; 349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint c_faceclip; // number of faces clipped 369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamzpointdesc_t r_zpointdesc; 389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreampolydesc_t r_polydesc; 409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t *entity_clipplanes; 449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t view_clipplanes[4]; 459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t world_clipplanes[16]; 469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammedge_t *r_pedge; 489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean r_leftclipped, r_rightclipped; 509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic qboolean makeleftedge, makerightedge; 519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean r_nearzionly; 529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint sintable[SIN_BUFFER_SIZE]; 549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint intsintable[SIN_BUFFER_SIZE]; 559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammvertex_t r_leftenter, r_leftexit; 579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammvertex_t r_rightenter, r_rightexit; 589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct 609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float u,v; 629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int ceilv; 639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} evert_t; 649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint r_emitted; 669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamfloat r_nearzi; 679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamfloat r_u1, r_v1, r_lzi1; 689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint r_ceilv1; 699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean r_lastvertvalid; 719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#if !id386 749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_EmitEdge 789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) 819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge_t *edge, *pcheck; 839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int u_check; 849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float u, u_step; 859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vec3_t local, transformed; 869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float *world; 879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int v, v2, ceilv0; 889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float scale, lzi0, u0, v0; 899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int side; 909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_lastvertvalid) 929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u0 = r_u1; 949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v0 = r_v1; 959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lzi0 = r_lzi1; 969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ceilv0 = r_ceilv1; 979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream world = &pv0->position[0]; 1019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // transform and project 1039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream VectorSubtract (world, modelorg, local); 1049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream TransformVector (local, transformed); 1059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (transformed[2] < NEAR_CLIP) 1079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream transformed[2] = NEAR_CLIP; 1089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lzi0 = 1.0 / transformed[2]; 1109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // FIXME: build x/yscale into transform? 1129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = xscale * lzi0; 1139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u0 = (xcenter + scale*transformed[0]); 1149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (u0 < r_refdef.fvrectx_adj) 1159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u0 = r_refdef.fvrectx_adj; 1169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (u0 > r_refdef.fvrectright_adj) 1179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u0 = r_refdef.fvrectright_adj; 1189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = yscale * lzi0; 1209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v0 = (ycenter - scale*transformed[1]); 1219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (v0 < r_refdef.fvrecty_adj) 1229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v0 = r_refdef.fvrecty_adj; 1239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (v0 > r_refdef.fvrectbottom_adj) 1249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v0 = r_refdef.fvrectbottom_adj; 1259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ceilv0 = (int) ceil(v0); 1279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 1289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream world = &pv1->position[0]; 1309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// transform and project 1329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream VectorSubtract (world, modelorg, local); 1339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream TransformVector (local, transformed); 1349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (transformed[2] < NEAR_CLIP) 1369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream transformed[2] = NEAR_CLIP; 1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lzi1 = 1.0 / transformed[2]; 1399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = xscale * r_lzi1; 1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_u1 = (xcenter + scale*transformed[0]); 1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_u1 < r_refdef.fvrectx_adj) 1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_u1 = r_refdef.fvrectx_adj; 1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_u1 > r_refdef.fvrectright_adj) 1459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_u1 = r_refdef.fvrectright_adj; 1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = yscale * r_lzi1; 1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_v1 = (ycenter - scale*transformed[1]); 1499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_v1 < r_refdef.fvrecty_adj) 1509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_v1 = r_refdef.fvrecty_adj; 1519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_v1 > r_refdef.fvrectbottom_adj) 1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_v1 = r_refdef.fvrectbottom_adj; 1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_lzi1 > lzi0) 1559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lzi0 = r_lzi1; 1569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (lzi0 > r_nearzi) // for mipmap finding 1589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = lzi0; 1599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// for right edges, all we want is the effect on 1/z 1619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_nearzionly) 1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_emitted = 1; 1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_ceilv1 = (int) ceil(r_v1); 1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// create the edge 1709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (ceilv0 == r_ceilv1) 1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // we cache unclipped horizontal edges as fully clipped 1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (cacheoffset != 0x7FFFFFFF) 1749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = FULLY_CLIPPED_CACHED | 1769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream (r_framecount & FRAMECOUNT_MASK); 1779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 1789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; // horizontal edge 1809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 1819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream side = ceilv0 > r_ceilv1; 1839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge = edge_p++; 1859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->owner = r_pedge; 1879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->nearzi = lzi0; 1899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (side == 0) 1919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // trailing edge (go from p1 to p2) 1939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v = ceilv0; 1949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v2 = r_ceilv1 - 1; 1959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->surfs[0] = surface_p - surfaces; 1979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->surfs[1] = 0; 1989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u_step = ((r_u1 - u0) / (r_v1 - v0)); 2009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u = u0 + ((float)v - v0) * u_step; 2019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 2039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // leading edge (go from p2 to p1) 2059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v2 = ceilv0 - 1; 2069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v = r_ceilv1; 2079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->surfs[0] = 0; 2099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->surfs[1] = surface_p - surfaces; 2109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u_step = ((u0 - r_u1) / (v0 - r_v1)); 2129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u = r_u1 + ((float)v - r_v1) * u_step; 2139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->u_step = u_step*0x100000; 2169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->u = u*0x100000 + 0xFFFFF; 2179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// we need to do this to avoid stepping off the edges if a very nearly 2199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// horizontal edge is less than epsilon above a scan, and numeric error causes 2209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// it to incorrectly extend to the scan, and the extension of the line goes off 2219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// the edge of the screen 2229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: is this actually needed? 2239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (edge->u < r_refdef.vrect_x_adj_shift20) 2249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->u = r_refdef.vrect_x_adj_shift20; 2259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (edge->u > r_refdef.vrectright_adj_shift20) 2269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->u = r_refdef.vrectright_adj_shift20; 2279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// 2299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// sort the edge in normally 2309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// 2319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u_check = edge->u; 2329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (edge->surfs[0]) 2339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u_check++; // sort trailers after leaders 2349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!newedges[v] || newedges[v]->u >= u_check) 2369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->next = newedges[v]; 2389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream newedges[v] = edge; 2399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 2419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pcheck = newedges[v]; 2439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream while (pcheck->next && pcheck->next->u < u_check) 2449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pcheck = pcheck->next; 2459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->next = pcheck->next; 2469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pcheck->next = edge; 2479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge->nextremove = removeedges[v2]; 2509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream removeedges[v2] = edge; 2519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 2529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 2559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 2569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_ClipEdge 2579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 2589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 2599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip) 2609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 2619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float d0, d1, f; 2629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mvertex_t clipvert; 2639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (clip) 2659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream do 2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream d0 = DotProduct (pv0->position, clip->normal) - clip->dist; 2699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream d1 = DotProduct (pv1->position, clip->normal) - clip->dist; 2709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (d0 >= 0) 2729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // point 0 is unclipped 2749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (d1 >= 0) 2759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // both points are unclipped 2779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 2789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // only point 1 is clipped 2819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // we don't cache clipped edges 2839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = 0x7FFFFFFF; 2849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f = d0 / (d0 - d1); 2869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[0] = pv0->position[0] + 2879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[0] - pv0->position[0]); 2889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[1] = pv0->position[1] + 2899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[1] - pv0->position[1]); 2909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[2] = pv0->position[2] + 2919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[2] - pv0->position[2]); 2929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (clip->leftedge) 2949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 2959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftclipped = true; 2969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftexit = clipvert; 2979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 2989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else if (clip->rightedge) 2999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_rightclipped = true; 3019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_rightexit = clipvert; 3029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (pv0, &clipvert, clip->next); 3059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 3069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 3089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // point 0 is clipped 3109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (d1 < 0) 3119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // both points are clipped 3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // we do cache fully clipped edges 3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!r_leftclipped) 3159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = FULLY_CLIPPED_CACHED | 3169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream (r_framecount & FRAMECOUNT_MASK); 3179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 3189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // only point 0 is clipped 3219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 3229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // we don't cache partially clipped edges 3249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = 0x7FFFFFFF; 3259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f = d0 / (d0 - d1); 3279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[0] = pv0->position[0] + 3289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[0] - pv0->position[0]); 3299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[1] = pv0->position[1] + 3309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[1] - pv0->position[1]); 3319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipvert.position[2] = pv0->position[2] + 3329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream f * (pv1->position[2] - pv0->position[2]); 3339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (clip->leftedge) 3359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftclipped = true; 3379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftenter = clipvert; 3389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else if (clip->rightedge) 3409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_rightclipped = true; 3429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_rightenter = clipvert; 3439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&clipvert, pv1, clip->next); 3469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 3479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } while ((clip = clip->next) != NULL); 3499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 3509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// add the edge 3529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_EmitEdge (pv0, pv1); 3539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 3549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#endif // !id386 3569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 3599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 3609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_EmitCachedEdge 3619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 3629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 3639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_EmitCachedEdge (void) 3649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 3659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream edge_t *pedge_t; 3669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset); 3689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!pedge_t->surfs[0]) 3709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pedge_t->surfs[0] = surface_p - surfaces; 3719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 3729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pedge_t->surfs[1] = surface_p - surfaces; 3739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (pedge_t->nearzi > r_nearzi) // for mipmap finding 3759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = pedge_t->nearzi; 3769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_emitted = 1; 3789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 3799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 3829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 3839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderFace 3849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 3859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 3869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderFace (msurface_t *fa, int clipflags) 3879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 3889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i, lindex; 3899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream unsigned mask; 3909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mplane_t *pplane; 3919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float distinv; 3929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vec3_t p_normal; 3939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream medge_t *pedges, tedge; 3949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipplane_t *pclip; 3959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 3969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// skip out if no more surfs 3979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((surface_p) >= surf_max) 3989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 3999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_outofsurfaces++; 4009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 4019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// ditto if not enough edges left, or switch to auxedges if possible 4049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((edge_p + fa->numedges + 4) >= edge_max) 4059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_outofedges += fa->numedges; 4079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 4089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream c_faceclip++; 4119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes 4139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = NULL; 4149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) 4169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (clipflags & mask) 4189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream view_clipplanes[i].next = pclip; 4209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = &view_clipplanes[i]; 4219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// push the edges through 4259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_emitted = 0; 4269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = 0; 4279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzionly = false; 4289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makeleftedge = makerightedge = false; 4299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pedges = currententity->model->edges; 4309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 4319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<fa->numedges ; i++) 4339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lindex = currententity->model->surfedges[fa->firstedge + i]; 4359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (lindex > 0) 4379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &pedges[lindex]; 4399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // if the edge is cached, we can just reuse the edge 4419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!insubmodel) 4429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) 4449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == 4469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_framecount) 4479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 4499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 4509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 4539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((((unsigned long)edge_p - (unsigned long)r_edges) > 4559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset) && 4569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream (((edge_t *)((unsigned long)r_edges + 4579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset))->owner == r_pedge)) 4589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_EmitCachedEdge (); 4609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 4619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 4629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // assume it's cacheable 4679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = (byte *)edge_p - (byte *)r_edges; 4689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftclipped = r_rightclipped = false; 4699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], 4709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream &r_pcurrentvertbase[r_pedge->v[1]], 4719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip); 4729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset = cacheoffset; 4739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 4749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_leftclipped) 4759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makeleftedge = true; 4769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_rightclipped) 4779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makerightedge = true; 4789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = true; 4799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 4819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lindex = -lindex; 4839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &pedges[lindex]; 4849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // if the edge is cached, we can just reuse the edge 4859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!insubmodel) 4869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) 4889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == 4909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_framecount) 4919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 4939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 4949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 4969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 4979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 4989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // it's cached if the cached edge is valid and is owned 4999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // by this medge_t 5009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((((unsigned long)edge_p - (unsigned long)r_edges) > 5019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset) && 5029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream (((edge_t *)((unsigned long)r_edges + 5039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset))->owner == r_pedge)) 5049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 5059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_EmitCachedEdge (); 5069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 5079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 5089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // assume it's cacheable 5139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream cacheoffset = (byte *)edge_p - (byte *)r_edges; 5149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftclipped = r_rightclipped = false; 5159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], 5169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream &r_pcurrentvertbase[r_pedge->v[0]], 5179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip); 5189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge->cachededgeoffset = cacheoffset; 5199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_leftclipped) 5219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makeleftedge = true; 5229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_rightclipped) 5239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makerightedge = true; 5249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = true; 5259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the left edge, add that edge too 5299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: faster to do in screen space? 5309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: share clipped edges? 5319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (makeleftedge) 5329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 5339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &tedge; 5349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 5359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); 5369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the right edge, get the right r_nearzi 5399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (makerightedge) 5409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 5419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &tedge; 5429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 5439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzionly = true; 5449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); 5459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 5469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if no edges made it out, return without posting the surface 5489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!r_emitted) 5499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 5509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polycount++; 5529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->data = (void *)fa; 5549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->nearzi = r_nearzi; 5559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->flags = fa->flags; 5569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->insubmodel = insubmodel; 5579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->spanstate = 0; 5589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->entity = currententity; 5599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->key = r_currentkey++; 5609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->spans = NULL; 5619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pplane = fa->plane; 5639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this? 5649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream TransformVector (pplane->normal, p_normal); 5659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this? 5669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); 5679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; 5699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; 5709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_ziorigin = p_normal[2] * distinv - 5719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream xcenter * surface_p->d_zistepu - 5729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ycenter * surface_p->d_zistepv; 5739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); 5759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p++; 5769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 5779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 5809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 5819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderBmodelFace 5829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 5839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 5849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) 5859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 5869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i; 5879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream unsigned mask; 5889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mplane_t *pplane; 5899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float distinv; 5909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vec3_t p_normal; 5919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream medge_t tedge; 5929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipplane_t *pclip; 5939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 5949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// skip out if no more surfs 5959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (surface_p >= surf_max) 5969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 5979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_outofsurfaces++; 5989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 5999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// ditto if not enough edges left, or switch to auxedges if possible 6029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((edge_p + psurf->numedges + 4) >= edge_max) 6039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_outofedges += psurf->numedges; 6059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 6069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream c_faceclip++; 6099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// this is a dummy to give the caching mechanism someplace to write to 6119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &tedge; 6129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes 6149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = NULL; 6159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) 6179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_clipflags & mask) 6199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream view_clipplanes[i].next = pclip; 6219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = &view_clipplanes[i]; 6229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// push the edges through 6269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_emitted = 0; 6279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = 0; 6289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzionly = false; 6299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makeleftedge = makerightedge = false; 6309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching 6319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// can be used? 6329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_lastvertvalid = false; 6339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for ( ; pedges ; pedges = pedges->pnext) 6359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_leftclipped = r_rightclipped = false; 6379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (pedges->v[0], pedges->v[1], pclip); 6389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_leftclipped) 6409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makeleftedge = true; 6419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (r_rightclipped) 6429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream makerightedge = true; 6439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the left edge, add that edge too 6469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: faster to do in screen space? 6479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: share clipped edges? 6489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (makeleftedge) 6499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &tedge; 6519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); 6529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the right edge, get the right r_nearzi 6559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (makerightedge) 6569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 6579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &tedge; 6589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzionly = true; 6599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); 6609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 6619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if no edges made it out, return without posting the surface 6639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!r_emitted) 6649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 6659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polycount++; 6679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->data = (void *)psurf; 6699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->nearzi = r_nearzi; 6709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->flags = psurf->flags; 6719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->insubmodel = true; 6729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->spanstate = 0; 6739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->entity = currententity; 6749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->key = r_currentbkey; 6759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->spans = NULL; 6769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pplane = psurf->plane; 6789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this? 6799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream TransformVector (pplane->normal, p_normal); 6809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this? 6819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); 6829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; 6849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; 6859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p->d_ziorigin = p_normal[2] * distinv - 6869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream xcenter * surface_p->d_zistepu - 6879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ycenter * surface_p->d_zistepv; 6889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); 6909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream surface_p++; 6919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 6929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 6949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 6959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 6969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderPoly 6979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 6989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 6999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderPoly (msurface_t *fa, int clipflags) 7009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 7019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i, lindex, lnumverts, s_axis, t_axis; 7029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float dist, lastdist, lzi, scale, u, v, frac; 7039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream unsigned mask; 7049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vec3_t local, transformed; 7059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream clipplane_t *pclip; 7069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream medge_t *pedges; 7079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mplane_t *pplane; 7089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mvertex_t verts[2][100]; //FIXME: do real number 7099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream polyvert_t pverts[100]; //FIXME: do real number, safely 7109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int vertpage, newverts, newpage, lastvert; 7119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream qboolean visible; 7129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: clean this up and make it faster 7149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: guard against running out of vertices 7159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream s_axis = t_axis = 0; // keep compiler happy 7179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes 7199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = NULL; 7209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) 7229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (clipflags & mask) 7249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream view_clipplanes[i].next = pclip; 7269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = &view_clipplanes[i]; 7279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// reconstruct the polygon 7319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: these should be precalculated and loaded off disk 7329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pedges = currententity->model->edges; 7339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lnumverts = fa->numedges; 7349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vertpage = 0; 7359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<lnumverts ; i++) 7379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lindex = currententity->model->surfedges[fa->firstedge + i]; 7399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (lindex > 0) 7419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &pedges[lindex]; 7439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]]; 7449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream else 7469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_pedge = &pedges[-lindex]; 7489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]]; 7499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// clip the polygon, done if not visible 7539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream while (pclip) 7549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lastvert = lnumverts - 1; 7569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lastdist = DotProduct (verts[vertpage][lastvert].position, 7579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip->normal) - pclip->dist; 7589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream visible = false; 7609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream newverts = 0; 7619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream newpage = vertpage ^ 1; 7629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<lnumverts ; i++) 7649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream dist = DotProduct (verts[vertpage][i].position, pclip->normal) - 7669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip->dist; 7679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if ((lastdist > 0) != (dist > 0)) 7699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream frac = dist / (dist - lastdist); 7719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[newpage][newverts].position[0] = 7729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[0] + 7739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ((verts[vertpage][lastvert].position[0] - 7749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[0]) * frac); 7759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[newpage][newverts].position[1] = 7769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[1] + 7779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ((verts[vertpage][lastvert].position[1] - 7789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[1]) * frac); 7799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[newpage][newverts].position[2] = 7809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[2] + 7819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream ((verts[vertpage][lastvert].position[2] - 7829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[vertpage][i].position[2]) * frac); 7839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream newverts++; 7849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (dist >= 0) 7879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 7889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream verts[newpage][newverts] = verts[vertpage][i]; 7899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream newverts++; 7909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream visible = true; 7919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lastvert = i; 7949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lastdist = dist; 7959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 7969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 7979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!visible || (newverts < 3)) 7989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 7999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lnumverts = newverts; 8019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vertpage ^= 1; 8029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pclip = pclip->next; 8039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 8049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// transform and project, remembering the z values at the vertices and 8069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// r_nearzi, and extract the s and t coordinates at the vertices 8079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pplane = fa->plane; 8089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream switch (pplane->type) 8099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 8109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_X: 8119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_ANYX: 8129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream s_axis = 1; 8139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream t_axis = 2; 8149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream break; 8159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_Y: 8169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_ANYY: 8179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream s_axis = 0; 8189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream t_axis = 2; 8199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream break; 8209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_Z: 8219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream case PLANE_ANYZ: 8229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream s_axis = 0; 8239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream t_axis = 1; 8249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream break; 8259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 8269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = 0; 8289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<lnumverts ; i++) 8309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 8319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // transform and project 8329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream VectorSubtract (verts[vertpage][i].position, modelorg, local); 8339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream TransformVector (local, transformed); 8349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (transformed[2] < NEAR_CLIP) 8369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream transformed[2] = NEAR_CLIP; 8379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lzi = 1.0 / transformed[2]; 8399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (lzi > r_nearzi) // for mipmap finding 8419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_nearzi = lzi; 8429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // FIXME: build x/yscale into transform? 8449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = xscale * lzi; 8459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u = (xcenter + scale*transformed[0]); 8469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (u < r_refdef.fvrectx_adj) 8479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u = r_refdef.fvrectx_adj; 8489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (u > r_refdef.fvrectright_adj) 8499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream u = r_refdef.fvrectright_adj; 8509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream scale = yscale * lzi; 8529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v = (ycenter - scale*transformed[1]); 8539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (v < r_refdef.fvrecty_adj) 8549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v = r_refdef.fvrecty_adj; 8559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (v > r_refdef.fvrectbottom_adj) 8569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v = r_refdef.fvrectbottom_adj; 8579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pverts[i].u = u; 8599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pverts[i].v = v; 8609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pverts[i].zi = lzi; 8619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pverts[i].s = verts[vertpage][i].position[s_axis]; 8629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pverts[i].t = verts[vertpage][i].position[t_axis]; 8639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 8649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z 8669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// for each vertex 8679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polydesc.numverts = lnumverts; 8689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polydesc.nearzi = r_nearzi; 8699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polydesc.pcurrentface = fa; 8709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_polydesc.pverts = pverts; 8719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// draw the polygon 8739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream D_DrawPoly (); 8749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 8759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 8789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 8799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_ZDrawSubmodelPolys 8809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================ 8819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 8829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_ZDrawSubmodelPolys (model_t *pmodel) 8839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 8849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i, numsurfaces; 8859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream msurface_t *psurf; 8869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float dot; 8879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream mplane_t *pplane; 8889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; 8909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream numsurfaces = pmodel->nummodelsurfaces; 8919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<numsurfaces ; i++, psurf++) 8939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 8949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // find which side of the node we are on 8959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream pplane = psurf->plane; 8969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream dot = DotProduct (modelorg, pplane->normal) - pplane->dist; 8989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 8999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // draw the polygon 9009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || 9019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) 9029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 9039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // FIXME: use bounding-box-based frustum clipping info? 9049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_RenderPoly (psurf, 15); 9059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 9069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 9079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 9089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 909