From f18556d9f7174dfb6822a7a543732389e8d48bcd Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 17 Oct 2022 00:40:08 +0300 Subject: [PATCH] fog --- src/main.c | 8 +++++-- src/voxscape.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------- src/voxscape.h | 7 ++++++- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/main.c b/src/main.c index 2a5459a..f0c89eb 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,9 @@ int32_t pos[2], angle; struct voxscape *vox; +#define COLOR_HORIZON 0xcc77ff +#define COLOR_ZENITH 0x5588cc + int main(int argc, char **argv) { @@ -76,8 +79,9 @@ int init(void) if(!(vox = vox_open("data/height.png", "data/color.png"))) { return -1; } - vox_framebuf(vox, FB_W, FB_H, fb); + vox_framebuf(vox, FB_W, FB_H, fb, -1); vox_proj(vox, 45, 1, 300); + vox_fog(vox, 260, COLOR_HORIZON); glfb_setup(FB_W, FB_H, GLFB_RGBA32, FB_W * 4); return 0; @@ -130,7 +134,7 @@ void display(void) memset(fb, 0, sizeof fb); vox_render(vox); - vox_sky_grad(vox, 0xcc77ff, 0x5588cc); + vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH); glfb_update(fb); glfb_display(); 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); diff --git a/src/voxscape.h b/src/voxscape.h index 1bbb03a..9bd5164 100644 --- a/src/voxscape.h +++ b/src/voxscape.h @@ -5,13 +5,17 @@ struct voxscape; +#define VOX_RGB(r, g, b) \ + ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16)) + struct voxscape *vox_create(int xsz, int ysz); struct voxscape *vox_open(const char *hfile, const char *cfile); void vox_free(struct voxscape *vox); +void vox_fog(struct voxscape *vox, int zstart, uint32_t color); int vox_height(struct voxscape *vox, int32_t x, int32_t y); -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); /* negative height for auto at -h above terrain */ void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle); void vox_proj(struct voxscape *vox, int fov, int znear, int zfar); @@ -21,6 +25,7 @@ void vox_render(struct voxscape *vox); void vox_begin(struct voxscape *vox); void vox_render_slice(struct voxscape *vox, int n); +void vox_sky_solid(struct voxscape *vox, uint32_t color); void vox_sky_grad(struct voxscape *vox, uint32_t chor, uint32_t ctop); #endif /* VOXSCAPE_H_ */ -- 1.7.10.4