Merge pull request #415 from 0lvin/for_review

Soft render speed up
This commit is contained in:
Yamagi 2019-06-25 15:21:50 +02:00 committed by GitHub
commit 75c0450508
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 448 additions and 297 deletions

View file

@ -151,14 +151,8 @@ extern oldrefdef_t r_refdef;
#define TRANSPARENT_COLOR 0xFF
#define TURB_TEX_SIZE 64 // base turbulent texture size
#define CYCLE 128 // turbulent cycle size
#define SCANBUFFERPAD 0x1000
#define DS_SPAN_LIST_END -128
// flags in finalvert_t.flags
#define ALIAS_LEFT_CLIP 0x0001
#define ALIAS_TOP_CLIP 0x0002
@ -175,8 +169,6 @@ extern oldrefdef_t r_refdef;
#define XCENTERING (1.0 / 2.0)
#define YCENTERING (1.0 / 2.0)
#define CLIP_EPSILON 0.001
#define BACKFACE_EPSILON 0.01
#define NEAR_CLIP 0.01
@ -184,9 +176,9 @@ extern oldrefdef_t r_refdef;
#define ALIAS_Z_CLIP_PLANE 4
// turbulence stuff
#define AMP 8*0x10000
#define AMP2 3
#define SPEED 20
#define AMP 8*0x10000
#define AMP2 3
#define SPEED 20
/*
@ -310,19 +302,24 @@ typedef struct surf_s
// -1 = in inverted span (end before
// start)
int flags; // currentface flags
msurface_t *msurf;
msurface_t *msurf;
entity_t *entity;
float nearzi; // nearest 1/z on surface, for mipmapping
qboolean insubmodel;
float d_ziorigin, d_zistepu, d_zistepv;
} surf_t;
typedef unsigned short surfindex_t;
// surface index size
#define SURFINDEX_MAX (1 << (sizeof(surfindex_t) * 8))
typedef struct edge_s
{
shift20_t u;
shift20_t u_step;
struct edge_s *prev, *next;
unsigned short surfs[2];
surfindex_t surfs[2];
struct edge_s *nextremove;
float nearzi;
medge_t *owner;
@ -357,14 +354,14 @@ extern pixel_t *r_warpbuffer;
extern float scale_for_mip;
extern float d_sdivzstepu, d_tdivzstepu, d_zistepu;
extern float d_sdivzstepv, d_tdivzstepv, d_zistepv;
extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
extern float d_sdivzstepu, d_tdivzstepu;
extern float d_sdivzstepv, d_tdivzstepv;
extern float d_sdivzorigin, d_tdivzorigin;
void D_DrawSpansPow2(espan_t *pspans);
void D_DrawZSpans(espan_t *pspans);
void TurbulentPow2(espan_t *pspan);
void NonTurbulentPow2(espan_t *pspan);
void D_DrawSpansPow2(espan_t *pspans, float d_ziorigin, float d_zistepu, float d_zistepv);
void D_DrawZSpans(espan_t *pspans, float d_ziorigin, float d_zistepu, float d_zistepv);
void TurbulentPow2(espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv);
void NonTurbulentPow2(espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv);
surfcache_t *D_CacheSurface(const entity_t *currententity, msurface_t *surface, int miplevel);
@ -394,6 +391,8 @@ extern vec3_t vpn, base_vpn;
extern vec3_t vright, base_vright;
extern surf_t *surfaces, *surface_p, *surf_max;
// allow some very large lightmaps
extern light_t *blocklights, *blocklight_max;
// surfaces are generated in back to front order by the bsp, so if a surf
// pointer is greater than another one, it should be drawn in front
@ -457,14 +456,12 @@ extern msurface_t *r_alpha_surfaces;
//
// current entity info
//
extern qboolean insubmodel;
void R_DrawAlphaSurfaces(const entity_t *currententity);
void R_DrawSprite(entity_t *currententity, const model_t *currentmodel);
void R_RenderFace(entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags);
void R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf);
void R_RenderFace(entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags, qboolean insubmodel);
void R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf, int r_currentbkey);
void R_TransformFrustum(void);
void R_DrawSubmodelPolygons(entity_t *currententity, const model_t *currentmodel, int clipflags, mnode_t *topnode);
@ -483,7 +480,6 @@ extern int sadjust, tadjust;
extern int bbextents, bbextentt;
extern int r_currentkey;
extern int r_currentbkey;
void R_DrawParticles (void);
@ -509,7 +505,9 @@ void R_PolysetDrawSpans8_Opaque(const entity_t *currententity, spanpackage_t *ps
extern byte **warp_rowptr;
extern int *warp_column;
extern espan_t *edge_basespans;
extern espan_t *max_span_p;
extern int r_numallocatedverts;
extern int r_numallocatededgebasespans;
extern finalvert_t *finalverts, *finalverts_max;
extern int r_aliasblendcolor;
@ -520,6 +518,8 @@ extern qboolean r_outofsurfaces;
extern qboolean r_outofedges;
extern qboolean r_outofverts;
extern qboolean r_outoftriangles;
extern qboolean r_outoflights;
extern qboolean r_outedgebasespans;
extern mvertex_t *r_pcurrentvertbase;
@ -530,7 +530,7 @@ void R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index
extern float r_time1;
extern float da_time1, da_time2;
extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
extern float se_time1, se_time2, de_time1, de_time2;
extern int r_viewcluster, r_oldviewcluster;
extern int r_clipflags;
@ -589,6 +589,6 @@ IMPORTED FUNCTIONS
====================================================================
*/
extern refimport_t ri;
extern refimport_t ri;
#endif

View file

@ -46,11 +46,6 @@ typedef struct
vec3_t position;
} mvertex_t;
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2
// plane_t structure
typedef struct mplane_s
{
@ -231,9 +226,6 @@ typedef struct model_s
//============================================================================
void Mod_Init(void);
void Mod_ClearAll(void);
void *Mod_Extradata(model_t *mod); // handles caching
void Mod_TouchModel(char *name);
mleaf_t *Mod_PointInLeaf(float *p, model_t *model);
byte *Mod_ClusterPVS(int cluster, model_t *model);

View file

@ -31,8 +31,6 @@ vec3_t r_entorigin; // the currently rendering entity in world
static float entity_rotation[3][3];
int r_currentbkey;
typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
#define MAX_BMODEL_VERTS 500 // 6K
@ -141,6 +139,24 @@ R_RotateBmodel(const entity_t *currententity)
}
static qboolean
R_AreaVisible(mleaf_t *pleaf)
{
int area;
// check for door connected areas
if (!r_newrefdef.areabits)
return true;
area = pleaf->area;
if ((r_newrefdef.areabits[area>>3] & (1<<(area&7))))
return true;
return false; // not visible
}
/*
================
R_RecursiveClipBPoly
@ -223,25 +239,23 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
// split into two edges, one on each side, and remember entering
// and exiting points
// FIXME: share the clip edge by having a winding direction flag?
if (numbedges >= (MAX_BMODEL_EDGES - 1))
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[lastside];
psideedges[lastside] = ptedge;
ptedge->v[0] = plastvert;
ptedge->v[1] = ptvert;
ptedge = &bedges[numbedges + 1];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[side];
psideedges[side] = ptedge;
ptedge->v[0] = ptvert;
ptedge->v[1] = pvert;
numbedges += 2;
if (numbedges >= MAX_BMODEL_EDGES)
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
if (side == 0)
{
@ -266,25 +280,23 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
// plane to both sides (but in opposite directions)
if (makeclippededge && pfrontexit != pfrontenter)
{
if (numbedges >= (MAX_BMODEL_EDGES - 2))
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[0];
psideedges[0] = ptedge;
ptedge->v[0] = pfrontexit;
ptedge->v[1] = pfrontenter;
ptedge = &bedges[numbedges + 1];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[1];
psideedges[1] = ptedge;
ptedge->v[0] = pfrontenter;
ptedge->v[1] = pfrontexit;
numbedges += 2;
if (numbedges >= MAX_BMODEL_EDGES)
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
}
// draw or recurse further
@ -303,17 +315,13 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
{
if (pn->contents != CONTENTS_SOLID)
{
if (r_newrefdef.areabits)
{
int area;
int r_currentbkey;
area = ((mleaf_t *)pn)->area;
if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) )
continue; // not visible
}
if (!R_AreaVisible((mleaf_t *)pn))
continue;
r_currentbkey = ((mleaf_t *)pn)->key;
R_RenderBmodelFace(currententity, psideedges[i], psurf);
R_RenderBmodelFace(currententity, psideedges[i], psurf, r_currentbkey);
}
}
else
@ -399,14 +407,14 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
pbedge[j-1].pnext = NULL; // mark end of edges
if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) )
if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ))
{
// FIXME: Fan broken in borehole
R_RecursiveClipBPoly(currententity, pbedge, topnode, psurf);
}
else
{
R_RenderBmodelFace(currententity, pbedge, psurf );
R_RenderBmodelFace(currententity, pbedge, psurf, ((mleaf_t *)topnode)->key);
}
}
}
@ -446,7 +454,7 @@ R_DrawSubmodelPolygons(entity_t *currententity, const model_t *currentmodel, int
r_currentkey = ((mleaf_t *)topnode)->key;
// FIXME: use bounding-box-based frustum clipping info?
R_RenderFace(currententity, currentmodel, psurf, clipflags);
R_RenderFace(currententity, currentmodel, psurf, clipflags, true);
}
}
}
@ -460,7 +468,8 @@ R_RecursiveWorldNode
================
*/
static void
R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnode_t *node, int clipflags)
R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnode_t *node,
int clipflags, qboolean insubmodel)
{
int c;
vec3_t acceptpt, rejectpt;
@ -519,12 +528,8 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
msurface_t **mark;
pleaf = (mleaf_t *)node;
// check for door connected areas
if (r_newrefdef.areabits)
{
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
return; // not visible
}
if (!R_AreaVisible(pleaf))
return; // not visible
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
@ -573,7 +578,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
side = 1;
// recurse down the children, front side first
R_RecursiveWorldNode (currententity, currentmodel, node->children[side], clipflags);
R_RecursiveWorldNode (currententity, currentmodel, node->children[side], clipflags, insubmodel);
// draw stuff
c = node->numsurfaces;
@ -591,7 +596,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if ((surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount))
{
R_RenderFace (currententity, currentmodel, surf, clipflags);
R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
}
surf++;
@ -604,7 +609,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if (!(surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount))
{
R_RenderFace (currententity, currentmodel, surf, clipflags);
R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
}
surf++;
@ -616,7 +621,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
}
// recurse down the back side
R_RecursiveWorldNode (currententity, currentmodel, node->children[!side], clipflags);
R_RecursiveWorldNode (currententity, currentmodel, node->children[!side], clipflags, insubmodel);
}
}
@ -643,5 +648,5 @@ R_RenderWorld (void)
VectorCopy (r_origin, modelorg);
r_pcurrentvertbase = currentmodel->vertexes;
R_RecursiveWorldNode (&r_worldentity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK);
R_RecursiveWorldNode (&r_worldentity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK, false);
}

View file

@ -77,13 +77,16 @@ smoothly scrolled off.
void
RE_Draw_CharScaled(int x, int y, int num, float scale)
{
pixel_t *dest, *dest_max;
pixel_t *dest;
byte *source;
int drawline;
int row, col, u, xpos, ypos, iscale;
int drawline;
int row, col, u, xpos, ypos, iscale;
iscale = (int) scale;
if (iscale < 1)
return;
num &= 255;
if (num == 32 || num == 32+128)
@ -109,7 +112,12 @@ RE_Draw_CharScaled(int x, int y, int num, float scale)
drawline = 8;
dest = vid_buffer + y * vid.width + x;
dest_max = vid_buffer + vid.height * vid.width;
// clipped last lines
if ((y + iscale * (drawline + 1)) > vid.height)
{
drawline = (vid.height - y) / iscale;
}
while (drawline--)
{
@ -124,12 +132,6 @@ RE_Draw_CharScaled(int x, int y, int num, float scale)
}
}
dest += vid.width;
// clipped last lines
if (dest >= dest_max)
{
return;
}
}
source += 128;
}
@ -160,14 +162,13 @@ RE_Draw_GetPicSize (int *w, int *h, char *pic)
RE_Draw_StretchPicImplementation
=============
*/
void
static void
RE_Draw_StretchPicImplementation (int x, int y, int w, int h, const image_t *pic)
{
pixel_t *dest;
byte *source;
int v, u;
int height;
int f, fstep;
int skip;
if ((x < 0) ||
@ -189,16 +190,24 @@ RE_Draw_StretchPicImplementation (int x, int y, int w, int h, const image_t *pic
dest = vid_buffer + y * vid.width + x;
for (v=0 ; v<height ; v++, dest += vid.width)
if (w == pic->width)
{
int sv = (skip + v)*pic->height/h;
source = pic->pixels[0] + sv*pic->width;
if (w == pic->width)
memcpy (dest, source, w);
else
for (v=0 ; v<height ; v++, dest += vid.width)
{
int sv = (skip + v)*pic->height/h;
source = pic->pixels[0] + sv*pic->width;
memcpy (dest, source, w);
}
}
else
{
for (v=0 ; v<height ; v++, dest += vid.width)
{
int f, fstep;
int sv = (skip + v)*pic->height/h;
source = pic->pixels[0] + sv*pic->width;
f = 0;
fstep = (pic->width * SHIFT16XYZ_MULT) / w;
fstep = (pic->width << SHIFT16XYZ) / w;
for (u=0 ; u<w ; u++)
{
dest[u] = source[f>>16];
@ -266,8 +275,8 @@ RE_Draw_PicScaled(int x, int y, char *name, float scale)
}
if ((x < 0) ||
(x + pic->width > vid.width) ||
(y + pic->height > vid.height))
(x + pic->width * scale > vid.width) ||
(y + pic->height * scale > vid.height))
{
R_Printf(PRINT_ALL, "Draw_Pic: bad coordinates\n");
return;

View file

@ -36,8 +36,9 @@ have a sentinal at both ends?
edge_t **newedges;
edge_t **removeedges;
espan_t *edge_basespans;
espan_t *max_span_p;
static espan_t *span_p, *max_span_p;
static espan_t *span_p;
int r_currentkey;
@ -107,7 +108,8 @@ R_BeginEdgeFrame (void)
R_InsertNewEdges
Adds the edges in the linked list edgestoadd, adding them to the edges in the
linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty
(this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
sentinel at the end (actually, this is the active edge table starting at
edge_head.next).
==============
@ -205,6 +207,22 @@ R_StepActiveU (edge_t *pedge)
}
}
static void
R_InsertSpan (surf_t *surf, shift20_t iu)
{
if (iu > surf->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
}
/*
==============
R_CleanupSpan
@ -214,22 +232,11 @@ static void
R_CleanupSpan (void)
{
surf_t *surf;
shift20_t iu;
espan_t *span;
// now that we've reached the right edge of the screen, we're done with any
// unfinished surfaces, so emit a span for whatever's on top
surf = surfaces[1].next;
iu = edge_tail_u_shift20;
if (iu > surf->last_u)
{
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
R_InsertSpan (surf, edge_tail_u_shift20);
// reset spanstate for all surfaces in the surface stack
do
@ -295,17 +302,7 @@ R_LeadingEdgeBackwards (const edge_t *edge)
// emit a span (obscures current top)
iu = edge->u >> shift_size;
if (iu > surf2->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf2->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf2->spans;
surf2->spans = span;
}
R_InsertSpan (surf2, iu);
// set last_u on the new span
surf->last_u = iu;
@ -332,8 +329,6 @@ R_TrailingEdge
static void
R_TrailingEdge (surf_t *surf, edge_t *edge)
{
espan_t *span;
// don't generate a span if this is an inverted span, with the end
// edge preceding the start edge (that is, we haven't seen the
// start edge yet)
@ -345,15 +340,7 @@ R_TrailingEdge (surf_t *surf, edge_t *edge)
// emit a span (current top going away)
iu = edge->u >> shift_size;
if (iu > surf->last_u)
{
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
R_InsertSpan (surf, iu);
// set last_u on the surface below
surf->next->last_u = iu;
@ -451,17 +438,7 @@ R_EmitSpanBeforeTop(const edge_t *edge, surf_t *surf, surf_t *surf2)
iu = edge->u >> shift_size;
if (iu > surf2->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf2->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf2->spans;
surf2->spans = span;
}
R_InsertSpan (surf2, iu);
// set last_u on the new span
surf->last_u = iu;
@ -623,18 +600,23 @@ void
R_ScanEdges (surf_t *surface)
{
shift20_t iv, bottom;
espan_t *basespan_p;
surf_t *s;
basespan_p = edge_basespans;
max_span_p = edge_basespans + vid.width * 2 - r_refdef.vrect.width;
if ((vid.width * 2 - r_refdef.vrect.width) < 0)
// clear the surface span pointers
for (s = &surfaces[1] ; s<surf_max ; s++)
{
R_Printf(PRINT_ALL,"No space in edge_basespans\n");
return;
s->last_u = 0;
s->spans = NULL;
}
span_p = basespan_p;
span_p = edge_basespans;
if (span_p + r_refdef.vrect.width >= max_span_p)
{
// Need to more space
r_outedgebasespans = true;
return;
}
// clear active edges to just the background edges around the whole screen
// FIXME: most of this only needs to be set up once
@ -687,7 +669,7 @@ R_ScanEdges (surf_t *surface)
// flush the span list if we can't be sure we have enough spans left for
// the next scan
if (span_p >= max_span_p)
if (span_p + r_refdef.vrect.width >= max_span_p)
{
// Draw stuff on screen
D_DrawSurfaces (surface);
@ -696,7 +678,10 @@ R_ScanEdges (surf_t *surface)
for (s = &surfaces[1] ; s<surface ; s++)
s->spans = NULL;
span_p = basespan_p;
span_p = edge_basespans;
// Need to more space
r_outedgebasespans = true;
}
if (removeedges[iv])
@ -793,7 +778,7 @@ D_CalcGradients
==============
*/
static void
D_CalcGradients (msurface_t *pface)
D_CalcGradients (msurface_t *pface, float d_ziorigin, float d_zistepu, float d_zistepv)
{
float mipscale;
vec3_t p_temp1;
@ -855,14 +840,10 @@ The grey background filler seen when there is a hole in the map
static void
D_BackgroundSurf (surf_t *s)
{
D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
// set up a gradient for the background surface that places it
// effectively at infinity distance from the viewpoint
d_zistepu = 0;
d_zistepv = 0;
d_ziorigin = -0.9;
D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
D_DrawZSpans (s->spans);
D_DrawZSpans (s->spans, -0.9, 0, 0);
}
/*
@ -873,10 +854,6 @@ D_TurbulentSurf
static void
D_TurbulentSurf(surf_t *s)
{
d_zistepu = s->d_zistepu;
d_zistepv = s->d_zistepv;
d_ziorigin = s->d_ziorigin;
pface = s->msurf;
miplevel = 0;
cacheblock = pface->texinfo->image->pixels[0];
@ -898,17 +875,17 @@ D_TurbulentSurf(surf_t *s)
// make entity passed in
}
D_CalcGradients (pface);
D_CalcGradients (pface, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
//============
// textures that aren't warping are just flowing. Use NonTurbulentPow2 instead
if(!(pface->texinfo->flags & SURF_WARP))
NonTurbulentPow2 (s->spans);
NonTurbulentPow2 (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
else
TurbulentPow2 (s->spans);
TurbulentPow2 (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
//============
D_DrawZSpans (s->spans);
D_DrawZSpans (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
if (s->insubmodel)
{
@ -941,21 +918,13 @@ D_SkySurf (surf_t *s)
cacheblock = pface->texinfo->image->pixels[0];
cachewidth = 256;
d_zistepu = s->d_zistepu;
d_zistepv = s->d_zistepv;
d_ziorigin = s->d_ziorigin;
D_CalcGradients (pface, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
D_CalcGradients (pface);
D_DrawSpansPow2 (s->spans);
D_DrawSpansPow2 (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
// set up a gradient for the background surface that places it
// effectively at infinity distance from the viewpoint
d_zistepu = 0;
d_zistepv = 0;
d_ziorigin = -0.9;
D_DrawZSpans (s->spans);
D_DrawZSpans (s->spans, -0.9, 0, 0);
}
/*
@ -970,10 +939,6 @@ D_SolidSurf (surf_t *s)
{
entity_t *currententity;
d_zistepu = s->d_zistepu;
d_zistepv = s->d_zistepv;
d_ziorigin = s->d_ziorigin;
if (s->insubmodel)
{
vec3_t local_modelorg;
@ -999,11 +964,11 @@ D_SolidSurf (surf_t *s)
cacheblock = (pixel_t *)pcurrentcache->data;
cachewidth = pcurrentcache->width;
D_CalcGradients (pface);
D_CalcGradients (pface, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
D_DrawSpansPow2 (s->spans);
D_DrawSpansPow2 (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
D_DrawZSpans (s->spans);
D_DrawZSpans (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
if (s->insubmodel)
{
@ -1039,14 +1004,10 @@ D_DrawflatSurfaces (surf_t *surface)
if (!s->spans)
continue;
d_zistepu = s->d_zistepu;
d_zistepv = s->d_zistepv;
d_ziorigin = s->d_ziorigin;
// make a stable color for each surface by taking the low
// bits of the msurface pointer
D_FlatFillSurface (s, color & 0xFF);
D_DrawZSpans (s->spans);
D_DrawZSpans (s->spans, s->d_ziorigin, s->d_zistepu, s->d_zistepv);
color ++;
}

View file

@ -265,7 +265,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color)
//===================================================================
unsigned blocklights[1024]; // allow some very large lightmaps
light_t *blocklights = NULL, *blocklight_max = NULL;
/*
===============
@ -292,6 +292,12 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
tmax = (surf->extents[1]>>4)+1;
tex = surf->texinfo;
if (blocklight_max <= blocklights + smax*tmax)
{
r_outoflights = true;
return;
}
for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
{
light_t *plightdest = blocklights;
@ -385,6 +391,11 @@ R_BuildLightMap (drawsurf_t* drawsurf)
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
size = smax*tmax;
if (blocklight_max <= blocklights + size)
{
r_outoflights = true;
return;
}
if (r_fullbright->value || !r_worldmodel->lightdata)
{

View file

@ -30,9 +30,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define NUMSTACKEDGES 2048
#define NUMSTACKSURFACES 1024
#define MAXALIASVERTS 2048
#define MAXLIGHTS 1024 // allow some very large lightmaps
viddef_t vid;
pixel_t *vid_buffer = NULL;
static pixel_t *swap_buffers = NULL;
static pixel_t *swap_frames[2] = {NULL, NULL};
static int swap_current = 0;
espan_t *vid_polygon_spans = NULL;
pixel_t *vid_colormap = NULL;
pixel_t *vid_alphamap = NULL;
@ -68,11 +72,15 @@ float r_time1;
int r_numallocatededges;
int r_numallocatedverts;
int r_numallocatedtriangles;
int r_numallocatedlights;
int r_numallocatededgebasespans;
float r_aliasuvscale = 1.0;
qboolean r_outofsurfaces;
qboolean r_outofedges;
qboolean r_outofverts;
qboolean r_outoftriangles;
qboolean r_outoflights;
qboolean r_outedgebasespans;
qboolean r_dowarp;
@ -176,9 +184,9 @@ static cvar_t *r_lockpvs;
// FIXME: make into one big structure, like cl or sv
// FIXME: do separately for refresh engine and driver
float d_sdivzstepu, d_tdivzstepu, d_zistepu;
float d_sdivzstepv, d_tdivzstepv, d_zistepv;
float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
float d_sdivzstepu, d_tdivzstepu;
float d_sdivzstepv, d_tdivzstepv;
float d_sdivzorigin, d_tdivzorigin;
int sadjust, tadjust, bbextents, bbextentt;
@ -187,11 +195,11 @@ int cachewidth;
pixel_t *d_viewbuffer;
zvalue_t *d_pzbuffer;
qboolean insubmodel;
static void Draw_GetPalette (void);
static void RE_BeginFrame( float camera_separation );
static void Draw_BuildGammaTable(void);
static void RE_FlushFrame(int vmin);
static void RE_CleanFrame(void);
static void RE_EndFrame(void);
static void R_DrawBeam(const entity_t *e);
@ -382,6 +390,14 @@ R_ReallocateMapBuffers (void)
if (r_cnumsurfs < NUMSTACKSURFACES)
r_cnumsurfs = NUMSTACKSURFACES;
// edge_t->surf limited size to short
if (r_cnumsurfs > SURFINDEX_MAX)
{
r_cnumsurfs = SURFINDEX_MAX;
R_Printf(PRINT_ALL, "%s: Code has limitation to surfaces count.\n",
__func__);
}
lsurfs = malloc (r_cnumsurfs * sizeof(surf_t));
if (!lsurfs)
{
@ -393,14 +409,46 @@ R_ReallocateMapBuffers (void)
surfaces = lsurfs;
// set limits
surf_max = &surfaces[r_cnumsurfs];
surface_p = lsurfs;
// surface 0 doesn't really exist; it's just a dummy because index 0
// is used to indicate no edge attached to surface
surfaces--;
surface_p = &surfaces[2]; // background is surface 1,
// surface 0 is a dummy
R_Printf(PRINT_ALL, "Allocated %d surfaces\n", r_cnumsurfs);
}
if (!r_numallocatedlights || r_outoflights)
{
if (!blocklights)
{
free(blocklights);
}
if (r_outoflights)
{
r_numallocatedlights *= 2;
r_outoflights = false;
}
if (r_numallocatedlights < MAXLIGHTS)
r_numallocatedlights = MAXLIGHTS;
blocklights = malloc (r_numallocatedlights * sizeof(light_t));
if (!blocklights)
{
R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n",
__func__, (int)(r_numallocatedlights * sizeof(light_t)));
return;
}
// set limits
blocklight_max = &blocklights[r_numallocatedlights];
R_Printf(PRINT_ALL, "Allocated %d lights\n", r_numallocatedlights);
}
if (!r_numallocatededges || r_outofedges)
{
if (!r_edges)
@ -487,6 +535,35 @@ R_ReallocateMapBuffers (void)
R_Printf(PRINT_ALL, "Allocated %d triangles\n", r_numallocatedtriangles);
}
if (!r_numallocatededgebasespans || r_outedgebasespans)
{
if (edge_basespans)
{
free(edge_basespans);
}
if (r_outedgebasespans)
{
r_numallocatededgebasespans *= 2;
r_outedgebasespans = false;
}
// used up to 8 * width spans for render, allocate once before use
if (r_numallocatededgebasespans < vid.width * 8)
r_numallocatededgebasespans = vid.width * 8;
edge_basespans = malloc(r_numallocatededgebasespans * sizeof(espan_t));
if (!edge_basespans)
{
R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n",
__func__, (int)(r_numallocatededgebasespans * sizeof(espan_t)));
return;
}
max_span_p = &edge_basespans[r_numallocatededgebasespans];
R_Printf(PRINT_ALL, "Allocated %d edgespans\n", r_numallocatededgebasespans);
}
}
@ -839,7 +916,6 @@ R_DrawBEntitiesOnList (void)
return;
VectorCopy (modelorg, oldorigin);
insubmodel = true;
for (i=0 ; i<r_newrefdef.num_entities ; i++)
{
@ -901,8 +977,6 @@ R_DrawBEntitiesOnList (void)
VectorCopy (oldorigin, modelorg);
R_TransformFrustum ();
}
insubmodel = false;
}
/*
@ -1242,10 +1316,7 @@ RE_SetPalette(const unsigned char *palette)
byte palette32[1024];
// clear screen to black to avoid any palette flash
memset(vid_buffer, 0, vid.height * vid.width * sizeof(pixel_t));
// flush it to the screen
RE_EndFrame ();
RE_CleanFrame();
if (palette)
{
@ -1592,11 +1663,14 @@ RE_InitContext(void *win)
static void
RE_ShutdownContext(void)
{
if (vid_buffer)
if (swap_buffers)
{
free(vid_buffer);
free(swap_buffers);
}
swap_buffers = NULL;
vid_buffer = NULL;
swap_frames[0] = NULL;
swap_frames[1] = NULL;
if (sintable)
{
@ -1664,6 +1738,12 @@ RE_ShutdownContext(void)
}
finalverts = NULL;
if(blocklights)
{
free(blocklights);
}
blocklights = NULL;
if(r_edges)
{
free(r_edges);
@ -1702,7 +1782,7 @@ point math used in R_ScanEdges() overflows at width 2048 !!
char shift_size;
static void
RE_CopyFrame (Uint32 * pixels, int pitch)
RE_CopyFrame (Uint32 * pixels, int pitch, int vmin, int vmax)
{
Uint32 *sdl_palette = (Uint32 *)sw_state.currentpalette;
@ -1713,10 +1793,10 @@ RE_CopyFrame (Uint32 * pixels, int pitch)
Uint32 *pixels_pos;
pixel_t *buffer_pos;
max_pixels = pixels + vid.height * vid.width;
buffer_pos = vid_buffer;
max_pixels = pixels + vmax * vid.width;
buffer_pos = vid_buffer + vmin * vid.width;
for (pixels_pos = pixels; pixels_pos < max_pixels; pixels_pos++)
for (pixels_pos = pixels + vmin * vid.width; pixels_pos < max_pixels; pixels_pos++)
{
*pixels_pos = sdl_palette[*buffer_pos];
buffer_pos++;
@ -1727,7 +1807,7 @@ RE_CopyFrame (Uint32 * pixels, int pitch)
int y,x, buffer_pos;
buffer_pos = 0;
for (y=0; y < vid.height; y++)
for (y=vmin; y < vmax; y++)
{
for (x=0; x < vid.width; x ++)
{
@ -1739,32 +1819,89 @@ RE_CopyFrame (Uint32 * pixels, int pitch)
}
}
/*
** RE_EndFrame
**
** This does an implementation specific copy from the backbuffer to the
** front buffer. In the Win32 case it uses BitBlt or BltFast depending
** on whether we're using DIB sections/GDI or DDRAW.
*/
static int
RE_BufferDifferenceStart(int vmin, int vmax)
{
int *front_buffer, *back_buffer, *back_max;
back_buffer = (int*)swap_frames[0] + vmin * vid.width;
front_buffer = (int*)swap_frames[1] + vmin * vid.width;
back_max = (int*)swap_frames[0] + vmax * vid.width;
while (back_buffer < back_max && *back_buffer == *front_buffer) {
back_buffer ++;
front_buffer ++;
}
return ((pixel_t*)back_buffer - swap_frames[0]) / vid.width;
}
static void
RE_EndFrame (void)
RE_CleanFrame(void)
{
int pitch;
Uint32 * pixels;
Uint32 *pixels;
memset(swap_buffers, 0, vid.height * vid.width * sizeof(pixel_t) * 2);
if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
{
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
return;
}
RE_CopyFrame (pixels, pitch / sizeof(Uint32));
memset(pixels, 0, pitch * vid.height);
SDL_UnlockTexture(texture);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
static void
RE_FlushFrame(int vmin)
{
int pitch;
Uint32 *pixels;
SDL_Rect copy_rect;
copy_rect.x = 0;
copy_rect.y = vmin;
copy_rect.w = vid.width;
copy_rect.h = vid.height - vmin;
if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
{
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
return;
}
RE_CopyFrame (pixels, pitch / sizeof(Uint32), vmin, vid.height);
SDL_UnlockTexture(texture);
SDL_RenderCopy(renderer, texture, &copy_rect, &copy_rect);
SDL_RenderPresent(renderer);
// replace use next buffer
swap_current ++;
vid_buffer = swap_frames[swap_current&1];
}
/*
** RE_EndFrame
**
** This does an implementation specific copy from the backbuffer to the
** front buffer.
*/
static void
RE_EndFrame (void)
{
int vmin;
vmin = RE_BufferDifferenceStart(0, vid.height);
if (vmin >= vid.height)
{
return;
}
RE_FlushFrame(vmin);
}
/*
** SWimp_SetMode
*/
@ -1807,7 +1944,11 @@ SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen )
static void
SWimp_CreateRender(void)
{
vid_buffer = malloc(vid.height * vid.width * sizeof(pixel_t));
swap_current = 0;
swap_buffers = malloc(vid.height * vid.width * sizeof(pixel_t) * 2);
swap_frames[0] = swap_buffers;
swap_frames[1] = swap_buffers + vid.height * vid.width * sizeof(pixel_t);
vid_buffer = swap_frames[swap_current&1];
sintable = malloc((vid.width+CYCLE) * sizeof(int));
intsintable = malloc((vid.width+CYCLE) * sizeof(int));
@ -1819,17 +1960,27 @@ SWimp_CreateRender(void)
warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*));
warp_column = malloc((vid.width+AMP2*2) * sizeof(int));
edge_basespans = malloc((vid.width*2) * sizeof(espan_t));
// count of "out of items"
r_outofsurfaces = r_outofedges = r_outofverts = r_outoftriangles = false;
r_outofsurfaces = false;
r_outofedges = false;
r_outofverts = false;
r_outoftriangles = false;
r_outoflights = false;
r_outedgebasespans = false;
// pointers to allocated buffers
finalverts = NULL;
r_edges = NULL;
lsurfs = NULL;
triangle_spans = NULL;
blocklights = NULL;
edge_basespans = NULL;
// curently allocated items
r_cnumsurfs = r_numallocatededges = r_numallocatedverts = r_numallocatedtriangles = 0;
r_cnumsurfs = 0;
r_numallocatededges = 0;
r_numallocatedverts = 0;
r_numallocatedtriangles = 0;
r_numallocatedlights = 0;
r_numallocatededgebasespans = 0;
R_ReallocateMapBuffers();

View file

@ -43,9 +43,7 @@ D_ViewChanged
static void
D_ViewChanged (void)
{
scale_for_mip = xscale;
if (yscale > xscale)
scale_for_mip = yscale;
scale_for_mip = sqrt(xscale*xscale + yscale*yscale);
d_pix_min = r_refdef.vrect.height / 240;
if (d_pix_min < 1)

View file

@ -494,15 +494,9 @@ Mod_LoadTexinfo (lump_t *l)
}
len1 = VectorLength (out->vecs[0]);
len2 = VectorLength (out->vecs[1]);
len1 = (len1 + len2)/2;
if (len1 < 0.32)
out->mipadjust = 4;
else if (len1 < 0.49)
out->mipadjust = 3;
else if (len1 < 0.99)
out->mipadjust = 2;
else
out->mipadjust = 1;
out->mipadjust = sqrt(len1*len1 + len2*len2);
if (out->mipadjust < 0.01)
out->mipadjust = 0.01;
out->flags = LittleLong (in->flags);
@ -1226,6 +1220,8 @@ SPRITE MODELS
/*
=================
Mod_LoadSpriteModel
support for .sp2 sprites
=================
*/
static void

View file

@ -101,6 +101,11 @@ R_DrawParticle(particle_t *pparticle, int level)
** render the appropriate pixels
*/
count = pix;
if ((pz[(vid.width * count / 2) + (count / 2)]) > izi)
{
// looks like under some object
return;
}
if (custom_particle == 0)
{

View file

@ -592,7 +592,7 @@ R_ClipPolyFace (int nump, clipplane_t *pclipplane)
*/
// iswater was qboolean. changed to allow passing more flags
static void
R_PolygonDrawSpans(espan_t *pspan, int iswater )
R_PolygonDrawSpans(espan_t *pspan, int iswater, float d_ziorigin, float d_zistepu, float d_zistepv)
{
int snext, tnext;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
@ -749,7 +749,7 @@ R_PolygonDrawSpans(espan_t *pspan, int iswater )
pspan++;
} while (pspan->count != DS_SPAN_LIST_END);
} while (pspan->count != INT_MIN);
}
/*
@ -818,6 +818,8 @@ R_PolygonScanLeftEdge (espan_t *s_polygon_spans)
i = r_polydesc.nump;
} while (i != lmaxindex);
pspan->count = INT_MIN; // mark the end of the span list
}
/*
@ -903,7 +905,7 @@ R_PolygonScanRightEdge(espan_t *s_polygon_spans)
} while (i != s_maxindex);
pspan->count = DS_SPAN_LIST_END; // mark the end of the span list
pspan->count = INT_MIN; // mark the end of the span list
}
/*
@ -1111,10 +1113,11 @@ R_BuildPolygonFromSurface(const entity_t *currententity, const model_t *currentm
** R_PolygonCalculateGradients
*/
static void
R_PolygonCalculateGradients (void)
R_PolygonCalculateGradients (float *p_ziorigin, float *p_zistepu, float *p_zistepv)
{
vec3_t p_normal, p_saxis, p_taxis;
float distinv;
vec3_t p_normal, p_saxis, p_taxis;
float distinv;
float d_ziorigin, d_zistepu, d_zistepv;
TransformVector (r_polydesc.vpn, p_normal);
TransformVector (r_polydesc.vright, p_saxis);
@ -1140,6 +1143,10 @@ R_PolygonCalculateGradients (void)
// -1 (-epsilon) so we never wander off the edge of the texture
bbextents = (r_polydesc.pixel_width << SHIFT16XYZ) - 1;
bbextentt = (r_polydesc.pixel_height << SHIFT16XYZ) - 1;
*p_zistepu = d_zistepu;
*p_zistepv = d_zistepv;
*p_ziorigin = d_ziorigin;
}
/*
@ -1157,6 +1164,7 @@ R_DrawPoly(int iswater, espan_t *spans)
int i, nump;
float ymin, ymax;
emitpoint_t *pverts;
float d_ziorigin, d_zistepu, d_zistepv;
// find the top and bottom vertices, and make sure there's at least one scan to
// draw
@ -1196,11 +1204,11 @@ R_DrawPoly(int iswater, espan_t *spans)
pverts = r_polydesc.pverts;
pverts[nump] = pverts[0];
R_PolygonCalculateGradients();
R_PolygonCalculateGradients(&d_ziorigin, &d_zistepu, &d_zistepv);
R_PolygonScanLeftEdge(spans);
R_PolygonScanRightEdge(spans);
R_PolygonDrawSpans(spans, iswater);
R_PolygonDrawSpans(spans, iswater, d_ziorigin, d_zistepu, d_zistepv);
}
/*

View file

@ -35,15 +35,9 @@ int c_faceclip; // number of faces clipped
clipplane_t view_clipplanes[4];
medge_t *r_pedge;
edge_t *r_edges = NULL, *edge_p = NULL, *edge_max = NULL;
surf_t *surfaces = NULL, *surface_p = NULL, *surf_max = NULL;
static qboolean r_leftclipped, r_rightclipped;
static qboolean makeleftedge, makerightedge;
static qboolean r_nearzionly;
int *sintable;
int *intsintable;
int *blanktable;
@ -163,7 +157,7 @@ R_EmitSkyBox
================
*/
static void
R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel)
R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel, qboolean insubmodel)
{
int i, j;
int oldkey;
@ -199,7 +193,7 @@ R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel)
r_currentkey = 0x7ffffff0;
for (i=0 ; i<6 ; i++)
{
R_RenderFace(currententity, currentmodel, r_skyfaces + i, ALIAS_XY_CLIP_MASK);
R_RenderFace(currententity, currentmodel, r_skyfaces + i, ALIAS_XY_CLIP_MASK, insubmodel);
}
r_currentkey = oldkey; // bsp sorting order
}
@ -210,10 +204,10 @@ R_EmitEdge
================
*/
static void
R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1, medge_t *r_pedge, qboolean r_nearzionly)
{
edge_t *edge, *pcheck;
int u_check;
int u_check;
float u, u_step;
vec3_t local, transformed;
float *world;
@ -387,14 +381,15 @@ R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
removeedges[v2] = edge;
}
/*
================
R_ClipEdge
================
*/
static void
R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip, medge_t *r_pedge,
qboolean *r_leftclipped, qboolean *r_rightclipped,
qboolean r_nearzionly)
{
if (clip)
{
@ -429,16 +424,18 @@ R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
if (clip->leftedge)
{
r_leftclipped = true;
*r_leftclipped = true;
r_leftexit = clipvert;
}
else if (clip->rightedge)
{
r_rightclipped = true;
*r_rightclipped = true;
r_rightexit = clipvert;
}
R_ClipEdge (pv0, &clipvert, clip->next);
R_ClipEdge (pv0, &clipvert, clip->next, r_pedge,
r_leftclipped, r_rightclipped,
r_nearzionly);
return;
}
else
@ -470,23 +467,25 @@ R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
if (clip->leftedge)
{
r_leftclipped = true;
*r_leftclipped = true;
r_leftenter = clipvert;
}
else if (clip->rightedge)
{
r_rightclipped = true;
*r_rightclipped = true;
r_rightenter = clipvert;
}
R_ClipEdge (&clipvert, pv1, clip->next);
R_ClipEdge (&clipvert, pv1, clip->next, r_pedge,
r_leftclipped, r_rightclipped,
r_nearzionly);
return;
}
} while ((clip = clip->next) != NULL);
}
// add the edge
R_EmitEdge (pv0, pv1);
R_EmitEdge (pv0, pv1, r_pedge, r_nearzionly);
}
/*
@ -495,7 +494,7 @@ R_EmitCachedEdge
================
*/
static void
R_EmitCachedEdge (void)
R_EmitCachedEdge (medge_t *r_pedge)
{
edge_t *pedge_t;
@ -519,7 +518,8 @@ R_RenderFace
================
*/
void
R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags)
R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *fa,
int clipflags, qboolean insubmodel)
{
int i;
unsigned mask;
@ -528,6 +528,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
vec3_t p_normal;
medge_t *pedges, tedge;
clipplane_t *pclip;
qboolean r_leftclipped, r_rightclipped;
qboolean makeleftedge, makerightedge;
qboolean r_nearzionly;
// translucent surfaces are not drawn by the edge renderer
if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
@ -541,7 +544,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
// environment box surfaces to be emited
if ( fa->texinfo->flags & SURF_SKY )
{
R_EmitSkyBox (currententity, currentmodel);
R_EmitSkyBox (currententity, currentmodel, insubmodel);
return;
}
@ -552,7 +555,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
return;
}
// ditto if not enough edges left, or switch to auxedges if possible
// ditto if not enough edges left
if ((edge_p + fa->numedges + 4) >= edge_max)
{
r_outofedges = true;
@ -589,7 +592,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
if (lindex > 0)
{
r_pedge = &pedges[lindex];
medge_t *r_pedge = &pedges[lindex];
// if the edge is cached, we can just reuse the edge
if (!insubmodel)
@ -610,7 +613,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
(((edge_t *)((uintptr_t)r_edges +
r_pedge->cachededgeoffset))->owner == r_pedge))
{
R_EmitCachedEdge ();
R_EmitCachedEdge (r_pedge);
r_lastvertvalid = false;
continue;
}
@ -622,7 +625,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
r_leftclipped = r_rightclipped = false;
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
&r_pcurrentvertbase[r_pedge->v[1]],
pclip);
pclip, r_pedge,
&r_leftclipped, &r_rightclipped,
r_nearzionly);
r_pedge->cachededgeoffset = cacheoffset;
if (r_leftclipped)
@ -633,6 +638,8 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
}
else
{
medge_t *r_pedge;
lindex = -lindex;
r_pedge = &pedges[lindex];
// if the edge is cached, we can just reuse the edge
@ -656,7 +663,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
(((edge_t *)((uintptr_t)r_edges +
r_pedge->cachededgeoffset))->owner == r_pedge))
{
R_EmitCachedEdge ();
R_EmitCachedEdge (r_pedge);
r_lastvertvalid = false;
continue;
}
@ -668,7 +675,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
r_leftclipped = r_rightclipped = false;
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
&r_pcurrentvertbase[r_pedge->v[0]],
pclip);
pclip, r_pedge,
&r_leftclipped, &r_rightclipped,
r_nearzionly);
r_pedge->cachededgeoffset = cacheoffset;
if (r_leftclipped)
@ -684,18 +693,18 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
// FIXME: share clipped edges?
if (makeleftedge)
{
r_pedge = &tedge;
r_lastvertvalid = false;
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if there was a clip off the right edge, get the right r_nearzi
if (makerightedge)
{
r_pedge = &tedge;
r_lastvertvalid = false;
r_nearzionly = true;
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if no edges made it out, return without posting the surface
@ -735,15 +744,18 @@ R_RenderBmodelFace
================
*/
void
R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf, int r_currentbkey)
{
int i;
int i;
unsigned mask;
mplane_t *pplane;
float distinv;
vec3_t p_normal;
medge_t tedge;
clipplane_t *pclip;
qboolean r_leftclipped, r_rightclipped;
qboolean makeleftedge, makerightedge;
qboolean r_nearzionly;
if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
{
@ -759,7 +771,7 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
return;
}
// ditto if not enough edges left, or switch to auxedges if possible
// ditto if not enough edges left
if ((edge_p + psurf->numedges + 4) >= edge_max)
{
r_outofedges = true;
@ -768,9 +780,6 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
c_faceclip++;
// this is a dummy to give the caching mechanism someplace to write to
r_pedge = &tedge;
// set up clip planes
pclip = NULL;
@ -795,7 +804,8 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
for ( ; pedges ; pedges = pedges->pnext)
{
r_leftclipped = r_rightclipped = false;
R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
R_ClipEdge (pedges->v[0], pedges->v[1], pclip, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
if (r_leftclipped)
makeleftedge = true;
@ -808,16 +818,16 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
// FIXME: share clipped edges?
if (makeleftedge)
{
r_pedge = &tedge;
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if there was a clip off the right edge, get the right r_nearzi
if (makerightedge)
{
r_pedge = &tedge;
r_nearzionly = true;
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if no edges made it out, return without posting the surface

View file

@ -184,7 +184,7 @@ TurbulentPow2
=============
*/
void
TurbulentPow2 (espan_t *pspan)
TurbulentPow2 (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv)
{
float spancountminus1;
float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu;
@ -338,7 +338,7 @@ NonTurbulentPow2 - this is for drawing scrolling textures. they're warping water
=============
*/
void
NonTurbulentPow2 (espan_t *pspan)
NonTurbulentPow2 (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv)
{
float spancountminus1;
float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu;
@ -590,7 +590,7 @@ D_DrawSpansPow2
=============
*/
void
D_DrawSpansPow2 (espan_t *pspan)
D_DrawSpansPow2 (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv)
{
int spancount;
pixel_t *pbase;
@ -742,7 +742,7 @@ D_DrawZSpans
=============
*/
void
D_DrawZSpans (espan_t *pspan)
D_DrawZSpans (espan_t *pspan, float d_ziorigin, float d_zistepu, float d_zistepv)
{
zvalue_t izistep;
int safe_step;

View file

@ -31,7 +31,6 @@ static unsigned char *r_source, *r_sourcemax;
static unsigned *r_lightptr;
void R_BuildLightMap (drawsurf_t *drawsurf);
extern unsigned blocklights[1024]; // allow some very large lightmaps
static int sc_size;
static surfcache_t *sc_rover;
@ -179,6 +178,12 @@ R_DrawSurface (drawsurf_t *drawsurf)
{
r_lightptr = blocklights + u;
if (r_lightptr >= blocklight_max)
{
r_outoflights = true;
continue;
}
prowdestbase = pcolumndest;
pbasesource = basetptr + soffset;