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