cube assembler replaced with a raycasting one - buggy, but faster!
This commit is contained in:
parent
7c25459609
commit
cbbdfa1f0a
@ -136,11 +136,15 @@ function new_player(settings)
|
||||
function this.spawn()
|
||||
local xlen,ylen,zlen
|
||||
xlen,ylen,zlen = common.map_get_dims()
|
||||
|
||||
while true do
|
||||
this.x = math.floor(math.random()*xlen/4.0)+0.5
|
||||
this.z = math.floor(math.random()*zlen)+0.5
|
||||
this.y = (common.map_pillar_get(this.x, this.z))[1+1]-3.0
|
||||
|
||||
if this.team == 1 then this.x = xlen - this.x end
|
||||
this.y = (common.map_pillar_get(this.x, this.z))[1+1]
|
||||
if this.y < 63 then break end
|
||||
end
|
||||
this.y = this.y - 3.0
|
||||
|
||||
this.alive = true
|
||||
this.spawned = true
|
||||
|
696
render.c
696
render.c
@ -17,10 +17,12 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// TODO: bump up to 127.5f
|
||||
#define FOG_DISTANCE 40.0f
|
||||
//define DEBUG_INVERT_DRAW_DIR
|
||||
|
||||
#define FTB_MAX_PERSPAN 50
|
||||
// TODO: bump up to 127.5f
|
||||
#define FOG_DISTANCE 60.0f
|
||||
|
||||
#define RAYC_MAX ((int)((FOG_DISTANCE+1)*(FOG_DISTANCE+1)*8+10))
|
||||
|
||||
#define DF_NX 0x01
|
||||
#define DF_NY 0x02
|
||||
@ -51,15 +53,57 @@ int rtmp_width, rtmp_height, rtmp_pitch;
|
||||
camera_t *rtmp_camera;
|
||||
map_t *rtmp_map;
|
||||
|
||||
int *ftb_first;
|
||||
typedef struct raydata {
|
||||
int16_t x,y,z;
|
||||
int8_t gx,gz;
|
||||
|
||||
float y1,y2;
|
||||
float sx,sy,sz;
|
||||
} raydata_t;
|
||||
|
||||
typedef struct rayblock {
|
||||
uint32_t color;
|
||||
float x,y,z;
|
||||
} rayblock_t;
|
||||
|
||||
int rayc_block_len, rayc_block_head;
|
||||
int rayc_data_len, rayc_data_head;
|
||||
raydata_t rayc_data[RAYC_MAX];
|
||||
rayblock_t *rayc_block = NULL;
|
||||
int *rayc_mark = NULL;
|
||||
int rayc_block_size = 0;
|
||||
int rayc_mark_size = 0;
|
||||
|
||||
float *dbuf;
|
||||
|
||||
|
||||
/*
|
||||
* REFERENCE IMPLEMENTATION
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t render_fog_apply_new(uint32_t color, float depth)
|
||||
{
|
||||
int b = color&255;
|
||||
int g = (color>>8)&255;
|
||||
int r = (color>>16)&255;
|
||||
int t = (color>>24)&255;
|
||||
|
||||
//float fog = (FOG_DISTANCE*FOG_DISTANCE/depth)/256.0f;
|
||||
float fog = (FOG_DISTANCE*FOG_DISTANCE-(depth < 0.001f ? 0.001f : depth))
|
||||
/(FOG_DISTANCE*FOG_DISTANCE);
|
||||
if(fog > 1.0f)
|
||||
fog = 1.0f;
|
||||
if(fog < 0.0f)
|
||||
fog = 0.0f;
|
||||
|
||||
r = (r*fog+0.5f);
|
||||
g = (g*fog+0.5f);
|
||||
b = (b*fog+0.5f);
|
||||
|
||||
return b|(g<<8)|(r<<16)|(t<<24);
|
||||
}
|
||||
|
||||
uint32_t render_fog_apply(uint32_t color, float depth)
|
||||
{
|
||||
int b = color&255;
|
||||
@ -198,7 +242,8 @@ void render_vxl_rect_ftb_fast(uint32_t *ccolor, float *cdepth, int x1, int y1, i
|
||||
// NOTE: this approach seems to be faster than render_vxl_rect_btf.
|
||||
|
||||
// clip
|
||||
render_rect_clip(&color, &x1, &y1, &x2, &y2, depth);
|
||||
uint32_t dummy;
|
||||
render_rect_clip(&dummy, &x1, &y1, &x2, &y2, depth);
|
||||
|
||||
if(x2 <= 0)
|
||||
return;
|
||||
@ -271,13 +316,11 @@ void render_vxl_cube(uint32_t *ccolor, float *cdepth, int x1, int y1, int x2, in
|
||||
render_vxl_cube_sides(ccolor, cdepth, x1, y1, x2, y2, color, depth);
|
||||
}
|
||||
|
||||
void render_vxl_face_vert(int blkx, int blky, int blkz,
|
||||
void render_vxl_face_raycast(int blkx, int blky, int blkz,
|
||||
float subx, float suby, float subz,
|
||||
int face,
|
||||
int gx, int gy, int gz)
|
||||
{
|
||||
// TODO: this function sucks, speed it up a bit
|
||||
int sx,sy;
|
||||
int i;
|
||||
|
||||
float tracemul = cubemap_size/2;
|
||||
@ -294,13 +337,6 @@ void render_vxl_face_vert(int blkx, int blky, int blkz,
|
||||
cdepth[i] = FOG_DISTANCE;
|
||||
}
|
||||
|
||||
// clear FTB buffers
|
||||
for(i = 0; i < cubemap_size; i++)
|
||||
{
|
||||
ftb_first[i] = 0;
|
||||
//ccolor[i<<cubemap_shift] = cubemap_size|(cubemap_size<<16);
|
||||
}
|
||||
|
||||
// get X cube direction
|
||||
int xgx = gz+gy;
|
||||
int xgy = 0;
|
||||
@ -308,402 +344,301 @@ void render_vxl_face_vert(int blkx, int blky, int blkz,
|
||||
|
||||
// get Y cube direction
|
||||
int ygx = 0;
|
||||
int ygy = gx+gz;
|
||||
int ygy = fabsf(gx+gz);
|
||||
int ygz = gy;
|
||||
|
||||
// get cubemap offset
|
||||
float cmoffsx = -(xgx*subx+xgy*suby+xgz*subz);
|
||||
float cmoffsy = -(ygx*subx+ygy*suby+ygz*subz);
|
||||
// get base pos
|
||||
float bx = blkx+subx;
|
||||
float by = blky+suby;
|
||||
float bz = blkz+subz;
|
||||
|
||||
// get distance to wall
|
||||
float dist = -(subx*gx+suby*gy+subz*gz);
|
||||
if(dist < 0.0f)
|
||||
dist = 1.0f+dist;
|
||||
else {
|
||||
//blky--;
|
||||
|
||||
blkx--;
|
||||
blkz--;
|
||||
}
|
||||
dist -= 1.0f;
|
||||
|
||||
//int coz = blky;
|
||||
|
||||
// now build pillars
|
||||
static uint32_t cdata[256]; // hypothetical maximum
|
||||
|
||||
// render cubes from centre out
|
||||
float odist = dist;
|
||||
|
||||
int lbx1 = 2;
|
||||
int lby1 = 2;
|
||||
int lbx2 = -2;
|
||||
int lby2 = -2;
|
||||
|
||||
// prep boundaries
|
||||
int bx1 = 0;
|
||||
int by1 = 0;
|
||||
int bx2 = 0;
|
||||
int by2 = 0;
|
||||
|
||||
if(gy < 0)
|
||||
if(xgx+xgy+xgz < 0)
|
||||
{
|
||||
bx1++;
|
||||
by1++;
|
||||
bx2++;
|
||||
by2++;
|
||||
bx += xgx;
|
||||
by += xgy;
|
||||
bz += xgz;
|
||||
}
|
||||
|
||||
int xlen = rtmp_map->xlen;
|
||||
int ylen = rtmp_map->ylen;
|
||||
int zlen = rtmp_map->zlen;
|
||||
int xlenm1 = xlen-1;
|
||||
int ylenm1 = ylen-1;
|
||||
int zlenm1 = zlen-1;
|
||||
|
||||
while(dist < FOG_DISTANCE)
|
||||
// now crawl through the block list
|
||||
#ifdef DEBUG_INVERT_DRAW_DIR
|
||||
rayblock_t *b = &rayc_block[rayc_block_len-1];
|
||||
rayblock_t *b_end = &rayc_block[0];
|
||||
for(; b >= b_end; b--)
|
||||
#else
|
||||
rayblock_t *b = &rayc_block[0];
|
||||
rayblock_t *b_end = &rayc_block[rayc_block_len];
|
||||
for(; b < b_end; b++)
|
||||
#endif
|
||||
{
|
||||
// go through each
|
||||
int cox,coy;
|
||||
cox = bx1; coy = by1;
|
||||
int pdx = 1, pdy = 0;
|
||||
// get block delta
|
||||
float dx = b->x - bx;
|
||||
float dy = b->y - by;
|
||||
float dz = b->z - bz;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// skip already-rendered stuff
|
||||
//if(cox >= lbx1 && coy >= lby1 && cox <= lbx2 && coy <= lby2)
|
||||
// continue;
|
||||
// get correct screen positions
|
||||
float sx = dx*xgx+dy*xgy+dz*xgz;
|
||||
float sy = dx*ygx+dy*ygy+dz*ygz;
|
||||
float sz = dx* gx+dy* gy+dz* gz;
|
||||
|
||||
// get pillar
|
||||
uint8_t *pillar = rtmp_map->pillars[
|
||||
((cox+blkx)&(xlenm1))
|
||||
+(((coy+blkz)&(zlenm1))*xlen)]+4;
|
||||
// check distance
|
||||
if(sz < 0.001f || sz >= FOG_DISTANCE)
|
||||
continue;
|
||||
|
||||
// load data
|
||||
// frustum cull
|
||||
if(fabsf(sx) > fabsf(sz+2.0f) || fabsf(sy) > fabsf(sz+2.0f))
|
||||
continue;
|
||||
|
||||
i = 0;
|
||||
for(;;)
|
||||
{
|
||||
uint8_t *csrc = &pillar[4];
|
||||
|
||||
int nrem = pillar[0]-1;
|
||||
|
||||
for(; i < pillar[1]; i++)
|
||||
cdata[i] = 0;
|
||||
|
||||
for(; i <= pillar[2]; i++, nrem--, csrc += 4)
|
||||
cdata[i] = *(uint32_t *)csrc;
|
||||
|
||||
if(pillar[0] == 0)
|
||||
break;
|
||||
|
||||
pillar += 4*(int)pillar[0];
|
||||
|
||||
for(; i < pillar[3]-nrem; i++)
|
||||
cdata[i] = 1;
|
||||
|
||||
for(; i < pillar[3]; i++, csrc += 4)
|
||||
cdata[i] = *(uint32_t *)csrc;
|
||||
}
|
||||
|
||||
for(; i < ylen; i++)
|
||||
cdata[i] = 1;
|
||||
|
||||
// render data
|
||||
if(gy >= 0)
|
||||
{
|
||||
// bottom cubemap
|
||||
float fdist = 0.0f-blky-suby;
|
||||
// TODO: work out min required distance by frustum
|
||||
|
||||
i = 0;
|
||||
|
||||
fdist += i;
|
||||
for(; i < ylen; i++)
|
||||
{
|
||||
if(fdist >= dist && fdist >= 0.001f && cdata[i] > 1)
|
||||
{
|
||||
float boxsize = tracemul/fdist;
|
||||
float px1 = (cox+cmoffsx)*boxsize+traceadd;
|
||||
float py1 = (coy+cmoffsy)*boxsize+traceadd;
|
||||
// draw
|
||||
float boxsize = tracemul/fabsf(sz);
|
||||
float px1 = sx*boxsize+traceadd;
|
||||
float py1 = sy*boxsize+traceadd;
|
||||
float px2 = px1+boxsize;
|
||||
float py2 = py1+boxsize;
|
||||
|
||||
if(1 || i == 0 || cdata[i-1] == 0)
|
||||
{
|
||||
render_vxl_cube(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
cdata[i], fdist);
|
||||
} else {
|
||||
render_vxl_cube_sides(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
cdata[i], fdist);
|
||||
}
|
||||
}
|
||||
|
||||
fdist += 1.0f;
|
||||
|
||||
if(fdist >= FOG_DISTANCE)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// top cubemap
|
||||
float fdist = 0.0f-blky-suby;
|
||||
fdist = -ylen-fdist;
|
||||
|
||||
// TODO: work out min required distance by frustum
|
||||
|
||||
i = ylenm1;
|
||||
for(; i >= 0; i--)
|
||||
{
|
||||
if(fdist >= dist && fdist >= 0.001f && cdata[i] > 1)
|
||||
{
|
||||
float boxsize = tracemul/fdist;
|
||||
float px1 = (-cox+cmoffsx)*boxsize+traceadd;
|
||||
float py1 = (-coy+cmoffsy)*boxsize+traceadd;
|
||||
float px2 = px1+boxsize;
|
||||
float py2 = py1+boxsize;
|
||||
|
||||
if(1 || i == ylenm1 || cdata[i+1] == 0)
|
||||
{
|
||||
render_vxl_cube(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
cdata[i], fdist);
|
||||
} else {
|
||||
render_vxl_cube_sides(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
cdata[i], fdist);
|
||||
}
|
||||
}
|
||||
|
||||
fdist += 1.0f;
|
||||
|
||||
if(fdist >= FOG_DISTANCE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(cox == bx2 && coy == by1)
|
||||
pdx = 0, pdy = 1;
|
||||
if(cox == bx2 && coy == by2)
|
||||
pdx = -1, pdy = 0;
|
||||
if(cox == bx1 && coy == by2)
|
||||
pdx = 0, pdy = -1;
|
||||
if(cox == bx1 && coy == by1 && pdy == -1)
|
||||
break;
|
||||
|
||||
cox += pdx;
|
||||
coy += pdy;
|
||||
}
|
||||
|
||||
// store "last" bounding box
|
||||
lbx1 = bx1;
|
||||
lby1 = by1;
|
||||
lbx2 = bx2;
|
||||
lby2 = by2;
|
||||
|
||||
// expand box
|
||||
bx1--;by1--;
|
||||
bx2++;by2++;
|
||||
// advance
|
||||
dist += 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void render_vxl_face_horiz(int blkx, int blky, int blkz,
|
||||
float subx, float suby, float subz,
|
||||
int face,
|
||||
int gx, int gy, int gz)
|
||||
{
|
||||
int sx,sy;
|
||||
int i;
|
||||
|
||||
float tracemul = cubemap_size/2;
|
||||
float traceadd = tracemul;
|
||||
|
||||
// get cubemaps
|
||||
uint32_t *ccolor = cubemap_color[face];
|
||||
float *cdepth = cubemap_depth[face];
|
||||
|
||||
// clear cubemap
|
||||
for(i = 0; i < cubemap_size*cubemap_size; i++)
|
||||
{
|
||||
ccolor[i] = 0x00000000;
|
||||
cdepth[i] = FOG_DISTANCE;
|
||||
}
|
||||
|
||||
// clear FTB buffers
|
||||
for(i = 0; i < cubemap_size; i++)
|
||||
{
|
||||
ftb_first[i] = 0;
|
||||
//ccolor[i<<cubemap_shift] = cubemap_size|(cubemap_size<<16);
|
||||
}
|
||||
|
||||
// get X cube direction
|
||||
int xgx = gz+gy;
|
||||
int xgy = 0;
|
||||
int xgz = -gx;
|
||||
|
||||
// get Y cube direction
|
||||
int ygx = 0;
|
||||
int ygy = gx+gz;
|
||||
int ygz = gy;
|
||||
|
||||
// get cubemap offset
|
||||
float cmoffsx = -(xgx*subx+xgy*suby+xgz*subz);
|
||||
float cmoffsy = -(ygx*subx+ygy*suby+ygz*subz);
|
||||
if(cmoffsy >= 0.0f)
|
||||
cmoffsy = -cmoffsy;
|
||||
if(cmoffsx >= 0.0f)
|
||||
cmoffsx -= 1.0f;
|
||||
//else
|
||||
// blky--;
|
||||
|
||||
|
||||
// get distance to wall
|
||||
float dist = -(subx*gx+suby*gy+subz*gz);
|
||||
if(dist < 0.0f)
|
||||
dist = 1.0f+dist;
|
||||
dist -= 1.0f;
|
||||
|
||||
int coz = blky;
|
||||
|
||||
// now loop and follow through
|
||||
while(dist < FOG_DISTANCE)
|
||||
{
|
||||
// calculate frustum
|
||||
int frustum = (int)(dist*cubemap_size);
|
||||
|
||||
// prep boundaries
|
||||
int bx1 = 0;
|
||||
int by1 = 0;
|
||||
int bx2 = frustum*2;
|
||||
int by2 = frustum*2;
|
||||
|
||||
// clamp wrt pixel counts
|
||||
// TODO!
|
||||
|
||||
// relocate
|
||||
bx1 -= frustum;
|
||||
by1 -= frustum;
|
||||
bx2 -= frustum;
|
||||
by2 -= frustum;
|
||||
|
||||
// need to go towards 0, not -inf!
|
||||
// (can be done as shifts, just looks nicer this way)
|
||||
bx1 /= cubemap_size;
|
||||
by1 /= cubemap_size;
|
||||
bx2 /= cubemap_size;
|
||||
by2 /= cubemap_size;
|
||||
|
||||
bx1-=2;by1--;
|
||||
bx2+=2;by2++;
|
||||
|
||||
// go through loop
|
||||
int cox,coy;
|
||||
cox = 0;
|
||||
coy = 0;
|
||||
|
||||
if(dist >= 0.001f)
|
||||
{
|
||||
float boxsize = tracemul/dist;
|
||||
float nboxsize = tracemul/(dist+0.5f);
|
||||
for(cox = bx1; cox <= bx2; cox++)
|
||||
{
|
||||
coz = 0;
|
||||
|
||||
uint8_t *pillar = rtmp_map->pillars[
|
||||
((cox*gz+blkx)&(rtmp_map->xlen-1))
|
||||
+(((-cox*gx+blkz)&(rtmp_map->zlen-1))*rtmp_map->xlen)]+4;
|
||||
|
||||
//printf("%4i %4i %4i - %i %i %i %i\n",cox,coy,coz,
|
||||
// pillar[0],pillar[1],pillar[2],pillar[3]);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
uint8_t *pcol = pillar+4;
|
||||
|
||||
// render top
|
||||
if(pillar[2]-blky >= by1 && pillar[1]-blky <= by2)
|
||||
for(coz = pillar[1]; coz <= pillar[2]; coz++)
|
||||
{
|
||||
if(coz-blky >= by1 && coz-blky <= by2)
|
||||
{
|
||||
float px1 = (cox+cmoffsx)*boxsize+traceadd;
|
||||
float py1 = (coz+cmoffsy-blky)*boxsize+traceadd;
|
||||
float px2 = px1+boxsize;
|
||||
float py2 = py1+boxsize;
|
||||
uint32_t xcolor = render_fog_apply_new(b->color, sx*sx+sy*sy+sz*sz);
|
||||
|
||||
render_vxl_cube(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
*((uint32_t *)pcol), dist);
|
||||
}
|
||||
pcol+=4;
|
||||
}
|
||||
|
||||
// advance where sensible
|
||||
if(pillar[2]-blky > by2)
|
||||
break;
|
||||
|
||||
if(pillar[0] == 0)
|
||||
break;
|
||||
|
||||
pillar += pillar[0]*4;
|
||||
|
||||
// render bottom
|
||||
int diff = (pillar-pcol)>>2;
|
||||
|
||||
for(coz = pillar[3]-diff; coz < pillar[3]; coz++)
|
||||
{
|
||||
if(coz-blky >= by1 && coz-blky <= by2)
|
||||
{
|
||||
float px1 = (cox+cmoffsx)*boxsize+traceadd;
|
||||
float py1 = (coz+cmoffsy-blky)*boxsize+traceadd;
|
||||
float px2 = px1+boxsize;
|
||||
float py2 = py1+boxsize;
|
||||
|
||||
render_vxl_cube(ccolor, cdepth,
|
||||
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||
*((uint32_t *)pcol), dist);
|
||||
}
|
||||
pcol+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dist += 1.0f;
|
||||
blkx += gx;
|
||||
blkz += gz;
|
||||
xcolor, sz);
|
||||
}
|
||||
}
|
||||
|
||||
void render_vxl_redraw(camera_t *camera, map_t *map)
|
||||
{
|
||||
int x,y,z;
|
||||
int i,x,y,z;
|
||||
|
||||
// stash stuff in globals to prevent spamming the stack too much
|
||||
// (and in turn thrashing the cache)
|
||||
rtmp_camera = camera;
|
||||
rtmp_map = map;
|
||||
|
||||
// stash x/y/zlen
|
||||
int xlen = map->xlen;
|
||||
int ylen = map->ylen;
|
||||
int zlen = map->zlen;
|
||||
|
||||
// get block pos
|
||||
int blkx = ((int)floor(camera->mpx)) & (map->xlen-1);
|
||||
int blky = ((int)floor(camera->mpy));// & (map->ylen-1);
|
||||
int blkz = ((int)floor(camera->mpz)) & (map->zlen-1);
|
||||
int blkx = ((int)floor(camera->mpx)) & (xlen-1);
|
||||
int blky = ((int)floor(camera->mpy));// & (ylen-1);
|
||||
int blkz = ((int)floor(camera->mpz)) & (zlen-1);
|
||||
|
||||
// get block subpos
|
||||
float subx = (camera->mpx - floor(camera->mpx));
|
||||
float suby = (camera->mpy - floor(camera->mpy));
|
||||
float subz = (camera->mpz - floor(camera->mpz));
|
||||
|
||||
// get centre (base) pos
|
||||
float bx = blkx + subx;
|
||||
float by = blky + suby;
|
||||
float bz = blkz + subz;
|
||||
|
||||
// check if we need to reallocate the mark table and block list
|
||||
{
|
||||
int markbase = xlen * zlen;
|
||||
int blockbase = markbase * ylen;
|
||||
|
||||
if(rayc_mark_size != markbase)
|
||||
{
|
||||
rayc_mark_size = markbase;
|
||||
rayc_mark = realloc(rayc_mark, rayc_mark_size*sizeof(int));
|
||||
}
|
||||
|
||||
if(rayc_block_size != blockbase)
|
||||
{
|
||||
rayc_block_size = markbase;
|
||||
rayc_block = realloc(rayc_block, rayc_block_size*sizeof(rayblock_t));
|
||||
}
|
||||
}
|
||||
|
||||
// clear the mark table
|
||||
memset(rayc_mark, 0, rayc_mark_size*sizeof(int));
|
||||
|
||||
// prep the starting block
|
||||
rayc_block_len = 0;
|
||||
rayc_block_head = 0;
|
||||
rayc_data_len = 1;
|
||||
rayc_data_head = 0;
|
||||
|
||||
rayc_data[0].x = blkx;
|
||||
rayc_data[0].y = blky;
|
||||
rayc_data[0].z = blkz;
|
||||
rayc_data[0].gx = 0;
|
||||
rayc_data[0].gz = 0;
|
||||
rayc_data[0].y1 = blky+suby;
|
||||
rayc_data[0].y2 = blky+suby;
|
||||
rayc_data[0].sx = subx;
|
||||
rayc_data[0].sy = suby;
|
||||
rayc_data[0].sz = subz;
|
||||
rayc_mark[blkx + blkz*xlen] = 1;
|
||||
|
||||
// build your way up
|
||||
while(rayc_data_head < rayc_data_len)
|
||||
{
|
||||
raydata_t *rd = &(rayc_data[rayc_data_head++]);
|
||||
|
||||
// get delta
|
||||
float dx = rd->x - bx;
|
||||
float dz = rd->z - bz;
|
||||
|
||||
// skip this if it's in the fog
|
||||
if(dx*dx+dz*dz >= FOG_DISTANCE*FOG_DISTANCE)
|
||||
continue;
|
||||
|
||||
// find where we are
|
||||
int idx = (((int)(rd->z)) & (zlen-1))*xlen + (((int)rd->x) & (xlen-1));
|
||||
uint8_t *p = map->pillars[idx]+4;
|
||||
rayc_mark[idx] = -1;
|
||||
int lastn = 0;
|
||||
int topcount = 0;
|
||||
int lasttop = 0;
|
||||
|
||||
while(p[0] != 0)
|
||||
{
|
||||
if(rd->y1 < p[1] && (lastn == 0 || rd->y1 >= lasttop))
|
||||
break;
|
||||
|
||||
lastn = p[0];
|
||||
lasttop = p[1];
|
||||
topcount = p[0] - (p[2]-p[1]+1);
|
||||
p += p[0]*4;
|
||||
}
|
||||
|
||||
int spreadflag = !(
|
||||
rd->y1 >= p[1] && (p[0] == 0 || rd->y1 <= p[p[0]*4+3])
|
||||
&& rd->y2 >= p[1] && (p[0] == 0 || rd->y2 <= p[p[0]*4+3]));
|
||||
|
||||
// advance y1/y2
|
||||
float y1 = rd->y1;
|
||||
float y2 = rd->y2;
|
||||
|
||||
if(rayc_data_head == 1)
|
||||
{
|
||||
y1 = (lastn == 0 ? 0.0f : p[3]);
|
||||
y2 = p[1];
|
||||
} else {
|
||||
float dist1 = sqrtf(dx*dx+dz*dz);
|
||||
float dist2 = dist1 + 1.42f; // max dist this can travel
|
||||
float travel = dist2/dist1;
|
||||
y1 = by + (y1-by)*travel;
|
||||
y2 = by + (y2-by)*travel;
|
||||
}
|
||||
|
||||
int iy1 = floor(y1);
|
||||
int iy2 = floor(y2);
|
||||
float by1 = y1;
|
||||
float by2 = y2;
|
||||
|
||||
// TODO: get the order right!
|
||||
|
||||
// add the top blocks (if they exist and we can see them)
|
||||
if(p[3] >= iy1 && lastn != 0)
|
||||
{
|
||||
y2 = y1 = p[3]-1;
|
||||
uint32_t *c = (uint32_t *)(&p[-4]);
|
||||
for(i = p[3]-1; i >= p[3]-topcount && i >= iy1; i--)
|
||||
{
|
||||
rayblock_t *b = &rayc_block[rayc_block_len++];
|
||||
b->x = rd->x;
|
||||
b->z = rd->z;
|
||||
b->y = i;
|
||||
b->color = *(c--);
|
||||
}
|
||||
}
|
||||
|
||||
// sneak your way down
|
||||
while(p[1] <= iy2)
|
||||
{
|
||||
y2 = p[1]+1;
|
||||
//printf("%i %i %i %i [%i, %i]\n", p[0],p[1],p[2],p[3],iy1,iy2);
|
||||
uint32_t *c = (uint32_t *)(&p[4]);
|
||||
for(i = p[1]; i <= p[2] && i <= iy2; i++)
|
||||
{
|
||||
rayblock_t *b = &rayc_block[rayc_block_len++];
|
||||
b->x = rd->x;
|
||||
b->z = rd->z;
|
||||
b->y = i;
|
||||
b->color = *(c++);
|
||||
}
|
||||
|
||||
if(p[0] == 0)
|
||||
break;
|
||||
|
||||
lastn = p[0];
|
||||
lasttop = p[1];
|
||||
topcount = p[0] - (p[2]-p[1]+1);
|
||||
p += 4*p[0];
|
||||
|
||||
c = (uint32_t *)(&p[-4]);
|
||||
for(i = p[3]-1; i >= p[3]-topcount; i--)
|
||||
{
|
||||
if(i > iy2)
|
||||
{
|
||||
c--;
|
||||
continue;
|
||||
}
|
||||
rayblock_t *b = &rayc_block[rayc_block_len++];
|
||||
b->x = rd->x;
|
||||
b->z = rd->z;
|
||||
b->y = i;
|
||||
b->color = *(c--);
|
||||
}
|
||||
}
|
||||
|
||||
// correct the y spread
|
||||
if(y1 < by1)
|
||||
y1 = by1;
|
||||
if(y2 > by2)
|
||||
y2 = by2;
|
||||
|
||||
// spread out
|
||||
int ofx = 1;
|
||||
int ofz = 0;
|
||||
if(spreadflag) do
|
||||
{
|
||||
int idx2 = ((ofx + (int)rd->x) & (xlen-1))
|
||||
+ xlen * ((ofz + (int)rd->z) & (zlen-1));
|
||||
|
||||
if((ofx != 0 && ofx == -rd->gx) || (ofz != 0 && ofz == -rd->gz))
|
||||
{
|
||||
// do nothing
|
||||
} else if(rayc_mark[idx2] == 0) {
|
||||
rayc_mark[idx2] = rayc_data_len+1;
|
||||
raydata_t *rd2 = &(rayc_data[rayc_data_len++]);
|
||||
|
||||
rd2->x = ofx + (int)rd->x;
|
||||
rd2->z = ofz + (int)rd->z;
|
||||
rd2->y1 = y1;
|
||||
rd2->y2 = y2;
|
||||
rd2->sx = subx;
|
||||
rd2->sy = suby;
|
||||
rd2->sz = subz;
|
||||
rd2->gx += ofx;
|
||||
rd2->gz += ofz;
|
||||
} else if(rayc_mark[idx2] != -1) {
|
||||
raydata_t *rd2 = &(rayc_data[rayc_mark[idx2]-1]);
|
||||
|
||||
if(y1 < rd2->y1)
|
||||
rd2->y1 = y1;
|
||||
if(y2 > rd2->y2)
|
||||
rd2->y2 = y2;
|
||||
}
|
||||
|
||||
{
|
||||
int t = ofx;
|
||||
ofx = -ofz;
|
||||
ofz = t;
|
||||
}
|
||||
} while(ofx != 1);
|
||||
|
||||
}
|
||||
|
||||
// render each face
|
||||
render_vxl_face_horiz(blkx, blky, blkz, subx, suby, subz, CM_NX, -1, 0, 0);
|
||||
render_vxl_face_vert(blkx, blky, blkz, subx, suby, subz, CM_NY, 0, -1, 0);
|
||||
render_vxl_face_horiz(blkx, blky, blkz, subx, suby, subz, CM_NZ, 0, 0, -1);
|
||||
render_vxl_face_horiz(blkx, blky, blkz, subx, suby, subz, CM_PX, 1, 0, 0);
|
||||
render_vxl_face_vert(blkx, blky, blkz, subx, suby, subz, CM_PY, 0, 1, 0);
|
||||
render_vxl_face_horiz(blkx, blky, blkz, subx, suby, subz, CM_PZ, 0, 0, 1);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_NX, -1, 0, 0);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_NY, 0, -1, 0);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_NZ, 0, 0, -1);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_PX, 1, 0, 0);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_PY, 0, 1, 0);
|
||||
render_vxl_face_raycast(blkx, blky, blkz, subx, suby, subz, CM_PZ, 0, 0, 1);
|
||||
}
|
||||
|
||||
void render_cubemap(uint32_t *pixels, int width, int height, int pitch, camera_t *camera, map_t *map)
|
||||
@ -1062,10 +997,6 @@ int render_init(int width, int height)
|
||||
size >>= 1;
|
||||
}
|
||||
|
||||
// allocate space for FTB buffers
|
||||
ftb_first = malloc(cubemap_size*sizeof(int));
|
||||
// TODO: check if NULL
|
||||
|
||||
// allocate space for depth buffer
|
||||
dbuf = malloc(width*height*sizeof(float));
|
||||
// TODO: check if NULL
|
||||
@ -1092,13 +1023,6 @@ void render_deinit(void)
|
||||
}
|
||||
}
|
||||
|
||||
// deallocate FTB buffers
|
||||
if(ftb_first != NULL)
|
||||
{
|
||||
free(ftb_first);
|
||||
ftb_first = NULL;
|
||||
}
|
||||
|
||||
// deallocate depth buffer
|
||||
if(dbuf != NULL)
|
||||
{
|
||||
|
1452
render.old1
Normal file
1452
render.old1
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user