[sw] Clean up r_refdef and R_ViewChanged

r_refdef is really meant for holding the various screen "constants" for
the software renderer rather than the more generic scene stuff. All the
fields referenced by the low level rendering code (especially assembly)
have been moved to the beginning of the struct (and nicely fit within 64
bytes). The other fields should be moved elsewhere, but not this commit.

On top of that, R_ViewChanged is much easier to read, and there are
fewer static globals.
This commit is contained in:
Bill Currie 2022-03-27 15:27:35 +09:00
parent aafd5c3d81
commit 3103f400fd
8 changed files with 94 additions and 117 deletions

View file

@ -203,25 +203,21 @@ typedef struct framebuffer_s {
// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct {
vrect_t vrect; // subwindow in video for refresh
// FIXME: not need vrect next field here?
vrect_t aliasvrect; // scaled Alias version
int vrectright, vrectbottom; // right & bottom screen coords
int aliasvrectright, aliasvrectbottom; // scaled Alias versions
float vrectrightedge; // rightmost right edge we care about,
// for use in edge list
float fvrectx, fvrecty; // for floating-point compares
float fvrectx_adj, fvrecty_adj; // left and top edges, for clamping
int vrect_x_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20
int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
float fvrectright_adj, fvrectbottom_adj;
int aliasvrectleft, aliasvrecttop; // scaled Alias versions
int aliasvrectright, aliasvrectbottom; // scaled Alias versions
int vrectright, vrectbottom; // right & bottom screen coords
int vrectx_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20
int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
float fvrectx, fvrecty; // for floating-point compares
// right and bottom edges, for clamping
float fvrectright; // rightmost edge, for Alias clamping
float fvrectbottom; // bottommost edge, for Alias clamping
float horizontalFieldOfView; // at Z = 1.0, this many X is visible
// 2.0 = 90 degrees
float xOrigin; // should probably always be 0.5
float yOrigin; // between be around 0.3 to 0.5
// end of asm refs
//FIXME move all of below elsewhere
vrect_t vrect; // subwindow in video for refresh
refframe_t frame;
plane_t frustum[4];

View file

@ -118,32 +118,23 @@
// refdef_t structure
// !!! if this is changed, it must be changed in render.h too !!!
#define rd_vrect 0
#define rd_aliasvrect 20
#define rd_vrectright 40
#define rd_vrectbottom 44
#define rd_aliasvrectright 48
#define rd_aliasvrectbottom 52
#define rd_vrectrightedge 56
#define rd_fvrectx 60
#define rd_fvrecty 64
#define rd_fvrectx_adj 68
#define rd_fvrecty_adj 72
#define rd_vrect_x_adj_shift20 76
#define rd_vrectright_adj_shift20 80
#define rd_fvrectright_adj 84
#define rd_fvrectbottom_adj 88
#define rd_fvrectright 92
#define rd_fvrectbottom 96
#define rd_horizontalFieldOfView 100
#define rd_xOrigin 104
#define rd_yOrigin 108
#define rd_viewposition 112
#define rd_viewrotation 128
#define rd_ambientlight 144
#defin rd_fov_x 148
#defin rd_fov_y 152
#define rd_size 156 // sizeof (refdef_t)
#define rd_fvrectx_adj 0
#define rd_fvrecty_adj 4
#define rd_fvrectright_adj 8
#define rd_fvrectbottom_adj 12
#define rd_aliasvrectleft 16
#define rd_aliasvrecttop 20
#define rd_aliasvrectright 24
#define rd_aliasvrectbottom 28
#define rd_vrectright 32
#define rd_vrectbottom 36
#define rd_vrectx_adj_shift20 40
#define rd_vrectright_adj_shift20 44
#define rd_fvrectx 48
#define rd_fvrecty 52
#define rd_fvrectright 56
#define rd_fvrectbottom 60
#define rd_size 64 // sizeof (refdef_t) FIXME make true
// mtriangle_t structure
// !!! if this is changed, it must be changed in model.h too !!!

View file

@ -80,9 +80,9 @@ R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
R_AliasProjectFinalVert (out, &avout);
if (out->v[0] < r_refdef.aliasvrect.x)
if (out->v[0] < r_refdef.aliasvrectleft)
out->flags |= ALIAS_LEFT_CLIP;
if (out->v[1] < r_refdef.aliasvrect.y)
if (out->v[1] < r_refdef.aliasvrecttop)
out->flags |= ALIAS_TOP_CLIP;
if (out->v[0] > r_refdef.aliasvrectright)
out->flags |= ALIAS_RIGHT_CLIP;
@ -99,12 +99,12 @@ R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
int i;
if (pfv0->v[1] >= pfv1->v[1]) {
scale = (float) (r_refdef.aliasvrect.x - pfv0->v[0]) /
scale = (float) (r_refdef.aliasvrectleft - pfv0->v[0]) /
(pfv1->v[0] - pfv0->v[0]);
for (i = 0; i < 6; i++)
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
} else {
scale = (float) (r_refdef.aliasvrect.x - pfv1->v[0]) /
scale = (float) (r_refdef.aliasvrectleft - pfv1->v[0]) /
(pfv0->v[0] - pfv1->v[0]);
for (i = 0; i < 6; i++)
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
@ -139,12 +139,12 @@ R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
int i;
if (pfv0->v[1] >= pfv1->v[1]) {
scale = (float) (r_refdef.aliasvrect.y - pfv0->v[1]) /
scale = (float) (r_refdef.aliasvrecttop - pfv0->v[1]) /
(pfv1->v[1] - pfv0->v[1]);
for (i = 0; i < 6; i++)
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
} else {
scale = (float) (r_refdef.aliasvrect.y - pfv1->v[1]) /
scale = (float) (r_refdef.aliasvrecttop - pfv1->v[1]) /
(pfv0->v[1] - pfv1->v[1]);
for (i = 0; i < 6; i++)
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
@ -195,9 +195,9 @@ R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
if (oldflags ^ flags) {
clip (&in[j], &in[i], &out[k]);
out[k].flags = 0;
if (out[k].v[0] < r_refdef.aliasvrect.x)
if (out[k].v[0] < r_refdef.aliasvrectleft)
out[k].flags |= ALIAS_LEFT_CLIP;
if (out[k].v[1] < r_refdef.aliasvrect.y)
if (out[k].v[1] < r_refdef.aliasvrecttop)
out[k].flags |= ALIAS_TOP_CLIP;
if (out[k].v[0] > r_refdef.aliasvrectright)
out[k].flags |= ALIAS_RIGHT_CLIP;
@ -291,13 +291,13 @@ R_AliasClipTriangle (mtriangle_t *ptri)
}
for (i = 0; i < k; i++) {
if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
if (fv[pingpong][i].v[0] < r_refdef.aliasvrectleft)
fv[pingpong][i].v[0] = r_refdef.aliasvrectleft;
else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
if (fv[pingpong][i].v[1] < r_refdef.aliasvrecttop)
fv[pingpong][i].v[1] = r_refdef.aliasvrecttop;
else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;

View file

@ -219,7 +219,7 @@ C(R_Alias_clip_top):
leal C(r_refdef),%eax
movl C(float_point5),%edx
#endif
movl rd_aliasvrect+4(%eax),%eax
movl rd_aliasvrecttop(%eax),%eax
movl %edx,point5(%esp)
jmp LDoForwardOrBackward
#ifdef PIC
@ -310,7 +310,7 @@ C(R_Alias_clip_left):
leal C(r_refdef),%eax
movl C(float_point5),%edx
#endif
movl rd_aliasvrect+0(%eax),%eax
movl rd_aliasvrectleft(%eax),%eax
movl %edx,point5(%esp)
jmp LRightLeftEntry
#ifdef PIC

View file

@ -254,9 +254,9 @@ R_AliasClipAndProjectFinalVert (finalvert_t *fv, auxvert_t *av)
R_AliasProjectFinalVert (fv, av);
if (fv->v[0] < r_refdef.aliasvrect.x)
if (fv->v[0] < r_refdef.aliasvrectleft)
fv->flags |= ALIAS_LEFT_CLIP;
if (fv->v[1] < r_refdef.aliasvrect.y)
if (fv->v[1] < r_refdef.aliasvrecttop)
fv->flags |= ALIAS_TOP_CLIP;
if (fv->v[0] > r_refdef.aliasvrectright)
fv->flags |= ALIAS_RIGHT_CLIP;

View file

@ -214,8 +214,8 @@ R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
// causes it to incorrectly extend to the scan, and the extension of the
// line goes off the edge of the screen
// FIXME: is this actually needed?
if (edge->u < r_refdef.vrect_x_adj_shift20)
edge->u = r_refdef.vrect_x_adj_shift20;
if (edge->u < r_refdef.vrectx_adj_shift20)
edge->u = r_refdef.vrectx_adj_shift20;
if (edge->u > r_refdef.vrectright_adj_shift20)
edge->u = r_refdef.vrectright_adj_shift20;

View file

@ -412,12 +412,12 @@ LSideDone:
// // causes it to incorrectly extend to the scan, and the extension of the
// // line goes off the edge of the screen
// // FIXME: is this actually needed?
// if (edge->u < r_refdef.vrect_x_adj_shift20)
// edge->u = r_refdef.vrect_x_adj_shift20;
// if (edge->u < r_refdef.vrectx_adj_shift20)
// edge->u = r_refdef.vrectx_adj_shift20;
// if (edge->u > r_refdef.vrectright_adj_shift20)
// edge->u = r_refdef.vrectright_adj_shift20;
movl et_u(%edi),%eax
movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx
movl C(r_refdef)+rd_vrectx_adj_shift20,%edx
cmpl %edx,%eax
jl LP4
movl C(r_refdef)+rd_vrectright_adj_shift20,%edx

View file

@ -91,9 +91,6 @@ float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
int screenwidth;
float pixelAspect;
static float screenAspect;
static float verticalFieldOfView;
static float xOrigin, yOrigin;
plane_t screenedge[4];
@ -145,9 +142,6 @@ sw_R_Init (void)
view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
view_clipplanes[3].rightedge = false;
r_refdef.xOrigin = XCENTERING;
r_refdef.yOrigin = YCENTERING;
// TODO: collect 386-specific code in one place
#ifdef USE_INTEL_ASM
Sys_MakeCodeWriteable ((long) R_EdgeCodeStart,
@ -231,42 +225,30 @@ R_ViewChanged (void)
r_viewchanged = true;
r_refdef.horizontalFieldOfView = 2.0 * tan (r_refdef.fov_x / 360 * M_PI);
r_refdef.fvrectx = (float) r_refdef.vrect.x;
r_refdef.fvrectx_adj = (float) r_refdef.vrect.x - 0.5;
r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x << 20) + (1 << 19) - 1;
r_refdef.fvrecty = (float) r_refdef.vrect.y;
r_refdef.fvrecty_adj = (float) r_refdef.vrect.y - 0.5;
r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
r_refdef.vrectright_adj_shift20 =
(r_refdef.vrectright << 20) + (1 << 19) - 1;
r_refdef.fvrectright = (float) r_refdef.vrectright;
r_refdef.fvrectright_adj = (float) r_refdef.vrectright - 0.5;
r_refdef.vrectrightedge = (float) r_refdef.vrectright - 0.99;
r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
#define SHIFT20(x) (((x) << 20) + (1 << 19) - 1)
r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
r_refdef.vrectx_adj_shift20 = SHIFT20 (r_refdef.vrect.x);
r_refdef.vrectright_adj_shift20 = SHIFT20 (r_refdef.vrectright);
r_refdef.fvrectx = (float) r_refdef.vrect.x;
r_refdef.fvrecty = (float) r_refdef.vrect.y;
r_refdef.fvrectright = (float) r_refdef.vrectright;
r_refdef.fvrectbottom = (float) r_refdef.vrectbottom;
r_refdef.fvrectx_adj = (float) r_refdef.vrect.x - 0.5;
r_refdef.fvrecty_adj = (float) r_refdef.vrect.y - 0.5;
r_refdef.fvrectright_adj = (float) r_refdef.vrectright - 0.5;
r_refdef.fvrectbottom_adj = (float) r_refdef.vrectbottom - 0.5;
r_refdef.aliasvrect.x = (int) (r_refdef.vrect.x * r_aliasuvscale);
r_refdef.aliasvrect.y = (int) (r_refdef.vrect.y * r_aliasuvscale);
r_refdef.aliasvrect.width = (int) (r_refdef.vrect.width * r_aliasuvscale);
r_refdef.aliasvrect.height = (int) (r_refdef.vrect.height *
r_aliasuvscale);
r_refdef.aliasvrectright = r_refdef.aliasvrect.x +
r_refdef.aliasvrect.width;
r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y +
r_refdef.aliasvrect.height;
pixelAspect = 1;//FIXME vid.aspect;
xOrigin = r_refdef.xOrigin;
yOrigin = r_refdef.yOrigin;
screenAspect = r_refdef.vrect.width * pixelAspect / r_refdef.vrect.height;
// 320*200 1.0 pixelAspect = 1.6 screenAspect
// 320*240 1.0 pixelAspect = 1.3333 screenAspect
// proper 320*200 pixelAspect = 0.8333333
verticalFieldOfView = r_refdef.horizontalFieldOfView / screenAspect;
int aleft = r_refdef.vrect.x * r_aliasuvscale;
int atop = r_refdef.vrect.y * r_aliasuvscale;
int awidth = r_refdef.vrect.width * r_aliasuvscale;
int aheight = r_refdef.vrect.height * r_aliasuvscale;
r_refdef.aliasvrectleft = aleft;
r_refdef.aliasvrecttop = atop;
r_refdef.aliasvrectright = aleft + awidth;
r_refdef.aliasvrectbottom = atop + aheight;
// values for perspective projection
// if math were exact, the values would range from 0.5 to to range+0.5
@ -274,45 +256,54 @@ R_ViewChanged (void)
// the polygon rasterization will never render in the first row or column
// but will definately render in the [range] row and column, so adjust the
// buffer origin to get an exact edge to edge fill
xcenter = ((float) r_refdef.vrect.width * XCENTERING) +
r_refdef.vrect.x - 0.5;
xcenter = r_refdef.vrect.width * XCENTERING + r_refdef.vrect.x - 0.5;
ycenter = r_refdef.vrect.height * YCENTERING + r_refdef.vrect.y - 0.5;
aliasxcenter = xcenter * r_aliasuvscale;
ycenter = ((float) r_refdef.vrect.height * YCENTERING) +
r_refdef.vrect.y - 0.5;
aliasycenter = ycenter * r_aliasuvscale;
xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
aliasxscale = xscale * r_aliasuvscale;
xscaleinv = 1.0 / xscale;
pixelAspect = 1;//FIXME vid.aspect;
float aspect = r_refdef.vrect.width * pixelAspect / r_refdef.vrect.height;
// 320*200 1.0 pixelAspect = 1.6 aspect
// 320*240 1.0 pixelAspect = 1.3333 aspect
// proper 320*200 pixelAspect = 0.8333333
float hFOV = 2.0 * tan (r_refdef.fov_x / 360 * M_PI);
float vFOV = hFOV / aspect;
// general perspective scaling
xscale = r_refdef.vrect.width / hFOV;
yscale = xscale * pixelAspect;
aliasyscale = yscale * r_aliasuvscale;
xscaleinv = 1.0 / xscale;
yscaleinv = 1.0 / yscale;
xscaleshrink = (r_refdef.vrect.width - 6) / r_refdef.horizontalFieldOfView;
// perspective scaling for alias models
aliasxscale = xscale * r_aliasuvscale;
aliasyscale = yscale * r_aliasuvscale;
// perspective scaling for paricle position
xscaleshrink = (r_refdef.vrect.width - 6) / hFOV;
yscaleshrink = xscaleshrink * pixelAspect;
// left side clip
screenedge[0].normal[0] = -1.0 / (xOrigin *
r_refdef.horizontalFieldOfView);
screenedge[0].normal[0] = -1.0 / (XCENTERING * hFOV);
screenedge[0].normal[1] = 0;
screenedge[0].normal[2] = 1;
screenedge[0].type = PLANE_ANYZ;
// right side clip
screenedge[1].normal[0] = 1.0 / ((1.0 - xOrigin) *
r_refdef.horizontalFieldOfView);
screenedge[1].normal[0] = 1.0 / ((1.0 - XCENTERING) * hFOV);
screenedge[1].normal[1] = 0;
screenedge[1].normal[2] = 1;
screenedge[1].type = PLANE_ANYZ;
// top side clip
screenedge[2].normal[0] = 0;
screenedge[2].normal[1] = -1.0 / (yOrigin * verticalFieldOfView);
screenedge[2].normal[1] = -1.0 / (YCENTERING * vFOV);
screenedge[2].normal[2] = 1;
screenedge[2].type = PLANE_ANYZ;
// bottom side clip
screenedge[3].normal[0] = 0;
screenedge[3].normal[1] = 1.0 / ((1.0 - yOrigin) * verticalFieldOfView);
screenedge[3].normal[1] = 1.0 / ((1.0 - YCENTERING) * vFOV);
screenedge[3].normal[2] = 1;
screenedge[3].type = PLANE_ANYZ;
@ -320,8 +311,7 @@ R_ViewChanged (void)
VectorNormalize (screenedge[i].normal);
res_scale = sqrt ((double) (r_refdef.vrect.width * r_refdef.vrect.height) /
(320.0 * 152.0)) * (2.0 /
r_refdef.horizontalFieldOfView);
(320.0 * 152.0)) * (2.0 / hFOV);
r_aliastransition = r_aliastransbase->value * res_scale;
r_resfudge = r_aliastransadj->value * res_scale;