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
// 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)
{
	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;









|
|







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(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
// 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];
	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;







|







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;
	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
// 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];
	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;







|







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)
{
	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
	// 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);           \
				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);

	LOOPH // ceils
	{
		int start = yy;
		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;
	}







|





|
|
|
|




|







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++) {              \
				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                             \
	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;
		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

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

sqr *w = SWS(s, 0, -1, sz);
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;
	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,







|
|





|
|







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

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;
	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
	    (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)
{
	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;
}

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

void
render_world(







|
|


|
|
|
|
|
|







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);
}
}
}
}

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;
}

// 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
		    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);
	} else if (yaw > 135 && yaw <= 225) {
		lodbot = lod;
		distlod(lodleft, lodright, yaw - 135, widef);
	} else if (yaw > 225 && yaw <= 315) {
		lodright = lod;
		distlod(lodbot, lodtop, yaw - 225, widef);
	} else {
		lodtop = lod;
		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]);
}







|


|


|


<
|
>









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);
	} else if (yaw > 135 && yaw <= 225) {
		lodbot = lod;
		distlod(&lodleft, &lodright, yaw - 135, widef);
	} else if (yaw > 225 && yaw <= 315) {
		lodright = lod;
		distlod(&lodbot, &lodtop, yaw - 225, widef);
	} else {
		lodtop = lod;

		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]);
}