📄 r_splats.c
字号:
// --------------------------------------------------------------------------// Before each frame being rendered, clear the visible floorsplats list// --------------------------------------------------------------------------static floorsplat_t* visfloorsplats;void R_ClearVisibleFloorSplats (void){ visfloorsplats = NULL;}// --------------------------------------------------------------------------// Add a floorsplat to the visible floorsplats list, for the current frame// --------------------------------------------------------------------------void R_AddVisibleFloorSplats (subsector_t* subsec){ floorsplat_t* pSplat;#ifdef PARANOIA if (subsec->splats==NULL) I_Error ("R_AddVisibleFloorSplats: call with no splats");#endif pSplat = subsec->splats; // the splat is not visible from below // FIXME: depending on some flag in pSplat->flags, some splats may be visible from 2 sides (above/below) if (pSplat->z < viewz) { pSplat->nextvis = visfloorsplats; visfloorsplats = pSplat; } while (pSplat->next) { pSplat = pSplat->next; if (pSplat->z < viewz) { pSplat->nextvis = visfloorsplats; visfloorsplats = pSplat; } }}// tv1,tv2 = x/y qui varie dans la texture, tc = x/y qui est constant.void ASMCALL rasterize_segment_tex (int x1, int y1, int x2, int y2, int tv1, int tv2, int tc, int dir);// current test with floor tile#define TEXWIDTH 64#define TEXHEIGHT 64//#define FLOORSPLATSOLIDCOLOR// --------------------------------------------------------------------------// Rasterize the four edges of a floor splat polygon,// fill the polygon with linear interpolation, call span drawer for each// scan line// --------------------------------------------------------------------------static void R_RenderFloorSplat (floorsplat_t* pSplat, vertex_t* verts, byte* pTex){ // resterizing int miny = vid.height + 1; int maxy = 0; int x, y; int x1, y1, x2, y2; byte* pDest; int tx, ty, tdx, tdy; // rendering lighttable_t** planezlight; fixed_t planeheight; angle_t angle; fixed_t distance; fixed_t length; unsigned index; int light; fixed_t offsetx,offsety; offsetx = pSplat->verts[0].x & 0x3fffff; offsety = pSplat->verts[0].y & 0x3fffff; // do for each segment, starting with the first one /*CONS_Printf ("floor splat (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", verts[3].x,verts[3].y,verts[2].x,verts[2].y, verts[1].x,verts[1].y,verts[0].x,verts[0].y);*/ // do segment a -> top of texture x1 = verts[3].x; y1 = verts[3].y; x2 = verts[2].x; y2 = verts[2].y; if (y1<0) y1=0; if (y1>=vid.height) y1 = vid.height-1; if (y2<0) y2=0; if (y2>=vid.height) y2 = vid.height-1; rasterize_segment_tex (x1, y1, x2, y2, 0, TEXWIDTH-1, 0, 0); if( y1 < miny ) miny = y1; if( y1 > maxy ) maxy = y1; // do segment b -> right side of texture x1 = x2; y1 = y2; x2 = verts[1].x; y2 = verts[1].y; if (y1<0) y1=0; if (y1>=vid.height) y1 = vid.height-1; if (y2<0) y2=0; if (y2>=vid.height) y2 = vid.height-1; rasterize_segment_tex (x1, y1, x2, y2, 0, TEXHEIGHT-1, TEXWIDTH-1, 1); if( y1 < miny ) miny = y1; if( y1 > maxy ) maxy = y1; // do segment c -> bottom of texture x1 = x2; y1 = y2; x2 = verts[0].x; y2 = verts[0].y; if (y1<0) y1=0; if (y1>=vid.height) y1 = vid.height-1; if (y2<0) y2=0; if (y2>=vid.height) y2 = vid.height-1; rasterize_segment_tex (x1, y1, x2, y2, TEXWIDTH-1, 0, TEXHEIGHT-1, 0); if( y1 < miny ) miny = y1; if( y1 > maxy ) maxy = y1; // do segment d -> left side of texture x1 = x2; y1 = y2; x2 = verts[3].x; y2 = verts[3].y; if (y1<0) y1=0; if (y1>=vid.height) y1 = vid.height-1; if (y2<0) y2=0; if (y2>=vid.height) y2 = vid.height-1; rasterize_segment_tex (x1, y1, x2, y2, TEXHEIGHT-1, 0, 0, 1); if( y1 < miny ) miny = y1; if( y1 > maxy ) maxy = y1; // remplissage du polygone a 4 cotes AVEC UNE TEXTURE //fill_texture_linear( trashbmp, tex->imgdata, miny, maxy ); //return;#ifndef FLOORSPLATSOLIDCOLOR // prepare values for all the splat ds_source = (byte *)W_CacheLumpNum(pSplat->pic,PU_CACHE); planeheight = abs(pSplat->z - viewz); light = (pSplat->subsector->sector->lightlevel >> LIGHTSEGSHIFT)+extralight; if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; if (light < 0) light = 0; planezlight = zlight[light]; for (y=miny; y<=maxy; y++) { x1 = rastertab[y].minx >> FRACBITS; x2 = rastertab[y].maxx >> FRACBITS; if (x1<0) x1 = 0; if (x2>=vid.width) x2 = vid.width-1; if (planeheight != cachedheight[y]) { cachedheight[y] = planeheight; distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]); ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale); ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale); } else { distance = cacheddistance[y]; ds_xstep = cachedxstep[y]; ds_ystep = cachedystep[y]; } length = FixedMul (distance,distscale[x1]); angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; ds_xfrac = viewx + FixedMul(finecosine[angle], length); ds_yfrac = -viewy - FixedMul(finesine[angle], length); ds_xfrac -= offsetx; ds_yfrac += offsety; if (fixedcolormap) ds_colormap = fixedcolormap; else { index = distance >> LIGHTZSHIFT; if (index >= MAXLIGHTZ ) index = MAXLIGHTZ-1; ds_colormap = planezlight[index]; } ds_y = y; ds_x1 = x1; ds_x2 = x2; spanfunc (); // reset for next calls to edge rasterizer rastertab[y].minx = MAXINT; rastertab[y].maxx = MININT; }#else for (y=miny; y<=maxy; y++) { x1 = rastertab[y].minx >> FRACBITS; x2 = rastertab[y].maxx >> FRACBITS; /*if ((unsigned)x1 >= vid.width) continue; if ((unsigned)x2 >= vid.width) continue;*/ if (x1<0) x1 = 0; //if (x1>=vid.width) x1 = vid.width-1; //if (x2<0) x1 = 0; if (x2>=vid.width) x2 = vid.width-1; pDest = ylookup[y] + columnofs[x1]; x = (x2-x1) + 1; //point de d閜art dans la texture tx = rastertab[y].tx1; ty = rastertab[y].ty1; // HORRIBLE BUG!!! if(x>0) { tdx = (rastertab[y].tx2 - tx) / x; tdy = (rastertab[y].ty2 - ty) / x; while (x-- > 0) { *(pDest++) = (y&255); tx += tdx; ty += tdy; } } // r閕nitialise les minimus maximus pour le prochain appel rastertab[y].minx = MAXINT; rastertab[y].maxx = MININT; }#endif}// --------------------------------------------------------------------------// R_DrawFloorSplats// draw the flat floor/ceiling splats// --------------------------------------------------------------------------void R_DrawVisibleFloorSplats (void){ floorsplat_t* pSplat; int iCount = 0; fixed_t tr_x; fixed_t tr_y; fixed_t rot_x; fixed_t rot_y; fixed_t rot_z; fixed_t xscale; fixed_t yscale; vertex_t* v3d; vertex_t v2d[4]; int i; pSplat = visfloorsplats; while (pSplat) { iCount++; // Draw a floor splat // 3--2 // | | // 0--1 rot_z = pSplat->z - viewz; for (i=0; i<4; i++) { v3d = &pSplat->verts[i]; // transform the origin point tr_x = v3d->x - viewx; tr_y = v3d->y - viewy; // rotation around vertical y axis rot_x = FixedMul(tr_x,viewsin) - FixedMul(tr_y,viewcos); rot_y = FixedMul(tr_x,viewcos) + FixedMul(tr_y,viewsin); if (rot_y < 4*FRACUNIT) goto skipit; // note: y from view above of map, is distance far away xscale = FixedDiv(projection, rot_y); yscale = -FixedDiv(projectiony, rot_y); // projection v2d[i].x = (centerxfrac + FixedMul (rot_x, xscale)) >>FRACBITS; v2d[i].y = (centeryfrac + FixedMul (rot_z, yscale)) >>FRACBITS; } /* pSplat->verts[3].x = 100 + iCount; pSplat->verts[3].y = 10 + iCount; pSplat->verts[2].x = 160 + iCount; pSplat->verts[2].y = 80 + iCount; pSplat->verts[1].x = 100 + iCount; pSplat->verts[1].y = 150 + iCount; pSplat->verts[0].x = 8 + iCount; pSplat->verts[0].y = 90 + iCount; */ R_RenderFloorSplat (pSplat, v2d, NULL);skipit: pSplat = pSplat->nextvis; } CONS_Printf ("%d floor splats in view\n", iCount);}static void prepare_rastertab (void){ int iLine; for (iLine=0; iLine<vid.height; iLine++) { rastertab[iLine].minx = MAXINT; rastertab[iLine].maxx = MININT; }}#endif // FLOORSPLATS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -