X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fvoxscape.c;h=60d80a041b05622035442e6271a5290a3f7ed138;hb=f18556d9f7174dfb6822a7a543732389e8d48bcd;hp=a23a851eaa1fa734fd6a878c06b099b19bafb551;hpb=34a5a35c6ba9aff4ae92475bfa8d3b398633d835;p=voxscape diff --git a/src/voxscape.c b/src/voxscape.c index a23a851..60d80a0 100644 --- a/src/voxscape.c +++ b/src/voxscape.c @@ -22,6 +22,7 @@ struct voxscape { uint32_t *fb; int fbwidth, fbheight; int *coltop; + int horizon; /* view */ int32_t x, y, angle; @@ -33,6 +34,9 @@ struct voxscape { int32_t *slicelen; int proj_dist; + int zfog; /* fog start Z (0: no fog) */ + int fogcolor[3]; + unsigned int valid; }; @@ -76,7 +80,7 @@ struct voxscape *vox_open(const char *hfile, const char *cfile) { unsigned char *hpix; uint32_t *cpix; - int width, height, cwidth, cheight; + int i, width, height, cwidth, cheight; struct voxscape *vox; if(!(hpix = img_load_pixels(hfile, &width, &height, IMG_FMT_GREY8))) { @@ -100,8 +104,12 @@ struct voxscape *vox_open(const char *hfile, const char *cfile) img_free_pixels(cpix); return 0; } + memcpy(vox->height, hpix, width * height); - memcpy(vox->color, cpix, width * height * sizeof *vox->color); + + for(i=0; icolor[i] = cpix[i] & 0xffffff; /* discard alpha */ + } img_free_pixels(hpix); img_free_pixels(cpix); @@ -120,6 +128,15 @@ void vox_free(struct voxscape *vox) free(vox); } +void vox_fog(struct voxscape *vox, int zstart, uint32_t color) +{ + vox->zfog = zstart; + + vox->fogcolor[0] = color >> 16; + vox->fogcolor[1] = (color >> 8) & 0xff; + vox->fogcolor[2] = color & 0xff; +} + int vox_height(struct voxscape *vox, int32_t x, int32_t y) { int tx = (x >> 16) & vox->xmask; @@ -128,7 +145,7 @@ int vox_height(struct voxscape *vox, int32_t x, int32_t y) return vox->height[(ty << vox->xshift) + tx]; } -void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb) +void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb, int horizon) { if(xres != vox->fbwidth) { free(vox->coltop); @@ -140,6 +157,7 @@ void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb) vox->fb = fb; vox->fbwidth = xres; vox->fbheight = yres; + vox->horizon = horizon >= 0 ? horizon : vox->fbheight / 2; } void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle) @@ -205,11 +223,17 @@ void vox_begin(struct voxscape *vox) void vox_render_slice(struct voxscape *vox, int n) { - int i, j, tx, ty, hval, colstart, colheight, z; - int32_t x, y, len, xstep, ystep; + int i, j, tx, ty, hval, colstart, colheight, z, r, g, b; + int32_t x, y, len, xstep, ystep, fog; uint32_t color; uint32_t *fbptr; + if(vox->zfog > 0 && n > vox->zfog) { + fog = ((n - vox->zfog) << 8) / (vox->zfar - vox->zfog); + } else { + fog = 0; + } + z = vox->znear + n; len = vox->slicelen[n] >> 8; @@ -223,7 +247,7 @@ void vox_render_slice(struct voxscape *vox, int n) ty = (y >> 16) & vox->ymask; hval = vox->height[(ty << vox->xshift) + tx] - vox->vheight; - hval = hval * 160 / (vox->znear + n) + 250; + hval = hval * 160 / (vox->znear + n) + vox->horizon; if(hval > vox->fbheight) hval = vox->fbheight; if(hval > vox->coltop[i]) { color = vox->color[(ty << vox->xshift) + tx]; @@ -231,6 +255,16 @@ void vox_render_slice(struct voxscape *vox, int n) colheight = hval - vox->coltop[i]; fbptr = vox->fb + colstart * vox->fbwidth + i; + if(fog > 0) { + r = color >> 16; + g = (color >> 8) & 0xff; + b = color & 0xff; + r = ((r << 8) + (vox->fogcolor[0] - r) * fog) >> 8; + g = ((g << 8) + (vox->fogcolor[1] - g) * fog) >> 8; + b = ((b << 8) + (vox->fogcolor[2] - b) * fog) >> 8; + color = (r << 16) | (g << 8) | b; + } + for(j=0; jfbwidth; @@ -243,11 +277,26 @@ void vox_render_slice(struct voxscape *vox, int n) } } +void vox_sky_solid(struct voxscape *vox, uint32_t color) +{ + int i, j, colheight; + uint32_t *fbptr; + + for(i=0; ifbwidth; i++) { + fbptr = vox->fb + i; + colheight = vox->fbheight - vox->coltop[i]; + for(j=0; jfbwidth; + } + } +} + void vox_sky_grad(struct voxscape *vox, uint32_t chor, uint32_t ctop) { int i, j, colheight, t; int r0, g0, b0, r1, g1, b1, r, g, b; - int d = vox->fbheight - 250; + int d = vox->fbheight - vox->horizon; uint32_t *grad, *fbptr; grad = alloca(vox->fbheight * sizeof *grad);