Cube  Diff

Differences From Artifact [f6cb50b391]:

To Artifact [6775552eda]:


1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16
17
18









-
-
+
+







// worldrender.cpp: goes through all cubes in top down quad tree fashion,
// determines what has to be rendered and how (depending on neighbouring cubes),
// then calls functions in rendercubes.cpp

#include "cube.h"

#import "DynamicEntity.h"

void
render_wall(sqr *o, sqr *s, int x1, int y1, int x2, int y2, int mip, sqr *d1,
    sqr *d2, bool topleft)
render_wall(struct sqr *o, struct sqr *s, int x1, int y1, int x2, int y2,
    int mip, struct sqr *d1, struct sqr *d2, bool topleft)
{
	if (SOLID(o) || o->type == SEMISOLID) {
		float c1 = s->floor;
		float c2 = s->floor;
		if (s->type == FHF) {
			c1 -= d1->vdelta / 4.0f;
			c2 -= d2->vdelta / 4.0f;
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







// mip cubes (used for wall rendering below)

bool
issemi(int mip, int x, int y, int x1, int y1, int x2, int y2)
{
	if (!(mip--))
		return true;
	sqr *w = wmip[mip];
	struct sqr *w = wmip[mip];
	int msize = ssize >> mip;
	x *= 2;
	y *= 2;
	switch (SWS(w, x + x1, y + y1, msize)->type) {
	case SEMISOLID:
		if (issemi(mip, x + x1, y + y1, x1, y1, x2, y2))
			return true;
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131







-
+







// machines however this function will use the higher mip levels only for
// perfect mips.

void
render_seg_new(
    float vx, float vy, float vh, int mip, int x, int y, int xs, int ys)
{
	sqr *w = wmip[mip];
	struct sqr *w = wmip[mip];
	int sz = ssize >> mip;
	int vxx = ((int)vx + (1 << mip) / 2) >> mip;
	int vyy = ((int)vy + (1 << mip) / 2) >> mip;
	int lx =
	    vxx - lodleft; // these mark the rect inside the current rest that
	                   // we want to render using a lower mip level
	int ly = vyy - lodtop;
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176




177
178
179
180
181

182
183
184
185
186
187
188
160
161
162
163
164
165
166

167
168
169
170
171
172




173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188







-
+





-
-
-
-
+
+
+
+




-
+







	// and are also deferred, and render them recursively. Anything left
	// (perfect mips and higher lods) we render here.

#define LOOPH                                                          \
	{                                                              \
		for (int xx = x; xx < xs; xx++)                        \
			for (int yy = y; yy < ys; yy++) {              \
				sqr *s = SWS(w, xx, yy, sz);           \
				struct sqr *s = SWS(w, xx, yy, sz);    \
				if (s->occluded == 1)                  \
					continue;                      \
				if (s->defer && !s->occluded && mip && \
				    xx >= lx && xx < rx && yy >= ly && \
				    yy < ry)
#define LOOPD                      \
	sqr *t = SWS(s, 1, 0, sz); \
	sqr *u = SWS(s, 1, 1, sz); \
	sqr *v = SWS(s, 0, 1, sz);
#define LOOPD                             \
	struct sqr *t = SWS(s, 1, 0, sz); \
	struct sqr *u = SWS(s, 1, 1, sz); \
	struct sqr *v = SWS(s, 0, 1, sz);

	LOOPH // ceils
	{
		int start = yy;
		sqr *next;
		struct sqr *next;
		while (yy < ys - 1 && (next = SWS(w, xx, yy + 1, sz))->defer &&
		    !next->occluded)
			yy++; // collect 2xN rect of lower mip
		render_seg_new(vx, vy, vh, mip - 1, xx * 2, start * 2,
		    xx * 2 + 2, yy * 2 + 2);
		continue;
	}
217
218
219
220
221
222
223
224
225


226
227
228
229
230
231
232


233
234
235
236
237
238
239
217
218
219
220
221
222
223


224
225
226
227
228
229
230


231
232
233
234
235
236
237
238
239







-
-
+
+





-
-
+
+








LOOPH continue; // walls
LOOPD
//  w
// zSt
//  vu

sqr *w = SWS(s, 0, -1, sz);
sqr *z = SWS(s, -1, 0, sz);
struct sqr *w = SWS(s, 0, -1, sz);
struct sqr *z = SWS(s, -1, 0, sz);
bool normalwall = true;

if (s->type == CORNER) {
	// cull also
	bool topleft = true;
	sqr *h1 = NULL;
	sqr *h2 = NULL;
	struct sqr *h1 = NULL;
	struct sqr *h2 = NULL;
	if (SOLID(z)) {
		if (SOLID(w)) {
			render_wall(w, h2 = s, xx + 1, yy, xx, yy + 1, mip, t,
			    v, false);
			topleft = false;
		} else if (SOLID(v)) {
			render_wall(v, h2 = s, xx, yy, xx + 1, yy + 1, mip, s,
295
296
297
298
299
300
301
302
303


304
305
306
307
308
309
310
311






312
313
314
315
316
317
318
295
296
297
298
299
300
301


302
303
304
305






306
307
308
309
310
311
312
313
314
315
316
317
318







-
-
+
+


-
-
-
-
-
-
+
+
+
+
+
+







	    (v->type != SEMISOLID || issemi(mip, xx, yy + 1, 0, 0, 1, 0)))
		render_wall(s, v, xx, yy + 1, xx + 1, yy + 1, mip, v, u, true);
}
}
}
}

void
distlod(int &low, int &high, int angle, float widef)
static void
distlod(int *low, int *high, int angle, float widef)
{
	float f = 90.0f / lod / widef;
	low = (int)((90 - angle) / f);
	high = (int)(angle / f);
	if (low < min_lod)
		low = min_lod;
	if (high < min_lod)
		high = min_lod;
	*low = (int)((90 - angle) / f);
	*high = (int)(angle / f);
	if (*low < min_lod)
		*low = min_lod;
	if (*high < min_lod)
		*high = min_lod;
}

// does some out of date view frustrum optimisation that doesn't contribute much
// anymore

void
render_world(
330
331
332
333
334
335
336
337

338
339
340

341
342
343

344
345
346
347


348
349
350
351
352
353
354
355
356
330
331
332
333
334
335
336

337
338
339

340
341
342

343
344
345


346
347
348
349
350
351
352
353
354
355
356







-
+


-
+


-
+


-
-
+
+









		    max(min_lod, (int)(MIN_LOD + (10 - cdist) / 1.0f * widef));
		widef = 1.0f;
	}
	lod = MAX_LOD;
	lodtop = lodbot = lodleft = lodright = min_lod;
	if (yaw > 45 && yaw <= 135) {
		lodleft = lod;
		distlod(lodtop, lodbot, yaw - 45, widef);
		distlod(&lodtop, &lodbot, yaw - 45, widef);
	} else if (yaw > 135 && yaw <= 225) {
		lodbot = lod;
		distlod(lodleft, lodright, yaw - 135, widef);
		distlod(&lodleft, &lodright, yaw - 135, widef);
	} else if (yaw > 225 && yaw <= 315) {
		lodright = lod;
		distlod(lodbot, lodtop, yaw - 225, widef);
		distlod(&lodbot, &lodtop, yaw - 225, widef);
	} else {
		lodtop = lod;
		distlod(
		    lodright, lodleft, yaw <= 45 ? yaw + 45 : yaw - 315, widef);
		distlod(&lodright, &lodleft, yaw <= 45 ? yaw + 45 : yaw - 315,
		    widef);
	}
	float hyfov = fov * h / w / 2;
	render_floor = pitch < hyfov;
	render_ceil = -pitch < hyfov;

	render_seg_new(
	    vx, vy, vh, MAX_MIP, 0, 0, ssize >> MAX_MIP, ssize >> MAX_MIP);
	mipstats(stats[0], stats[1], stats[2]);
}