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()
|
function this.spawn()
|
||||||
local xlen,ylen,zlen
|
local xlen,ylen,zlen
|
||||||
xlen,ylen,zlen = common.map_get_dims()
|
xlen,ylen,zlen = common.map_get_dims()
|
||||||
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
|
while true do
|
||||||
|
this.x = math.floor(math.random()*xlen/4.0)+0.5
|
||||||
|
this.z = math.floor(math.random()*zlen)+0.5
|
||||||
|
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.alive = true
|
||||||
this.spawned = true
|
this.spawned = true
|
||||||
|
704
render.c
704
render.c
@ -17,10 +17,12 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
// TODO: bump up to 127.5f
|
//define DEBUG_INVERT_DRAW_DIR
|
||||||
#define FOG_DISTANCE 40.0f
|
|
||||||
|
|
||||||
#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_NX 0x01
|
||||||
#define DF_NY 0x02
|
#define DF_NY 0x02
|
||||||
@ -51,15 +53,57 @@ int rtmp_width, rtmp_height, rtmp_pitch;
|
|||||||
camera_t *rtmp_camera;
|
camera_t *rtmp_camera;
|
||||||
map_t *rtmp_map;
|
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;
|
float *dbuf;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REFERENCE IMPLEMENTATION
|
* 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)
|
uint32_t render_fog_apply(uint32_t color, float depth)
|
||||||
{
|
{
|
||||||
int b = color&255;
|
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.
|
// NOTE: this approach seems to be faster than render_vxl_rect_btf.
|
||||||
|
|
||||||
// clip
|
// 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)
|
if(x2 <= 0)
|
||||||
return;
|
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);
|
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,
|
float subx, float suby, float subz,
|
||||||
int face,
|
int face,
|
||||||
int gx, int gy, int gz)
|
int gx, int gy, int gz)
|
||||||
{
|
{
|
||||||
// TODO: this function sucks, speed it up a bit
|
|
||||||
int sx,sy;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
float tracemul = cubemap_size/2;
|
float tracemul = cubemap_size/2;
|
||||||
@ -294,13 +337,6 @@ void render_vxl_face_vert(int blkx, int blky, int blkz,
|
|||||||
cdepth[i] = FOG_DISTANCE;
|
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
|
// get X cube direction
|
||||||
int xgx = gz+gy;
|
int xgx = gz+gy;
|
||||||
int xgy = 0;
|
int xgy = 0;
|
||||||
@ -308,402 +344,301 @@ void render_vxl_face_vert(int blkx, int blky, int blkz,
|
|||||||
|
|
||||||
// get Y cube direction
|
// get Y cube direction
|
||||||
int ygx = 0;
|
int ygx = 0;
|
||||||
int ygy = gx+gz;
|
int ygy = fabsf(gx+gz);
|
||||||
int ygz = gy;
|
int ygz = gy;
|
||||||
|
|
||||||
// get cubemap offset
|
// get base pos
|
||||||
float cmoffsx = -(xgx*subx+xgy*suby+xgz*subz);
|
float bx = blkx+subx;
|
||||||
float cmoffsy = -(ygx*subx+ygy*suby+ygz*subz);
|
float by = blky+suby;
|
||||||
|
float bz = blkz+subz;
|
||||||
|
|
||||||
// get distance to wall
|
if(xgx+xgy+xgz < 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
bx1++;
|
bx += xgx;
|
||||||
by1++;
|
by += xgy;
|
||||||
bx2++;
|
bz += xgz;
|
||||||
by2++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int xlen = rtmp_map->xlen;
|
// now crawl through the block list
|
||||||
int ylen = rtmp_map->ylen;
|
#ifdef DEBUG_INVERT_DRAW_DIR
|
||||||
int zlen = rtmp_map->zlen;
|
rayblock_t *b = &rayc_block[rayc_block_len-1];
|
||||||
int xlenm1 = xlen-1;
|
rayblock_t *b_end = &rayc_block[0];
|
||||||
int ylenm1 = ylen-1;
|
for(; b >= b_end; b--)
|
||||||
int zlenm1 = zlen-1;
|
#else
|
||||||
|
rayblock_t *b = &rayc_block[0];
|
||||||
while(dist < FOG_DISTANCE)
|
rayblock_t *b_end = &rayc_block[rayc_block_len];
|
||||||
|
for(; b < b_end; b++)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// go through each
|
// get block delta
|
||||||
int cox,coy;
|
float dx = b->x - bx;
|
||||||
cox = bx1; coy = by1;
|
float dy = b->y - by;
|
||||||
int pdx = 1, pdy = 0;
|
float dz = b->z - bz;
|
||||||
|
|
||||||
for(;;)
|
// get correct screen positions
|
||||||
{
|
float sx = dx*xgx+dy*xgy+dz*xgz;
|
||||||
// skip already-rendered stuff
|
float sy = dx*ygx+dy*ygy+dz*ygz;
|
||||||
//if(cox >= lbx1 && coy >= lby1 && cox <= lbx2 && coy <= lby2)
|
float sz = dx* gx+dy* gy+dz* gz;
|
||||||
// continue;
|
|
||||||
|
|
||||||
// get pillar
|
|
||||||
uint8_t *pillar = rtmp_map->pillars[
|
|
||||||
((cox+blkx)&(xlenm1))
|
|
||||||
+(((coy+blkz)&(zlenm1))*xlen)]+4;
|
|
||||||
|
|
||||||
// load data
|
|
||||||
|
|
||||||
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;
|
|
||||||
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
|
// check distance
|
||||||
lbx1 = bx1;
|
if(sz < 0.001f || sz >= FOG_DISTANCE)
|
||||||
lby1 = by1;
|
continue;
|
||||||
lbx2 = bx2;
|
|
||||||
lby2 = by2;
|
|
||||||
|
|
||||||
// expand box
|
// frustum cull
|
||||||
bx1--;by1--;
|
if(fabsf(sx) > fabsf(sz+2.0f) || fabsf(sy) > fabsf(sz+2.0f))
|
||||||
bx2++;by2++;
|
continue;
|
||||||
// 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
|
// draw
|
||||||
int bx1 = 0;
|
float boxsize = tracemul/fabsf(sz);
|
||||||
int by1 = 0;
|
float px1 = sx*boxsize+traceadd;
|
||||||
int bx2 = frustum*2;
|
float py1 = sy*boxsize+traceadd;
|
||||||
int by2 = frustum*2;
|
float px2 = px1+boxsize;
|
||||||
|
float py2 = py1+boxsize;
|
||||||
|
|
||||||
// clamp wrt pixel counts
|
uint32_t xcolor = render_fog_apply_new(b->color, sx*sx+sy*sy+sz*sz);
|
||||||
// TODO!
|
|
||||||
|
|
||||||
// relocate
|
render_vxl_cube(ccolor, cdepth,
|
||||||
bx1 -= frustum;
|
(int)px1, (int)py1, (int)px2, (int)py2,
|
||||||
by1 -= frustum;
|
xcolor, sz);
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_vxl_redraw(camera_t *camera, map_t *map)
|
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
|
// stash stuff in globals to prevent spamming the stack too much
|
||||||
// (and in turn thrashing the cache)
|
// (and in turn thrashing the cache)
|
||||||
rtmp_camera = camera;
|
rtmp_camera = camera;
|
||||||
rtmp_map = map;
|
rtmp_map = map;
|
||||||
|
|
||||||
|
// stash x/y/zlen
|
||||||
|
int xlen = map->xlen;
|
||||||
|
int ylen = map->ylen;
|
||||||
|
int zlen = map->zlen;
|
||||||
|
|
||||||
// get block pos
|
// get block pos
|
||||||
int blkx = ((int)floor(camera->mpx)) & (map->xlen-1);
|
int blkx = ((int)floor(camera->mpx)) & (xlen-1);
|
||||||
int blky = ((int)floor(camera->mpy));// & (map->ylen-1);
|
int blky = ((int)floor(camera->mpy));// & (ylen-1);
|
||||||
int blkz = ((int)floor(camera->mpz)) & (map->zlen-1);
|
int blkz = ((int)floor(camera->mpz)) & (zlen-1);
|
||||||
|
|
||||||
// get block subpos
|
// get block subpos
|
||||||
float subx = (camera->mpx - floor(camera->mpx));
|
float subx = (camera->mpx - floor(camera->mpx));
|
||||||
float suby = (camera->mpy - floor(camera->mpy));
|
float suby = (camera->mpy - floor(camera->mpy));
|
||||||
float subz = (camera->mpz - floor(camera->mpz));
|
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 each face
|
||||||
render_vxl_face_horiz(blkx, blky, blkz, subx, suby, subz, CM_NX, -1, 0, 0);
|
render_vxl_face_raycast(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_raycast(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_raycast(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_raycast(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_raycast(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_PZ, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_cubemap(uint32_t *pixels, int width, int height, int pitch, camera_t *camera, map_t *map)
|
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;
|
size >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate space for FTB buffers
|
|
||||||
ftb_first = malloc(cubemap_size*sizeof(int));
|
|
||||||
// TODO: check if NULL
|
|
||||||
|
|
||||||
// allocate space for depth buffer
|
// allocate space for depth buffer
|
||||||
dbuf = malloc(width*height*sizeof(float));
|
dbuf = malloc(width*height*sizeof(float));
|
||||||
// TODO: check if NULL
|
// 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
|
// deallocate depth buffer
|
||||||
if(dbuf != NULL)
|
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